diff options
Diffstat (limited to 'kopete/protocols/oscar/icq')
32 files changed, 6984 insertions, 0 deletions
diff --git a/kopete/protocols/oscar/icq/Makefile.am b/kopete/protocols/oscar/icq/Makefile.am new file mode 100644 index 00000000..defadf37 --- /dev/null +++ b/kopete/protocols/oscar/icq/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = ui . +METASOURCES = AUTO +AM_CPPFLAGS = -I$(srcdir)/../ \ + -I$(srcdir)/ui/ \ + -I$(top_builddir)/kopete/protocols/oscar/icq/ui \ + -I$(srcdir)/../liboscar \ + $(KOPETE_INCLUDES) $(all_includes) + +kde_module_LTLIBRARIES = kopete_icq.la + +kopete_icq_la_SOURCES = icqpresence.cpp icqaccount.cpp icqcontact.cpp icqprotocol.cpp +# icquserinfo.cpp icqreadaway.cpp icqsendsmsdialog.cpp + +kopete_icq_la_LDFLAGS = -no-undefined -module $(KDE_PLUGIN) $(all_libraries) +kopete_icq_la_LIBADD = ../libkopete_oscar.la \ + $(top_builddir)/kopete/libkopete/libkopete.la ui/libkopeteicqui.la + +service_DATA = kopete_icq.desktop +servicedir = $(kde_servicesdir) + +mime_DATA = x-icq.desktop +mimedir = $(kde_mimedir)/application diff --git a/kopete/protocols/oscar/icq/icqaccount.cpp b/kopete/protocols/oscar/icq/icqaccount.cpp new file mode 100644 index 00000000..9a071442 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqaccount.cpp @@ -0,0 +1,529 @@ +/* + icqaccount.cpp - ICQ Account Class + + Copyright (c) 2002 by Chris TenHarmsel <tenharmsel@staticmethod.net> + Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk> + 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 <qfile.h> + +#include <kconfig.h> +#include <kdebug.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kmdcodec.h> +#include <kmessagebox.h> + +#include "kopeteawayaction.h" +#include "kopetemessage.h" +#include "kopetecontactlist.h" +#include "kopeteuiglobal.h" + +#include "client.h" +#include "icquserinfo.h" +#include "oscarsettings.h" +#include "oscarutils.h" +#include "ssimanager.h" + +#include "icqcontact.h" +#include "icqprotocol.h" +#include "icqaccount.h" + +#include "oscarvisibilitydialog.h" + +ICQMyselfContact::ICQMyselfContact( ICQAccount *acct ) : OscarMyselfContact( acct ) +{ + QObject::connect( acct->engine(), SIGNAL( loggedIn() ), this, SLOT( fetchShortInfo() ) ); + QObject::connect( acct->engine(), SIGNAL( receivedIcqShortInfo( const QString& ) ), + this, SLOT( receivedShortInfo( const QString& ) ) ); +} + +void ICQMyselfContact::userInfoUpdated() +{ + DWORD extendedStatus = details().extendedStatus(); + kdDebug( OSCAR_ICQ_DEBUG ) << k_funcinfo << "extendedStatus is " << QString::number( extendedStatus, 16 ) << endl; + ICQ::Presence presence = ICQ::Presence::fromOscarStatus( extendedStatus & 0xffff ); + setOnlineStatus( presence.toOnlineStatus() ); + setProperty( Kopete::Global::Properties::self()->awayMessage(), static_cast<ICQAccount*>( account() )->engine()->statusMessage() ); +} + +void ICQMyselfContact::receivedShortInfo( const QString& contact ) +{ + if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) ) + return; + + ICQShortInfo shortInfo = static_cast<ICQAccount*>( account() )->engine()->getShortInfo( contact ); + if ( !shortInfo.nickname.isEmpty() ) + { + setProperty( Kopete::Global::Properties::self()->nickName(), static_cast<ICQAccount*>( account() )->defaultCodec()->toUnicode( shortInfo.nickname ) ); + } +} + +void ICQMyselfContact::fetchShortInfo() +{ + static_cast<ICQAccount*>( account() )->engine()->requestShortInfo( contactId() ); +} + +ICQAccount::ICQAccount(Kopete::Protocol *parent, QString accountID, const char *name) + : OscarAccount(parent, accountID, name, true) +{ + kdDebug(14152) << k_funcinfo << accountID << ": Called."<< endl; + setMyself( new ICQMyselfContact( this ) ); + myself()->setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() ); + + m_visibilityDialog = 0; + + QString nickName = configGroup()->readEntry("NickName", QString::null); + mWebAware = configGroup()->readBoolEntry( "WebAware", false ); + mHideIP = configGroup()->readBoolEntry( "HideIP", true ); + mInitialStatusMessage = QString::null; + + QObject::connect( Kopete::ContactList::self(), SIGNAL( globalIdentityChanged( const QString&, const QVariant& ) ), + this, SLOT( slotGlobalIdentityChanged( const QString&, const QVariant& ) ) ); + + QObject::connect( this, SIGNAL( buddyIconChanged() ), this, SLOT( slotBuddyIconChanged() ) ); + + //setIgnoreUnknownContacts(pluginData(protocol(), "IgnoreUnknownContacts").toUInt() == 1); + + /* FIXME: need to do this when web aware or hide ip change + if(isConnected() && (oldhideip != mHideIP || oldwebaware != mWebAware)) + { + kdDebug(14153) << k_funcinfo << + "sending status to reflect HideIP and WebAware settings" << endl; + //setStatus(mStatus, QString::null); + }*/ +} + +ICQAccount::~ICQAccount() +{ +} + +ICQProtocol* ICQAccount::protocol() +{ + return static_cast<ICQProtocol*>(OscarAccount::protocol()); +} + + +ICQ::Presence ICQAccount::presence() +{ + return ICQ::Presence::fromOnlineStatus( myself()->onlineStatus() ); +} + + +KActionMenu* ICQAccount::actionMenu() +{ + KActionMenu* actionMenu = Kopete::Account::actionMenu(); + + actionMenu->popupMenu()->insertSeparator(); + + KToggleAction* actionInvisible = + new KToggleAction( i18n( "In&visible" ), + ICQ::Presence( presence().type(), ICQ::Presence::Invisible ).toOnlineStatus().iconFor( this ), + 0, this, SLOT( slotToggleInvisible() ), this ); + actionInvisible->setChecked( presence().visibility() == ICQ::Presence::Invisible ); + actionMenu->insert( actionInvisible ); + + actionMenu->popupMenu()->insertSeparator(); + actionMenu->insert( new KToggleAction( i18n( "Set Visibility..." ), 0, 0, + this, SLOT( slotSetVisiblility() ), this, + "ICQAccount::mActionSetVisibility") ); + //actionMenu->insert( new KToggleAction( i18n( "Send &SMS..." ), 0, 0, this, SLOT( slotSendSMS() ), this, "ICQAccount::mActionSendSMS") ); + + return actionMenu; +} + + +void ICQAccount::connectWithPassword( const QString &password ) +{ + if ( password.isNull() ) + return; + + kdDebug(14153) << k_funcinfo << "accountId='" << accountId() << "'" << endl; + + Kopete::OnlineStatus status = initialStatus(); + if ( status == Kopete::OnlineStatus() && + status.status() == Kopete::OnlineStatus::Unknown ) + //use default online in case of invalid online status for connecting + status = Kopete::OnlineStatus( Kopete::OnlineStatus::Online ); + ICQ::Presence pres = ICQ::Presence::fromOnlineStatus( status ); + bool accountIsOffline = ( presence().type() == ICQ::Presence::Offline || + myself()->onlineStatus() == protocol()->statusManager()->connectingStatus() ); + + if ( accountIsOffline ) + { + myself()->setOnlineStatus( protocol()->statusManager()->connectingStatus() ); + QString icqNumber = accountId(); + kdDebug(14153) << k_funcinfo << "Logging in as " << icqNumber << endl ; + QString server = configGroup()->readEntry( "Server", QString::fromLatin1( "login.oscar.aol.com" ) ); + uint port = configGroup()->readNumEntry( "Port", 5190 ); + Connection* c = setupConnection( server, port ); + + //set up the settings for the account + Oscar::Settings* oscarSettings = engine()->clientSettings(); + oscarSettings->setWebAware( configGroup()->readBoolEntry( "WebAware", false ) ); + oscarSettings->setHideIP( configGroup()->readBoolEntry( "HideIP", true ) ); + //FIXME: also needed for the other call to setStatus (in setPresenceTarget) + DWORD status = pres.toOscarStatus(); + + if ( !mHideIP ) + status |= ICQ::StatusCode::SHOWIP; + if ( mWebAware ) + status |= ICQ::StatusCode::WEBAWARE; + + engine()->setStatus( status, mInitialStatusMessage ); + updateVersionUpdaterStamp(); + engine()->start( server, port, accountId(), password ); + engine()->connectToServer( c, server, true /* doAuth */ ); + + mInitialStatusMessage = QString::null; + } +} + +void ICQAccount::disconnected( DisconnectReason reason ) +{ + kdDebug(14153) << k_funcinfo << "Attempting to set status offline" << endl; + ICQ::Presence presOffline = ICQ::Presence( ICQ::Presence::Offline, presence().visibility() ); + myself()->setOnlineStatus( presOffline.toOnlineStatus() ); + + QDictIterator<Kopete::Contact> it( contacts() ); + for( ; it.current(); ++it ) + { + OscarContact* oc = dynamic_cast<OscarContact*>( it.current() ); + if ( oc ) + { + if ( oc->ssiItem().waitingAuth() ) + oc->setOnlineStatus( protocol()->statusManager()->waitingForAuth() ); + else + oc->setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() ); + } + } + + OscarAccount::disconnected( reason ); +} + + +void ICQAccount::slotToggleInvisible() +{ + using namespace ICQ; + setInvisible( (presence().visibility() == Presence::Visible) ? Presence::Invisible : Presence::Visible ); +} + +void ICQAccount::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; + //temporary map for faster lookup of contactId + 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 ) + { //for better orientation in lists use nickName and icq number + QString screenName( "%1 (%2)" ); + screenName = screenName.arg( oc->nickName(), contactId); + contactMap.insert( screenName, contactId ); + revContactMap.insert( contactId, screenName ); + } + 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 ICQAccount::slotVisibilityDialogClosed() +{ + m_visibilityDialog->delayedDestruct(); + m_visibilityDialog = 0L; +} + +void ICQAccount::setAway( bool away, const QString &awayReason ) +{ + kdDebug(14153) << k_funcinfo << "account='" << accountId() << "'" << endl; + if ( away ) + setPresenceType( ICQ::Presence::Away, awayReason ); + else + setPresenceType( ICQ::Presence::Online ); +} + + +void ICQAccount::setInvisible( ICQ::Presence::Visibility vis ) +{ + ICQ::Presence pres = presence(); + if ( vis == pres.visibility() ) + return; + + kdDebug(14153) << k_funcinfo << "changing invisible setting to " << (int)vis << endl; + setPresenceTarget( ICQ::Presence( pres.type(), vis ) ); +} + +void ICQAccount::setPresenceType( ICQ::Presence::Type type, const QString &message ) +{ + ICQ::Presence pres = presence(); + kdDebug(14153) << k_funcinfo << "new type=" << (int)type << ", old type=" << (int)pres.type() << ", new message=" << message << endl; + //setAwayMessage(awayMessage); + setPresenceTarget( ICQ::Presence( type, pres.visibility() ), message ); +} + +void ICQAccount::setPresenceTarget( const ICQ::Presence &newPres, const QString &message ) +{ + bool targetIsOffline = (newPres.type() == ICQ::Presence::Offline); + bool accountIsOffline = ( presence().type() == ICQ::Presence::Offline || + myself()->onlineStatus() == protocol()->statusManager()->connectingStatus() ); + + if ( targetIsOffline ) + { + OscarAccount::disconnect(); + // allow toggling invisibility when offline + myself()->setOnlineStatus( newPres.toOnlineStatus() ); + } + else if ( accountIsOffline ) + { + mInitialStatusMessage = message; + OscarAccount::connect( newPres.toOnlineStatus() ); + } + else + { + engine()->setStatus( newPres.toOscarStatus(), message ); + } +} + + +void ICQAccount::setOnlineStatus( const Kopete::OnlineStatus& status, const QString& reason ) +{ + if ( status.status() == Kopete::OnlineStatus::Invisible ) + { + // called from outside, i.e. not by our custom action menu entry... + + if ( presence().type() == ICQ::Presence::Offline ) + { + // ...when we are offline go online invisible. + setPresenceTarget( ICQ::Presence( ICQ::Presence::Online, ICQ::Presence::Invisible ) ); + } + else + { + // ...when we are not offline set invisible. + setInvisible( ICQ::Presence::Invisible ); + } + } + else + { + setPresenceType( ICQ::Presence::fromOnlineStatus( status ).type(), reason ); + } +} + + +OscarContact *ICQAccount::createNewContact( const QString &contactId, Kopete::MetaContact *parentContact, const SSI& ssiItem ) +{ + ICQContact* contact = new ICQContact( this, contactId, parentContact, QString::null, ssiItem ); + if ( !ssiItem.alias().isEmpty() ) + contact->setProperty( Kopete::Global::Properties::self()->nickName(), ssiItem.alias() ); + + if ( isConnected() ) + contact->loggedIn(); + + return contact; +} + +QString ICQAccount::sanitizedMessage( const QString& message ) +{ + return Kopete::Message::escape( message ); +} + + +void ICQAccount::slotGlobalIdentityChanged( const QString& key, const QVariant& value ) +{ + //do something with the photo + kdDebug(14153) << k_funcinfo << "Global identity changed" << endl; + kdDebug(14153) << k_funcinfo << "key: " << key << endl; + kdDebug(14153) << 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 ICQAccount::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(14153) << 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 ); + + t = Oscar::findTLV( tList, 0x0131 ); + 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(14153) << k_funcinfo << "hash is :" << iconHash.hexDigest() << endl; + + //find old item, create updated item + if ( !item ) + { + kdDebug(14153) << k_funcinfo << "no existing icon hash item in ssi. creating new" << endl; + + TLV t; + t.type = 0x00D5; + t.data.resize( 18 ); + t.data[0] = 0x01; + t.data[1] = 0x10; + memcpy(t.data.data() + 2, iconHash.rawDigest(), 16); + t.length = t.data.size(); + + //alias, it's always empty + TLV t2; + t2.type = 0x0131; + t2.length = 0; + + QValueList<Oscar::TLV> list; + list.append( t ); + list.append( t2 ); + + 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(14153) << k_funcinfo << "setting new icon item" << endl; + engine()->modifySSIItem( item, s ); + } + else + { //found an item + Oscar::SSI s(item); + kdDebug(14153) << 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] = 0x01; + t.data[1] = 0x10; + memcpy(t.data.data() + 2, iconHash.rawDigest(), 16); + t.length = t.data.size(); + tList.append( t ); + + //add empty alias + t = Oscar::findTLV( tList, 0x0131 ); + if ( !t ) + { + t.type = 0x0131; + t.length = 0; + tList.append( t ); + } + + item.setTLVList( tList ); + //s is old, item is new. modification will occur + engine()->modifySSIItem( s, item ); + } + iconFile.close(); + } +} + +#include "icqaccount.moc" + +//kate: tab-width 4; indent-mode csands; diff --git a/kopete/protocols/oscar/icq/icqaccount.h b/kopete/protocols/oscar/icq/icqaccount.h new file mode 100644 index 00000000..f6231ec9 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqaccount.h @@ -0,0 +1,105 @@ +/* + icqaccount.h - ICQ Account Class Header + + Copyright (c) 2002 by Chris TenHarmsel <tenharmsel@staticmethod.net> + Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk> + 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 ICQACCOUNT_H +#define ICQACCOUNT_H + +#include "oscaraccount.h" +#include "oscarmyselfcontact.h" + +#include "icqpresence.h" +#include "oscartypeclasses.h" + +class KAction; +namespace Kopete { class AwayAction; } +class ICQProtocol; +class ICQAccount; +class OscarVisibilityDialog; + +class ICQMyselfContact : public OscarMyselfContact +{ +Q_OBJECT +public: + ICQMyselfContact( ICQAccount *acct ); + void userInfoUpdated(); + +public slots: + void receivedShortInfo( const QString& ); + void fetchShortInfo(); +}; + + +class ICQAccount : public OscarAccount +{ +Q_OBJECT + +public: + ICQAccount( Kopete::Protocol *parent, QString accountID, const char *name = 0L ); + virtual ~ICQAccount(); + + ICQProtocol *protocol(); + + // Accessor method for the action menu + virtual KActionMenu* actionMenu(); + + /** Reimplementation from Kopete::Account */ + void setOnlineStatus( const Kopete::OnlineStatus&, const QString& ); + + virtual void setAway( bool away, const QString &awayReason ); + + void connectWithPassword( const QString &password ); + + void setUserProfile( const QString &profile ); + +protected: + virtual OscarContact *createNewContact( const QString &contactId, Kopete::MetaContact *parentContact, const SSI& ssiItem ); + + virtual QString sanitizedMessage( const QString& message ); + +protected slots: + virtual void disconnected( DisconnectReason reason ); + + +private: + ICQ::Presence presence(); + + void setInvisible( ICQ::Presence::Visibility ); + void setPresenceType( ICQ::Presence::Type, const QString &awayMessage = QString::null ); + void setPresenceTarget( const ICQ::Presence &presence, const QString &message = QString::null ); + + //const unsigned long fullStatus( const unsigned long plainStatus ); + +private slots: + void slotToggleInvisible(); + + void slotSetVisiblility(); + void slotVisibilityDialogClosed(); + + void slotGlobalIdentityChanged( const QString& key, const QVariant& value ); + + void slotBuddyIconChanged(); + +private: + bool mWebAware; + bool mHideIP; + QString mInitialStatusMessage; + OscarVisibilityDialog* m_visibilityDialog; +}; + +#endif +//kate: indent-mode csands; diff --git a/kopete/protocols/oscar/icq/icqcontact.cpp b/kopete/protocols/oscar/icq/icqcontact.cpp new file mode 100644 index 00000000..8ba8d195 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqcontact.cpp @@ -0,0 +1,939 @@ +/* + icqontact.cpp - Oscar Protocol Plugin + + Copyright (c) 2003 by Stefan Gehn <metz AT gehn.net> + Copyright (c) 2003 by Olivier Goffart + Kopete (c) 2003-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 "icqcontact.h" + +#include <qtimer.h> +#include <qimage.h> +#include <qfile.h> + +#include <kaction.h> +#include <kactionclasses.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <knotifyclient.h> +#include <kpassivepopup.h> +#include <kinputdialog.h> +#include <kmdcodec.h> +#include <kstandarddirs.h> + +#include "kopetechatsessionmanager.h" +#include "kopeteuiglobal.h" +#include "kopetemetacontact.h" + +#include "icquserinfo.h" +#include "icqreadaway.h" +#include "icqprotocol.h" +#include "icqaccount.h" +#include "icqpresence.h" +#include "icquserinfowidget.h" +#include "icqauthreplydialog.h" + +#include "client.h" +#include "oscarutils.h" +#include "oscarencodingselectiondialog.h" +#include "ssimanager.h" + +ICQContact::ICQContact( ICQAccount *account, const QString &name, Kopete::MetaContact *parent, + const QString& icon, const Oscar::SSI& ssiItem ) +: OscarContact( account, name, parent, icon, ssiItem ) +{ + mProtocol = static_cast<ICQProtocol *>(protocol()); + m_infoWidget = 0L; + m_requestingNickname = false; + m_oesd = 0; + m_buddyIconDirty = false; + + if ( ssiItem.waitingAuth() ) + setOnlineStatus( mProtocol->statusManager()->waitingForAuth() ); + else + setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() ); + + QObject::connect( mAccount->engine(), SIGNAL( loggedIn() ), this, SLOT( loggedIn() ) ); + //QObject::connect( mAccount->engine(), SIGNAL( userIsOnline( const QString& ) ), this, SLOT( userOnline( const QString&, UserDetails ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( userIsOffline( const QString& ) ), this, SLOT( userOffline( const QString& ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( authRequestReceived( const QString&, const QString& ) ), + this, SLOT( slotGotAuthRequest( const QString&, const QString& ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( authReplyReceived( const QString&, const QString&, bool ) ), + this, SLOT( slotGotAuthReply(const QString&, const QString&, bool ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( receivedIcqShortInfo( const QString& ) ), + this, SLOT( receivedShortInfo( const QString& ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( receivedIcqLongInfo( const QString& ) ), + this, SLOT( receivedLongInfo( const QString& ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( receivedUserInfo( const QString&, const UserDetails& ) ), + this, SLOT( userInfoUpdated( const QString&, const UserDetails& ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( receivedAwayMessage( const QString&, const QString& ) ), + this, SLOT( receivedStatusMessage( const QString&, const QString& ) ) ); + QObject::connect( mAccount->engine(), SIGNAL( receivedAwayMessage( const Oscar::Message& ) ), + this, SLOT( receivedStatusMessage( const Oscar::Message& ) ) ); + QObject::connect( this, SIGNAL( featuresUpdated() ), this, SLOT( updateFeatures() ) ); + QObject::connect( mAccount->engine(), SIGNAL( iconServerConnected() ), + this, SLOT( requestBuddyIcon() ) ); + QObject::connect( mAccount->engine(), SIGNAL( haveIconForContact( const QString&, QByteArray ) ), + this, SLOT( haveIcon( const QString&, QByteArray ) ) ); + +} + +ICQContact::~ICQContact() +{ + delete m_infoWidget; +} + +void ICQContact::updateSSIItem() +{ + //kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << endl; + if ( m_ssiItem.waitingAuth() ) + setOnlineStatus( mProtocol->statusManager()->waitingForAuth() ); + + if ( m_ssiItem.type() != 0xFFFF && m_ssiItem.waitingAuth() == false && + onlineStatus() == Kopete::OnlineStatus::Unknown ) + { + //make sure they're offline + setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() ); + } +} + + +void ICQContact::userInfoUpdated( const QString& contact, const UserDetails& details ) +{ + //kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << contact << contactId() << endl; + if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) ) + return; + + // invalidate old away message if user was offline + if ( !isOnline() ) + removeProperty( mProtocol->awayMessage ); + + kdDebug( OSCAR_ICQ_DEBUG ) << k_funcinfo << "extendedStatus is " << details.extendedStatus() << endl; + ICQ::Presence presence = ICQ::Presence::fromOscarStatus( details.extendedStatus() & 0xffff ); + setOnlineStatus( presence.toOnlineStatus() ); + + // ICQ does not support status messages for state Online + if ( presence.type() == ICQ::Presence::Online ) + { + mAccount->engine()->removeICQAwayMessageRequest( contactId() ); + removeProperty( mProtocol->awayMessage ); + } + else + { + if ( ICQ::Presence::fromOnlineStatus( account()->myself()->onlineStatus() ).visibility() == ICQ::Presence::Visible ) + { + switch ( presence.type() ) + { + case ICQ::Presence::Away: + mAccount->engine()->addICQAwayMessageRequest( contactId(), Client::ICQAway ); + break; + case ICQ::Presence::NotAvailable: + mAccount->engine()->addICQAwayMessageRequest( contactId(), Client::ICQNotAvailable ); + break; + case ICQ::Presence::Occupied: + mAccount->engine()->addICQAwayMessageRequest( contactId(), Client::ICQOccupied ); + break; + case ICQ::Presence::DoNotDisturb: + mAccount->engine()->addICQAwayMessageRequest( contactId(), Client::ICQDoNotDisturb ); + break; + case ICQ::Presence::FreeForChat: + mAccount->engine()->addICQAwayMessageRequest( contactId(), Client::ICQFreeForChat ); + break; + default: + break; + } + } + else + { + mAccount->engine()->removeICQAwayMessageRequest( contactId() ); + } + } + + + if ( details.dcOutsideSpecified() ) + { + if ( details.dcExternalIp().isUnspecified() ) + removeProperty( mProtocol->ipAddress ); + else + setProperty( mProtocol->ipAddress, details.dcExternalIp().toString() ); + } + + if ( details.capabilitiesSpecified() ) + { + if ( details.clientName().isEmpty() ) + removeProperty( mProtocol->clientFeatures ); + else + setProperty( mProtocol->clientFeatures, details.clientName() ); + } + + if ( details.buddyIconHash().size() > 0 && details.buddyIconHash() != m_details.buddyIconHash() ) + { + m_buddyIconDirty = true; + if ( cachedBuddyIcon( details.buddyIconHash() ) == false ) + { + if ( !mAccount->engine()->hasIconConnection() ) + { + mAccount->engine()->connectToIconServer(); + } + else + { + 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 ICQContact::userOnline( const QString& userId ) +{ + if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) ) + return; + + kdDebug(OSCAR_ICQ_DEBUG) << "Setting " << userId << " online" << endl; + ICQ::Presence online = mProtocol->statusManager()->presenceOf( ICQ::Presence::Online ); + //mAccount->engine()->requestStatusInfo( contactId() ); +} + +void ICQContact::userOffline( const QString& userId ) +{ + if ( Oscar::normalize( userId ) != Oscar::normalize( contactId() ) ) + return; + + kdDebug(OSCAR_ICQ_DEBUG) << "Setting " << userId << " offline" << endl; + ICQ::Presence offline = mProtocol->statusManager()->presenceOf( ICQ::Presence::Offline ); + setOnlineStatus( mProtocol->statusManager()->onlineStatusOf( offline ) ); +} + +void ICQContact::loggedIn() +{ + if ( metaContact()->isTemporary() ) + return; + + if ( m_ssiItem.waitingAuth() ) + setOnlineStatus( mProtocol->statusManager()->waitingForAuth() ); + + if ( ( ( hasProperty( Kopete::Global::Properties::self()->nickName().key() ) + && nickName() == contactId() ) + || !hasProperty( Kopete::Global::Properties::self()->nickName().key() ) ) && + !m_requestingNickname && m_ssiItem.alias().isEmpty() ) + { + m_requestingNickname = true; + int time = ( KApplication::random() % 20 ) * 1000; + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "updating nickname in " << time/1000 << " seconds" << endl; + QTimer::singleShot( time, this, SLOT( requestShortInfo() ) ); + } + +} + +void ICQContact::requestShortInfo() +{ + if ( mAccount->isConnected() ) + mAccount->engine()->requestShortInfo( contactId() ); +} + +void ICQContact::slotRequestAuth() +{ + QString reason = KInputDialog::getText( i18n("Request Authorization"), + i18n("Reason for requesting authorization:") ); + if ( !reason.isNull() ) + mAccount->engine()->requestAuth( contactId(), reason ); +} + +void ICQContact::slotSendAuth() +{ + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "Sending auth reply" << endl; + ICQAuthReplyDialog replyDialog( 0, "replyDialog", false ); + + replyDialog.setUser( property( Kopete::Global::Properties::self()->nickName() ).value().toString() ); + if ( replyDialog.exec() ) + mAccount->engine()->sendAuth( contactId(), replyDialog.reason(), replyDialog.grantAuth() ); +} + +void ICQContact::slotGotAuthReply( const QString& contact, const QString& reason, bool granted ) +{ + if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) ) + return; + + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << endl; + QString message; + if( granted ) + { + message = i18n( "User %1 has granted your authorization request.\nReason: %2" ) + .arg( property( Kopete::Global::Properties::self()->nickName() ).value().toString() ) + .arg( reason ); + + // remove the unknown status + setOnlineStatus( ICQ::Presence( ICQ::Presence::Offline, ICQ::Presence::Visible ).toOnlineStatus() ); + } + else + { + message = i18n( "User %1 has rejected the authorization request.\nReason: %2" ) + .arg( property( Kopete::Global::Properties::self()->nickName() ).value().toString() ) + .arg( reason ); + } + KNotifyClient::event( Kopete::UI::Global::sysTrayWId(), "icq_authorization", message ); +} + +void ICQContact::slotGotAuthRequest( const QString& contact, const QString& reason ) +{ + if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) ) + return; + + ICQAuthReplyDialog *replyDialog = new ICQAuthReplyDialog(); + + connect( replyDialog, SIGNAL( okClicked() ), this, SLOT( slotAuthReplyDialogOkClicked() ) ); + replyDialog->setUser( property( Kopete::Global::Properties::self()->nickName() ).value().toString() ); + replyDialog->setRequestReason( reason ); + replyDialog->setModal( TRUE ); + replyDialog->show(); +} + +void ICQContact::slotAuthReplyDialogOkClicked() +{ + // Do not need to delete will delete itself automatically + ICQAuthReplyDialog *replyDialog = (ICQAuthReplyDialog*)sender(); + + if (replyDialog) + mAccount->engine()->sendAuth( contactId(), replyDialog->reason(), replyDialog->grantAuth() ); +} + +void ICQContact::receivedLongInfo( const QString& contact ) +{ + if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) ) + { + if ( m_infoWidget ) + m_infoWidget->delayedDestruct(); + return; + } + + QTextCodec* codec = contactCodec(); + + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "received long info from engine" << endl; + + ICQGeneralUserInfo genInfo = mAccount->engine()->getGeneralInfo( contact ); + if ( m_ssiItem.alias().isEmpty() && !genInfo.nickname.isEmpty() ) + setNickName( codec->toUnicode( genInfo.nickname ) ); + emit haveBasicInfo( genInfo ); + + ICQWorkUserInfo workInfo = mAccount->engine()->getWorkInfo( contact ); + emit haveWorkInfo( workInfo ); + + ICQMoreUserInfo moreInfo = mAccount->engine()->getMoreInfo( contact ); + emit haveMoreInfo( moreInfo ); + + ICQInterestInfo interestInfo = mAccount->engine()->getInterestInfo( contact ); + emit haveInterestInfo( interestInfo ); + +} + +void ICQContact::receivedShortInfo( const QString& contact ) +{ + if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) ) + return; + + QTextCodec* codec = contactCodec(); + + m_requestingNickname = false; //done requesting nickname + ICQShortInfo shortInfo = mAccount->engine()->getShortInfo( contact ); + /* + if(!shortInfo.firstName.isEmpty()) + setProperty( mProtocol->firstName, codec->toUnicode( shortInfo.firstName ) ); + else + removeProperty(mProtocol->firstName); + + if(!shortInfo.lastName.isEmpty()) + setProperty( mProtocol->lastName, codec->toUnicode( shortInfo.lastName ) ); + else + removeProperty(mProtocol->lastName); + */ + if ( m_ssiItem.alias().isEmpty() && !shortInfo.nickname.isEmpty() ) + { + kdDebug(14153) << k_funcinfo << + "setting new displayname for former UIN-only Contact" << endl; + setProperty( Kopete::Global::Properties::self()->nickName(), codec->toUnicode( shortInfo.nickname ) ); + } + +} + +void ICQContact::receivedStatusMessage( const QString &contact, const QString &message ) +{ + if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) ) + return; + + if ( ! message.isEmpty() ) + setProperty( mProtocol->awayMessage, message ); + else + removeProperty( mProtocol->awayMessage ); +} + +void ICQContact::receivedStatusMessage( const Oscar::Message &message ) +{ + if ( Oscar::normalize( message.sender() ) != Oscar::normalize( contactId() ) ) + return; + + //decode message + QTextCodec* codec = contactCodec(); + + QString realText = message.text(codec); + + if ( !realText.isEmpty() ) + setProperty( mProtocol->awayMessage, realText ); + else + removeProperty( mProtocol->awayMessage ); +} + +void ICQContact::slotSendMsg( Kopete::Message& msg, Kopete::ChatSession* session ) +{ + //Why is this unused? + Q_UNUSED( session ); + + QTextCodec* codec = contactCodec(); + + int messageChannel = 0x01; + Oscar::Message::Encoding messageEncoding; + + if ( isOnline() && m_details.hasCap( CAP_UTF8 ) ) + messageEncoding = Oscar::Message::UCS2; + else + messageEncoding = Oscar::Message::UserDefined; + + QString msgText( msg.plainBody() ); + // TODO: More intelligent handling of message length. + uint chunk_length = !isOnline() ? 450 : 4096; + uint msgPosition = 0; + + do + { + QString msgChunk( msgText.mid( msgPosition, chunk_length ) ); + // Try to split on space if needed + if ( msgChunk.length() == chunk_length ) + { + for ( int i = 0; i < 100; i++ ) + { + if ( msgChunk[chunk_length - i].isSpace() ) + { + msgChunk = msgChunk.left( chunk_length - i ); + msgPosition++; + } + } + } + msgPosition += msgChunk.length(); + + Oscar::Message message( messageEncoding, msgChunk, messageChannel, 0, msg.timestamp(), codec ); + message.setSender( mAccount->accountId() ); + message.setReceiver( mName ); + mAccount->engine()->sendMessage( message ); + } while ( msgPosition < msgText.length() ); + + manager(Kopete::Contact::CanCreate)->appendMessage(msg); + manager(Kopete::Contact::CanCreate)->messageSucceeded(); +} + +void ICQContact::updateFeatures() +{ + setProperty( static_cast<ICQProtocol*>(protocol())->clientFeatures, m_clientFeatures ); +} + +void ICQContact::requestBuddyIcon() +{ + if ( m_buddyIconDirty && m_details.buddyIconHash().size() > 0 ) + { + account()->engine()->requestBuddyIcon( contactId(), m_details.buddyIconHash(), + m_details.iconCheckSumType() ); + } +} + +void ICQContact::haveIcon( const QString& user, QByteArray icon ) +{ + if ( Oscar::normalize( user ) != Oscar::normalize( contactId() ) ) + return; + + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "Updating icon for " << contactId() << endl; + + KMD5 buddyIconHash( icon ); + if ( memcmp( buddyIconHash.rawDigest(), m_details.buddyIconHash().data(), 16 ) == 0 ) + { + QString iconLocation( locateLocal( "appdata", "oscarpictures/"+ contactId() ) ); + + QFile iconFile( iconLocation ); + if ( !iconFile.open( IO_WriteOnly ) ) + { + kdDebug(14153) << k_funcinfo << "Cannot open file" + << iconLocation << " for writing!" << endl; + return; + } + + iconFile.writeBlock( icon ); + iconFile.close(); + + setProperty( Kopete::Global::Properties::self()->photo(), QString::null ); + setProperty( Kopete::Global::Properties::self()->photo(), iconLocation ); + m_buddyIconDirty = false; + } + else + { + kdDebug(14153) << k_funcinfo << "Buddy icon hash does not match!" << endl; + removeProperty( Kopete::Global::Properties::self()->photo() ); + } +} + +bool ICQContact::cachedBuddyIcon( QByteArray hash ) +{ + QString iconLocation( locateLocal( "appdata", "oscarpictures/"+ contactId() ) ); + + QFile iconFile( iconLocation ); + if ( !iconFile.open( IO_ReadOnly ) ) + return false; + + KMD5 buddyIconHash; + buddyIconHash.update( iconFile ); + iconFile.close(); + + if ( memcmp( buddyIconHash.rawDigest(), hash.data(), 16 ) == 0 ) + { + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "Updating icon for " + << contactId() << " from local cache" << endl; + setProperty( Kopete::Global::Properties::self()->photo(), QString::null ); + setProperty( Kopete::Global::Properties::self()->photo(), iconLocation ); + m_buddyIconDirty = false; + return true; + } + else + { + return false; + } +} + +#if 0 +void ICQContact::slotContactChanged(const UserInfo &u) +{ + if (u.sn != contactName()) + return; + + // update mInfo and general stuff from OscarContact + slotParseUserInfo(u); + + /*kdDebug(14190) << k_funcinfo << "Called for '" + << displayName() << "', contactName()=" << contactName() << endl;*/ + QStringList capList; + // Append client name and version in case we found one + if (!mInfo.clientName.isEmpty()) + { + if (!mInfo.clientVersion.isEmpty()) + { + capList << i18n("Translators: client-name client-version", + "%1 %2").arg(mInfo.clientName, mInfo.clientVersion); + } + else + { + capList << mInfo.clientName; + } + } + // and now for some general informative capabilities + if (hasCap(CAP_UTF8)) + capList << i18n("UTF-8"); + if (hasCap(CAP_RTFMSGS)) + capList << i18n("RTF-Messages"); + if (hasCap(CAP_IMIMAGE)) + capList << i18n("DirectIM/IMImage"); + if (hasCap(CAP_CHAT)) + capList << i18n("Groupchat"); + + if (capList.count() > 0) + setProperty(mProtocol->clientFeatures, capList.join(", ")); + else + removeProperty(mProtocol->clientFeatures); + + unsigned int newStatus = 0; + mInvisible = (mInfo.icqextstatus & ICQ_STATUS_IS_INVIS); + + if (mInfo.icqextstatus & ICQ_STATUS_IS_FFC) + newStatus = OSCAR_FFC; + else if (mInfo.icqextstatus & ICQ_STATUS_IS_DND) + newStatus = OSCAR_DND; + else if (mInfo.icqextstatus & ICQ_STATUS_IS_OCC) + newStatus = OSCAR_OCC; + else if (mInfo.icqextstatus & ICQ_STATUS_IS_NA) + newStatus = OSCAR_NA; + else if (mInfo.icqextstatus & ICQ_STATUS_IS_AWAY) + newStatus = OSCAR_AWAY; + else + newStatus = OSCAR_ONLINE; + + if (this != account()->myself()) + { + if(newStatus != onlineStatus().internalStatus()) + { + if(newStatus != OSCAR_ONLINE) // if user changed to some state other than online + { + mAccount->engine()->requestAwayMessage(this); + } + else // user changed to "Online" status and has no away message anymore + { + removeProperty(mProtocol->awayMessage); + } + } + } + + setStatus(newStatus); +} + +void ICQContact::slotOffgoingBuddy(QString sender) +{ + if(sender != contactName()) + return; + + removeProperty(mProtocol->clientFeatures); + removeProperty(mProtocol->awayMessage); + setOnlineStatus(mProtocol->statusOffline); +} + +void ICQContact::gotIM(OscarSocket::OscarMessageType /*type*/, const QString &message) +{ + // Build a Kopete::Message and set the body as Rich Text + Kopete::ContactPtrList tmpList; + tmpList.append(account()->myself()); + Kopete::Message msg(this, tmpList, message, Kopete::Message::Inbound, + Kopete::Message::RichText); + manager(true)->appendMessage(msg); +} + + +void ICQContact::slotSendMsg(Kopete::Message& message, Kopete::ChatSession *) +{ + if (message.plainBody().isEmpty()) // no text, do nothing + return; + + // Check to see if we're even online + if(!account()->isConnected()) + { + KMessageBox::sorry(Kopete::UI::Global::mainWidget(), + i18n("<qt>You must be logged on to ICQ before you can " + "send a message to a user.</qt>"), + i18n("Not Signed On")); + return; + } + + // FIXME: We don't do HTML in ICQ + // we might be able to do that in AIM and we might also convert + // HTML to RTF for ICQ type-2 messages [mETz] + static_cast<OscarAccount*>(account())->engine()->sendIM( + message.plainBody(), this, false); + + // Show the message we just sent in the chat window + manager(Kopete::Contact::CanCreate)->appendMessage(message); + manager(Kopete::Contact::CanCreate)->messageSucceeded(); +} + +#endif + +bool ICQContact::isReachable() +{ + return account()->isConnected(); +} + +QPtrList<KAction> *ICQContact::customContextMenuActions() +{ + QPtrList<KAction> *actionCollection = new QPtrList<KAction>(); +/* + QString awTxt; + QString awIcn; + unsigned int status = onlineStatus().internalStatus(); + if (status >= 15) + status -= 15; // get rid of invis addon + switch(status) + { + case OSCAR_FFC: + awTxt = i18n("Read 'Free For Chat' &Message"); + awIcn = "icq_ffc"; + break; + case OSCAR_DND: + awTxt = i18n("Read 'Do Not Disturb' &Message"); + awIcn = "icq_dnd"; + break; + case OSCAR_NA: + awTxt = i18n("Read 'Not Available' &Message"); + awIcn = "icq_na"; + break; + case OSCAR_OCC: + awTxt = i18n("Read 'Occupied' &Message"); + awIcn = "icq_occ"; + break; + default: + awTxt = i18n("Read 'Away' &Message"); + awIcn = "icq_away"; + break; + } + + if(actionReadAwayMessage==0) + { + actionReadAwayMessage = new KAction(awTxt, awIcn, 0, + this, SLOT(slotReadAwayMessage()), this, "actionReadAwayMessage"); + */ + actionRequestAuth = new KAction(i18n("&Request Authorization"), "mail_reply", 0, + this, SLOT(slotRequestAuth()), this, "actionRequestAuth"); + actionSendAuth = new KAction(i18n("&Grant Authorization"), "mail_forward", 0, + this, SLOT(slotSendAuth()), this, "actionSendAuth"); + /* + } + else + { + actionReadAwayMessage->setText(awTxt); + actionReadAwayMessage->setIconSet(SmallIconSet(awIcn)); + } + +*/ + m_actionIgnore = new KToggleAction(i18n("&Ignore"), "", 0, + this, SLOT(slotIgnore()), this, "actionIgnore"); + 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(); + if ( m_ssiItem.waitingAuth() ) + actionRequestAuth->setEnabled(on); + else + actionRequestAuth->setEnabled(false); + + actionSendAuth->setEnabled(on); + + + m_selectEncoding = new KAction( i18n( "Select Encoding..." ), "charset", 0, + this, SLOT( changeContactEncoding() ), this, "changeEncoding" ); + +/* + actionReadAwayMessage->setEnabled(status != OSCAR_OFFLINE && status != OSCAR_ONLINE); +*/ + m_actionIgnore->setEnabled(on); + m_actionVisibleTo->setEnabled(on); + m_actionInvisibleTo->setEnabled(on); + + SSIManager* ssi = account()->engine()->ssiManager(); + m_actionIgnore->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_IGNORE )); + m_actionVisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_VISIBLE )); + m_actionInvisibleTo->setChecked( ssi->findItem( m_ssiItem.name(), ROSTER_INVISIBLE )); + + actionCollection->append(actionRequestAuth); + actionCollection->append(actionSendAuth); + actionCollection->append( m_selectEncoding ); + + actionCollection->append(m_actionIgnore); + actionCollection->append(m_actionVisibleTo); + actionCollection->append(m_actionInvisibleTo); + +// actionCollection->append(actionReadAwayMessage); + + return actionCollection; +} + + +void ICQContact::slotUserInfo() +{ + m_infoWidget = new ICQUserInfoWidget( Kopete::UI::Global::mainWidget(), "icq info" ); + QObject::connect( m_infoWidget, SIGNAL( finished() ), this, SLOT( closeUserInfoDialog() ) ); + m_infoWidget->setContact( this ); + m_infoWidget->show(); + if ( account()->isConnected() ) + mAccount->engine()->requestFullInfo( contactId() ); +} + +void ICQContact::closeUserInfoDialog() +{ + QObject::disconnect( this, 0, m_infoWidget, 0 ); + m_infoWidget->delayedDestruct(); + m_infoWidget = 0L; +} + +void ICQContact::changeContactEncoding() +{ + if ( m_oesd ) + return; + + m_oesd = new OscarEncodingSelectionDialog( Kopete::UI::Global::mainWidget(), property(mProtocol->contactEncoding).value().toInt() ); + connect( m_oesd, SIGNAL( closing( int ) ), + this, SLOT( changeEncodingDialogClosed( int ) ) ); + m_oesd->show(); +} + +void ICQContact::changeEncodingDialogClosed( int result ) +{ + if ( result == QDialog::Accepted ) + { + int mib = m_oesd->selectedEncoding(); + if ( mib != 0 ) + { + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "setting encoding mib to " + << m_oesd->selectedEncoding() << endl; + setProperty( mProtocol->contactEncoding, m_oesd->selectedEncoding() ); + } + else + { + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo + << "setting encoding to default" << endl; + removeProperty( mProtocol->contactEncoding ); + } + } + + if ( m_oesd ) + { + m_oesd->delayedDestruct(); + m_oesd = 0L; + } +} + + +void ICQContact::slotIgnore() +{ + account()->engine()->setIgnore( contactId(), m_actionIgnore->isChecked() ); +} + +void ICQContact::slotVisibleTo() +{ + account()->engine()->setVisibleTo( contactId(), m_actionVisibleTo->isChecked() ); +} + +void ICQContact::slotInvisibleTo() +{ + account()->engine()->setInvisibleTo( contactId(), m_actionInvisibleTo->isChecked() ); +} + +#if 0 + +void ICQContact::slotReadAwayMessage() +{ + kdDebug(14153) << k_funcinfo << "account='" << account()->accountId() << + "', contact='" << displayName() << "'" << endl; + + if (!awayMessageDialog) + { + awayMessageDialog = new ICQReadAway(this, 0L, "awayMessageDialog"); + if(!awayMessageDialog) + return; + QObject::connect(awayMessageDialog, SIGNAL(closing()), this, SLOT(slotCloseAwayMessageDialog())); + awayMessageDialog->show(); + } + else + { + awayMessageDialog->raise(); + } +} + + +void ICQContact::slotCloseAwayMessageDialog() +{ + awayMessageDialog->delayedDestruct(); + awayMessageDialog = 0L; +} + + +const QString ICQContact::awayMessage() +{ + kdDebug(14150) << k_funcinfo << property(mProtocol->awayMessage).value().toString() << endl; + return property(mProtocol->awayMessage).value().toString(); +} + + +void ICQContact::setAwayMessage(const QString &message) +{ + /*kdDebug(14150) << k_funcinfo << + "Called for '" << displayName() << "', away msg='" << message << "'" << endl;*/ + setProperty(mProtocol->awayMessage, message); + emit awayMessageChanged(); +} + + +void ICQContact::slotUpdGeneralInfo(const int seq, const ICQGeneralUserInfo &inf) +{ + // compare reply's sequence with the one we sent with our last request + if(seq != userinfoRequestSequence) + return; + generalInfo = inf; + + if(!generalInfo.firstName.isEmpty()) + setProperty(mProtocol->firstName, generalInfo.firstName); + else + removeProperty(mProtocol->firstName); + + if(!generalInfo.lastName.isEmpty()) + setProperty(mProtocol->lastName, generalInfo.lastName); + else + removeProperty(mProtocol->lastName); + + if(!generalInfo.eMail.isEmpty()) + setProperty(mProtocol->emailAddress, generalInfo.eMail); + else + removeProperty(mProtocol->emailAddress); + /* + if(!generalInfo.phoneNumber.isEmpty()) + setProperty("privPhoneNum", generalInfo.phoneNumber); + else + removeProperty("privPhoneNum"); + + if(!generalInfo.faxNumber.isEmpty()) + setProperty("privFaxNum", generalInfo.faxNumber); + else + removeProperty("privFaxNum"); + + if(!generalInfo.cellularNumber.isEmpty()) + setProperty("privMobileNum", generalInfo.cellularNumber); + else + removeProperty("privMobileNum"); + */ + + if(contactName() == displayName() && !generalInfo.nickName.isEmpty()) + { + kdDebug(14153) << k_funcinfo << "setting new displayname for former UIN-only Contact" << endl; + setDisplayName(generalInfo.nickName); + } + + incUserInfoCounter(); +} + + +void ICQContact::slotSnacFailed(WORD snacID) +{ + if (userinfoRequestSequence != 0) + kdDebug(14153) << k_funcinfo << "snacID = " << snacID << " seq = " << userinfoRequestSequence << endl; + + //TODO: ugly interaction between snacID and request sequence, see OscarSocket::sendCLI_TOICQSRV + if (snacID == (0x0000 << 16) | userinfoRequestSequence) + { + userinfoRequestSequence = 0; + emit userInfoRequestFailed(); + } +} + +void ICQContact::slotIgnore() +{ + kdDebug(14150) << k_funcinfo << + "Called; ignore = " << actionIgnore->isChecked() << endl; + setIgnore(actionIgnore->isChecked(), true); +} + +void ICQContact::slotVisibleTo() +{ + kdDebug(14150) << k_funcinfo << + "Called; visible = " << actionVisibleTo->isChecked() << endl; + setVisibleTo(actionVisibleTo->isChecked(), true); +} +#endif +#include "icqcontact.moc" +//kate: indent-mode csands; tab-width 4; replace-tabs off; space-indent off; diff --git a/kopete/protocols/oscar/icq/icqcontact.h b/kopete/protocols/oscar/icq/icqcontact.h new file mode 100644 index 00000000..41084e63 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqcontact.h @@ -0,0 +1,155 @@ +/* + icqcontact.h - ICQ Contact + + Copyright (c) 2003 by Stefan Gehn <metz AT gehn.net> + Copyright (c) 2003 by Olivier Goffart + Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk> + 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 ICQCONTACT_H +#define ICQCONTACT_H + +#include "oscarcontact.h" +#include "userdetails.h" + +class OscarEncodingSelectionDialog; +class KAction; +class KToggleAction; +namespace Kopete { class ChatSession; } +namespace Kopete { class OnlineStatus; } +class ICQProtocol; +class ICQAccount; +class OscarAccount; +class ICQUserInfo; // user info dialog +class ICQReadAway; + +class ICQGeneralUserInfo; +class ICQWorkUserInfo; +class ICQUserInfoWidget; +class ICQInterestInfoWidget; + +/** + * Contact for ICQ over Oscar protocol + * @author Stefan Gehn + * @author Richard Smith + * @author Matt Rogers + */ +class ICQContact : public OscarContact +{ +Q_OBJECT + +public: + + /** Normal ICQ constructor */ + ICQContact( ICQAccount *account, const QString &name, Kopete::MetaContact *parent, + const QString& icon = QString::null, const Oscar::SSI& ssiItem = Oscar::SSI() ); + virtual ~ICQContact(); + + /** + * Returns a set of custom menu items for + * the context menu + */ + virtual QPtrList<KAction> *customContextMenuActions(); + + /** Return whether or not this contact is reachable. */ + virtual bool isReachable(); + + + //virtual const QString awayMessage(); + //virtual void setAwayMessage(const QString &message); + +public slots: + virtual void slotUserInfo(); + virtual void updateSSIItem(); + void userInfoUpdated( const QString& contact, const UserDetails& details ); + + void userOnline( const QString& userId ); + void userOffline( const QString& userID ); + void loggedIn(); + + void requestShortInfo(); + +signals: + void haveBasicInfo( const ICQGeneralUserInfo& ); + void haveWorkInfo( const ICQWorkUserInfo& ); + void haveEmailInfo( const ICQEmailInfo& ); + void haveMoreInfo( const ICQMoreUserInfo& ); + void haveInterestInfo( const ICQInterestInfo& ); + +private: + bool cachedBuddyIcon( QByteArray hash ); + bool m_buddyIconDirty; + + bool m_requestingNickname; + ICQProtocol *mProtocol; + ICQUserInfoWidget* m_infoWidget; + /* + ICQReadAway *awayMessageDialog; + KAction *actionReadAwayMessage; + */ + KAction *actionRequestAuth; + KAction *actionSendAuth; + KAction *m_selectEncoding; + + KToggleAction *m_actionIgnore; + KToggleAction *m_actionVisibleTo; + KToggleAction *m_actionInvisibleTo; + + /* + bool mInvisible; + */ + + OscarEncodingSelectionDialog* m_oesd; + +protected slots: + virtual void slotSendMsg(Kopete::Message& message, Kopete::ChatSession *); + virtual void updateFeatures(); + +private slots: + /** Request authorization from this contact */ + void slotRequestAuth(); + + /** Authorize this contact */ + void slotSendAuth(); + + void slotAuthReplyDialogOkClicked(); + + /** We have received an auth request */ + void slotGotAuthRequest( const QString& contact, const QString& reason ); + + /** We have received an auth reply */ + void slotGotAuthReply( const QString& contact, const QString& reason, bool granted ); + + void closeUserInfoDialog(); + + void receivedLongInfo( const QString& contact ); + void receivedShortInfo( const QString& contact ); + + void changeContactEncoding(); + void changeEncodingDialogClosed( int ); + + void requestBuddyIcon(); + void haveIcon( const QString&, QByteArray ); + void receivedStatusMessage( const QString &contact, const QString &message ); + void receivedStatusMessage( const Oscar::Message &message ); + +//void slotCloseAwayMessageDialog(); + //void slotReadAwayMessage(); + + void slotIgnore(); + void slotVisibleTo(); + void slotInvisibleTo(); +}; + +#endif +//kate: tab-width 4; indent-mode csands; space-indent off; replace-tabs off; diff --git a/kopete/protocols/oscar/icq/icqpresence.cpp b/kopete/protocols/oscar/icq/icqpresence.cpp new file mode 100644 index 00000000..ab6bb670 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqpresence.cpp @@ -0,0 +1,294 @@ +/* + icqpresence.cpp - ICQ online status and presence management + + Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk> + 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 <utility> +#include <vector> + +#include <kdebug.h> +#include <klocale.h> +#include <kstaticdeleter.h> + +#include <kopeteonlinestatus.h> +#include <kopeteonlinestatusmanager.h> + +#include "icqprotocol.h" + +#include "icqpresence.h" + +namespace ICQ +{ + +//BEGIN struct PresenceTypeData + +struct PresenceTypeData +{ + Presence::Type type; + Kopete::OnlineStatus::StatusType onlineStatusType; + unsigned long setFlag; + unsigned long getFlag; + QString caption; + QString visibleName; + QString invisibleName; + const char *visibleIcon; + const char *invisibleIcon; + unsigned int categories; + unsigned int options; + + static const PresenceTypeData *all(); + static const PresenceTypeData &forType( Presence::Type type ); + static const PresenceTypeData &forStatus( unsigned long status ); + static const PresenceTypeData &forOnlineStatusType( const Kopete::OnlineStatus::StatusType statusType ); +}; + +const PresenceTypeData *PresenceTypeData::all() +{ + using namespace Kopete; + using namespace ICQ::StatusCode; + /** + * The order here is important - this is the order the IS_XXX flags will be checked for in. + * That, in particular, means that NA, Occupied and DND must appear before Away, and that + * DND must appear before Occupied. Offline (testing all bits) must go first, and Online + * (testing no bits - will always match a status) must go last. + * + * Free For Chat is currently listed after Away, since if someone is Away + Free For Chat we + * want to show them as Away more than we want to show them FFC. + */ + static const PresenceTypeData data[] = + { + { Presence::Offline, OnlineStatus::Offline, OFFLINE, OFFLINE, i18n( "O&ffline" ), i18n("Offline"), i18n("Offline"), 0, "contact_invisible_overlay", Kopete::OnlineStatusManager::Offline, 0 }, + { Presence::DoNotDisturb, OnlineStatus::Away, SET_DND, IS_DND, i18n( "&Do Not Disturb" ), i18n("Do Not Disturb"), i18n("Do Not Disturb (Invisible)"), "contact_busy_overlay", "contact_invisible_overlay", Kopete::OnlineStatusManager::Busy, Kopete::OnlineStatusManager::HasAwayMessage }, + { Presence::Occupied, OnlineStatus::Away, SET_OCC, IS_OCC, i18n( "O&ccupied" ), i18n("Occupied"), i18n("Occupied (Invisible)"), "contact_busy_overlay", "contact_invisible_overlay", 0, Kopete::OnlineStatusManager::HasAwayMessage }, + { Presence::NotAvailable, OnlineStatus::Away, SET_NA, IS_NA, i18n( "Not A&vailable" ), i18n("Not Available"), i18n("Not Available (Invisible)"), "contact_xa_overlay", "contact_invisible_overlay", Kopete::OnlineStatusManager::ExtendedAway, Kopete::OnlineStatusManager::HasAwayMessage }, + { Presence::Away, OnlineStatus::Away, SET_AWAY, IS_AWAY, i18n( "&Away" ), i18n("Away"), i18n("Away (Invisible)"), "contact_away_overlay", "contact_invisible_overlay", Kopete::OnlineStatusManager::Away, Kopete::OnlineStatusManager::HasAwayMessage }, + { Presence::FreeForChat, OnlineStatus::Online, SET_FFC, IS_FFC, i18n( "&Free for Chat" ), i18n("Free For Chat"), i18n("Free For Chat (Invisible)"), "icq_ffc", "contact_invisible_overlay", Kopete::OnlineStatusManager::FreeForChat, 0 }, + { Presence::Online, OnlineStatus::Online, ONLINE, ONLINE, i18n( "O&nline" ), i18n("Online"), i18n("Online (Invisible)"), 0, "contact_invisible_overlay", Kopete::OnlineStatusManager::Online, 0 } + }; + return data; +} + +const PresenceTypeData &PresenceTypeData::forType( Presence::Type type ) +{ + const PresenceTypeData *array = all(); + for ( uint n = 0; n < Presence::TypeCount; ++n ) + if ( array[n].type == type ) + return array[n]; + kdWarning(14153) << k_funcinfo << "type " << (int)type << " not found! Returning Offline" << endl; + return array[0]; +} + +const PresenceTypeData &PresenceTypeData::forStatus( unsigned long status ) +{ + const PresenceTypeData *array = all(); + for ( uint n = 0; n < Presence::TypeCount; ++n ) + { + //kdDebug(14153) << k_funcinfo << "array[n].getFlag is " << array[n].getFlag << ", status is " << status << ", & is " << (array[n].getFlag & status) << endl; + if ( (array[n].getFlag & status) == array[n].getFlag ) + return array[n]; + } + kdWarning(14153) << k_funcinfo << "status " << (int)status << " not found! Returning Offline. This should not happen." << endl; + return array[0]; +} + +const PresenceTypeData &PresenceTypeData::forOnlineStatusType( const Kopete::OnlineStatus::StatusType statusType ) +{ + const PresenceTypeData *array = all(); + for ( int n = Presence::TypeCount - 1; n >= 0; --n ) + { + if ( array[n].onlineStatusType == statusType ) + return array[n]; + } + kdWarning(14153) << k_funcinfo << "online status " << (int)statusType << " not found! Returning Offline. This should not happen." << endl; + return array[0]; +} + +//END struct PresenceTypeData + +//BEGIN class OnlineStatusManager + +class OnlineStatusManager::Private +{ +public: + typedef std::vector<Kopete::OnlineStatus> StatusList; + + // connecting and unknown should have the same internal status as offline, so converting to a Presence gives an Offline one + Private() + : connecting( Kopete::OnlineStatus::Connecting, 99, ICQProtocol::protocol(), + 99, "icq_connecting", i18n("Connecting...") ) + , unknown( Kopete::OnlineStatus::Unknown, 0, ICQProtocol::protocol(), + Presence::Offline, "status_unknown", i18n("Unknown") ) + , waitingForAuth( Kopete::OnlineStatus::Unknown, 1, ICQProtocol::protocol(), + Presence::Offline, "button_cancel", i18n("Waiting for Authorization") ) + , invisible( Kopete::OnlineStatus::Invisible, 2, ICQProtocol::protocol(), + Presence::Offline, QString::null, QString::null, + QString::null, Kopete::OnlineStatusManager::Invisible, + Kopete::OnlineStatusManager::HideFromMenu ) + + { + createStatusList( false, 0, visibleStatusList ); + createStatusList( true, Presence::TypeCount, invisibleStatusList ); + } + void createStatusList( bool invisible, const uint invisibleOffset, StatusList &statusList ) + { + //weight 0, 1 and 2 are used by KOS unknown, waitingForAuth and invisible + const uint firstUsableWeight = 3; + statusList.reserve( Presence::TypeCount ); + for ( uint n = 0; n < Presence::TypeCount; ++n ) + { + const PresenceTypeData &data = PresenceTypeData::forType( static_cast<Presence::Type>(n) ); + const uint weight = n + firstUsableWeight; + const uint internalStatus = n + invisibleOffset; + QStringList overlayIcons( data.visibleIcon ); + QString description( data.visibleName ); + Kopete::OnlineStatus status; + if ( invisible ) + { + overlayIcons << data.invisibleIcon; + description = data.invisibleName; + //don't add invisible KOS to account's context menu + status = Kopete::OnlineStatus( data.onlineStatusType, weight, + ICQProtocol::protocol(), internalStatus, + overlayIcons, description ); + } + else + { + //add visible KOS + status = Kopete::OnlineStatus( data.onlineStatusType, weight, + ICQProtocol::protocol(), internalStatus, + overlayIcons, description, + data.caption, data.categories, data.options ); + } + statusList.push_back( status ); + } + } + + StatusList visibleStatusList, invisibleStatusList; + Kopete::OnlineStatus connecting; + Kopete::OnlineStatus unknown; + Kopete::OnlineStatus waitingForAuth; + Kopete::OnlineStatus invisible; +}; + +OnlineStatusManager::OnlineStatusManager() + : d( new Private ) +{ +} + +OnlineStatusManager::~OnlineStatusManager() +{ + delete d; +} + +Presence OnlineStatusManager::presenceOf( uint internalStatus ) +{ + if ( internalStatus < Presence::TypeCount ) + { + return Presence( static_cast<Presence::Type>( internalStatus ), Presence::Visible ); + } + else if ( internalStatus < 2 * Presence::TypeCount ) + { + return Presence( static_cast<Presence::Type>( internalStatus - Presence::TypeCount ), Presence::Invisible ); + } + else + { + kdWarning(14153) << k_funcinfo << "No presence exists for internal status " << internalStatus << "! Returning Offline" << endl; + return Presence( Presence::Offline, Presence::Visible ); + } +} + +Kopete::OnlineStatus OnlineStatusManager::onlineStatusOf( const Presence &presence ) +{ + if ( presence.visibility() == Presence::Visible ) + return d->visibleStatusList[ presence.type() ]; + else + return d->invisibleStatusList[ presence.type() ]; +} + +Kopete::OnlineStatus OnlineStatusManager::connectingStatus() +{ + return d->connecting; +} + +Kopete::OnlineStatus OnlineStatusManager::unknownStatus() +{ + return d->unknown; +} + +Kopete::OnlineStatus OnlineStatusManager::waitingForAuth() +{ + return d->waitingForAuth; +} + +//END class OnlineStatusManager + +//BEGIN class Presence + +Presence Presence::fromOnlineStatus( const Kopete::OnlineStatus &status ) +{ + if ( status.protocol() == ICQProtocol::protocol() ) + { + OnlineStatusManager *store = ICQProtocol::protocol()->statusManager(); + return store->presenceOf( status.internalStatus() ); + } + else + { + //status is a libkopete builtin status object + //don't even think about converting it to ICQ::Presence using presenceOf! + return Presence( PresenceTypeData::forOnlineStatusType( status.status() ).type, + Presence::Visible ); + } +} + +Kopete::OnlineStatus Presence::toOnlineStatus() const +{ + OnlineStatusManager *store = ICQProtocol::protocol()->statusManager(); + return store->onlineStatusOf( *this ); +} + + +unsigned long Presence::toOscarStatus() const +{ + unsigned long basicStatus = basicOscarStatus(); + if ( _visibility == Invisible ) + basicStatus |= StatusCode::INVISIBLE; + return basicStatus; +} + +Presence Presence::fromOscarStatus( unsigned long code ) +{ + Type type = typeFromOscarStatus( code & ~StatusCode::INVISIBLE ); + bool invisible = (code & StatusCode::INVISIBLE) == StatusCode::INVISIBLE; + return Presence( type, invisible ? Invisible : Visible ); +} + + +unsigned long Presence::basicOscarStatus() const +{ + const PresenceTypeData &data = PresenceTypeData::forType( _type ); + return data.setFlag; +} + +Presence::Type Presence::typeFromOscarStatus( unsigned long status ) +{ + const PresenceTypeData &data = PresenceTypeData::forStatus( status ); + return data.type; +} + +//END class Presence + +} // end namespace ICQ + +// vim: set noet ts=4 sts=4 sw=4: +// kate: indent-mode: csands; space-indent off; tab-width 4; diff --git a/kopete/protocols/oscar/icq/icqpresence.h b/kopete/protocols/oscar/icq/icqpresence.h new file mode 100644 index 00000000..d7ef9ed2 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqpresence.h @@ -0,0 +1,177 @@ +/* + icqpresence.h - ICQ online status and presence management + + Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk> + 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 ICQCOMMON_H +#define ICQCOMMON_H + +#include <kdebug.h> + +namespace Kopete { class OnlineStatus; } + +namespace ICQ +{ + +class Presence; + +/** + * @brief This namespace contains status flags used in OSCAR's on-the-wire format. + * + * The IS_XXX values are bits representing actual status flags. However, the flags + * are just that -- flags. ICQ statuses are represented by a combination of these + * flags rather than just one value. This seems to be for backwards compatibility + * reasons -- this way you can add a new status and existing clients should still + * work correctly. + * + * So, when changing status you need to specify not only what status it is, but + * also all other status flags that are appropriate. The SET_XXX flags do just that; + * SET_DND for instance sets the DND, Occupied and Away bits. + */ +namespace StatusCode +{ + enum + { + OFFLINE = 0xFFFFFFFF, + ONLINE = 0x00000000, + INVISIBLE = 0x00000100, + + IS_DND = 0x00000002, ///< Do Not Disturb + IS_OCC = 0x00000010, ///< Occupied + IS_NA = 0x00000004, ///< Not Available + IS_AWAY = 0x00000001, ///< Away + IS_FFC = 0x00000020, ///< Free For Chat + + SET_DND = 0x00000013, //== DND + Occupied + Away + SET_OCC = 0x00000011, //== Occupied + Away + SET_NA = 0x00000005, //== NA + Away + SET_AWAY = 0x00000001, + SET_FFC = 0x00000020, + + WEBAWARE = 0x00010000, + SHOWIP = 0x00020000 + }; +} // end namespace StatusCode + +/** + * @brief A manager for ICQ's online statuses + * + * Looks after ICQ's numerous online statuses, and maps between them and Presence objects. + * A single instance of this class is held by the ICQProtocol object. + */ +class OnlineStatusManager +{ +public: + OnlineStatusManager(); + ~OnlineStatusManager(); + ICQ::Presence presenceOf( uint internalStatus ); + Kopete::OnlineStatus onlineStatusOf( const ICQ::Presence &presence ); + Kopete::OnlineStatus connectingStatus(); + Kopete::OnlineStatus unknownStatus(); + Kopete::OnlineStatus waitingForAuth(); + +private: + class Private; + Private *d; +}; + +/** + * @brief An ICQ online presence object + */ +class Presence +{ +public: + /** + * Friendly types this status can be + */ + enum Type { Offline, DoNotDisturb, Occupied, NotAvailable, Away, Online, FreeForChat }; + enum { TypeCount = FreeForChat + 1 }; + + enum Visibility { Invisible, Visible }; + + Presence( Type type, Visibility vis ) : _type(type), _visibility(vis) {} + + Type type() const { return _type; } + Visibility visibility() const { return _visibility; } + + /** + * Generate a Presence object from an online status + */ + static Presence fromOnlineStatus( const Kopete::OnlineStatus &status ); + + /** + * Convert this Presence object to an online status + */ + Kopete::OnlineStatus toOnlineStatus() const; + + /** + * Get the status code to pass to liboscar to set us to this Status. + * @note This is not the opposite of fromOnlineStatus(). The set and get codes don't match. + */ + unsigned long toOscarStatus() const; + + /** + * Get the status a contact is at based on liboscar's view of its status. + * @note This is not the opposite of toOnlineStatus(). + */ + static Presence fromOscarStatus( unsigned long code ); + + bool operator==( const Presence &other ) const { return other._type == _type && other._visibility == _visibility; } + bool operator!=( const Presence &other ) const { return !(*this == other); } + +private: + unsigned long basicOscarStatus() const; + static Type typeFromOscarStatus( unsigned long status ); +private: + Type _type; + Visibility _visibility; +}; + +} + +#if 0 +const unsigned int ICQ_PORT = 5190; + + +const unsigned short ICQ_SEARCHSTATE_OFFLINE = 0; +const unsigned short ICQ_SEARCHSTATE_ONLINE = 1; +const unsigned short ICQ_SEARCHSTATE_DISABLED = 2; + + +// Taken from libicq, not sure if we ever support these requests +const unsigned char PHONEBOOK_SIGN[16] = +{ + 0x90, 0x7C, 0x21, 0x2C, 0x91, 0x4D, 0xD3, 0x11, + 0xAD, 0xEB, 0x00, 0x04, 0xAC, 0x96, 0xAA, 0xB2 +}; + +const unsigned char PLUGINS_SIGN[16] = +{ + 0xF0, 0x02, 0xBF, 0x71, 0x43, 0x71, 0xD3, 0x11, + 0x8D, 0xD2, 0x00, 0x10, 0x4B, 0x06, 0x46, 0x2E +}; + +/* +const unsigned char SHARED_FILES_SIGN[16] = +{ + 0xF0, 0x2D, 0x12, 0xD9, 0x30, 0x91, 0xD3, 0x11, + 0x8D, 0xD7, 0x00, 0x10, 0x4B, 0x06, 0x46, 0x2E +}; +*/ +#endif + +#endif +// vim: set noet ts=4 sts=4 sw=4: +// kate: indent-mode: csands diff --git a/kopete/protocols/oscar/icq/icqprotocol.cpp b/kopete/protocols/oscar/icq/icqprotocol.cpp new file mode 100644 index 00000000..42616e32 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqprotocol.cpp @@ -0,0 +1,820 @@ +/* + icqprotocol.cpp - ICQ Protocol Plugin + + Copyright (c) 2003 by Olivier Goffart <ogoffart @ kde.org> + Copyright (c) 2004 by Richard Smith <kde@metafoo.co.uk> + 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 "config.h" + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif + +#include <netinet/in.h> // for ntohl() + +#include <qcombobox.h> +/* +#include <qhostaddress.h> +#include <qlistbox.h> +#include <qspinbox.h> +#include <qtextedit.h> + +#include <kdatewidget.h>*/ +#include <qvaluelist.h> +#include <kdialogbase.h> +/* +#include <klineedit.h> +#include <kurllabel.h> +*/ +#include <kgenericfactory.h> +#include <kdebug.h> +#include <klocale.h> +#include <ksimpleconfig.h> +#include <kmessagebox.h> + +#include "kopeteglobal.h" +#include "kopeteuiglobal.h" +#include "accountselector.h" +#include "kopeteaccountmanager.h" + +#include "oscartypeclasses.h" + +#include "icqaccount.h" +#include "icqcontact.h" +#include "icqaddcontactpage.h" +#include "icqeditaccountwidget.h" +//#include "icquserinfowidget.h" + + +#include "icqprotocol.h" + +typedef KGenericFactory<ICQProtocol> ICQProtocolFactory; +K_EXPORT_COMPONENT_FACTORY( kopete_icq, ICQProtocolFactory( "kopete_icq" ) ) + +//BEGIN class ICQProtocolHandler + +ICQProtocolHandler::ICQProtocolHandler() : Kopete::MimeTypeHandler(false) +{ + registerAsMimeHandler(QString::fromLatin1("application/x-icq")); +} + +void ICQProtocolHandler::handleURL(const QString &mimeType, const KURL & url) const +{ + if (mimeType != "application/x-icq") + return; + + /** + * File Format usually looks like + * + * [ICQ User] + * UIN=123456789 + * Email= + * NickName= + * FirstName= + * LastName= + */ + + KSimpleConfig file(url.path(), true); + + if (file.hasGroup("ICQ User")) + file.setGroup("ICQ User"); + else if (file.hasGroup("ICQ Message User")) + file.setGroup("ICQ Message User"); + else + return; + + ICQProtocol *proto = ICQProtocol::protocol(); + + QString uin = file.readEntry("UIN"); + if (uin.isEmpty()) + return; + + QString nick = file.readEntry("NickName"); + QString first = file.readEntry("FirstName"); + QString last = file.readEntry("LastName"); + QString email = file.readEntry("Email"); + + Kopete::Account *account = 0; + QDict<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts(proto); + // do not show chooser if we only have one account to "choose" from + 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(14153) << k_funcinfo << "Cancelled" << endl; + return; + } + } + + if (!account->isConnected()) + { + kdDebug(14153) << k_funcinfo << "Can't add contact, we are offline!" << endl; + KMessageBox::sorry( Kopete::UI::Global::mainWidget(), i18n("You must be online to add a contact."), i18n("ICQ") ); + return; + } + + QString nickuin = nick.isEmpty() ? + i18n("'%1'").arg(uin) : + i18n("'%1' (%2)").arg(nick, uin); + + if (KMessageBox::questionYesNo(Kopete::UI::Global::mainWidget(), + i18n("Do you want to add %1 to your contact list?").arg(nickuin), QString::null, i18n("Add"), i18n("Do Not Add")) + != KMessageBox::Yes) + { + kdDebug(14153) << k_funcinfo << "Cancelled" << endl; + return; + } + + kdDebug(14153) << k_funcinfo << + "Adding Contact; uin = " << uin << ", nick = '" << nick << + "', firstname = '" << first << "', lastname = '" << last <<"'" << endl; + if (account->addContact(uin, nick, 0L, Kopete::Account::Temporary)) + { + Kopete::Contact *contact = account->contacts()[uin]; + if (!first.isEmpty()) + contact->setProperty(Kopete::Global::Properties::self()->firstName(), first); + if (!last.isEmpty()) + contact->setProperty(Kopete::Global::Properties::self()->lastName(), last); + if (!email.isEmpty()) + contact->setProperty(Kopete::Global::Properties::self()->emailAddress(), email); + } +} + +//END class ICQProtocolHandler + +//BEGIN class ICQProtocol + +ICQProtocol* ICQProtocol::protocolStatic_ = 0L; + +ICQProtocol::ICQProtocol(QObject *parent, const char *name, const QStringList&) +: Kopete::Protocol( ICQProtocolFactory::instance(), parent, name ), + firstName(Kopete::Global::Properties::self()->firstName()), + lastName(Kopete::Global::Properties::self()->lastName()), + awayMessage(Kopete::Global::Properties::self()->awayMessage()), + emailAddress(Kopete::Global::Properties::self()->emailAddress()), + ipAddress("ipAddress", i18n("IP Address") ), + clientFeatures("clientFeatures", i18n("Client Features"), 0, false), + buddyIconHash("iconHash", i18n("Buddy Icon MD5 Hash"), QString::null, true, false, true), + contactEncoding( "contactEncoding", i18n( "Contact Encoding" ), QString::null, true, false, true ) + +{ + if (protocolStatic_) + kdWarning(14153) << k_funcinfo << "ICQ plugin already initialized" << endl; + else + protocolStatic_ = this; + + // must be done after protocolStatic_ is set... + statusManager_ = new ICQ::OnlineStatusManager; + + addAddressBookField("messaging/icq", Kopete::Plugin::MakeIndexField); + + initGenders(); + initLang(); + initCountries(); + initEncodings(); + initMaritals(); + initInterests(); +} + +ICQProtocol::~ICQProtocol() +{ + delete statusManager_; + protocolStatic_ =0L; +} + +void ICQProtocol::initGenders() +{ + mGenders.insert(0, ""); // unspecified + mGenders.insert(1, i18n("Female")); + mGenders.insert(2, i18n("Male")); +} + +void ICQProtocol::initCountries() +{ + mCountries.insert(0, ""); // unspecified + KLocale *kl = KGlobal::locale(); //KLocale(QString::fromLatin1("kopete")); + + mCountries.insert(93, kl->twoAlphaToCountryName("af")); + mCountries.insert(355, kl->twoAlphaToCountryName("al")); + mCountries.insert(213, kl->twoAlphaToCountryName("dz")); + mCountries.insert(684, kl->twoAlphaToCountryName("as")); + mCountries.insert(376, kl->twoAlphaToCountryName("ad")); + mCountries.insert(244, kl->twoAlphaToCountryName("ao")); + mCountries.insert(101, kl->twoAlphaToCountryName("ai")); + mCountries.insert(102, kl->twoAlphaToCountryName("ag")); + mCountries.insert(54, kl->twoAlphaToCountryName("ar")); + mCountries.insert(374, kl->twoAlphaToCountryName("am")); + mCountries.insert(297, kl->twoAlphaToCountryName("aw")); + mCountries.insert(247, i18n("Ascension Island")); + mCountries.insert(61, kl->twoAlphaToCountryName("au")); + mCountries.insert(6721, i18n("Australian Antarctic Territory")); + mCountries.insert(43, kl->twoAlphaToCountryName("at")); + mCountries.insert(994, kl->twoAlphaToCountryName("az")); + mCountries.insert(103, kl->twoAlphaToCountryName("bs")); + mCountries.insert(973, kl->twoAlphaToCountryName("bh")); + mCountries.insert(880, kl->twoAlphaToCountryName("bd")); + mCountries.insert(104, kl->twoAlphaToCountryName("bb")); + mCountries.insert(120, i18n("Barbuda")); + mCountries.insert(375, kl->twoAlphaToCountryName("by")); + mCountries.insert(32, kl->twoAlphaToCountryName("be")); + mCountries.insert(501, kl->twoAlphaToCountryName("bz")); + mCountries.insert(229, kl->twoAlphaToCountryName("bj")); + mCountries.insert(105, kl->twoAlphaToCountryName("bm")); + mCountries.insert(975, kl->twoAlphaToCountryName("bt")); + mCountries.insert(591, kl->twoAlphaToCountryName("bo")); + mCountries.insert(387, kl->twoAlphaToCountryName("ba")); + mCountries.insert(267, kl->twoAlphaToCountryName("bw")); + mCountries.insert(55, kl->twoAlphaToCountryName("br")); + mCountries.insert(106, i18n("British Virgin Islands")); + mCountries.insert(673, kl->twoAlphaToCountryName("bn")); + mCountries.insert(359, kl->twoAlphaToCountryName("bg")); + mCountries.insert(226, kl->twoAlphaToCountryName("bf")); + mCountries.insert(257, kl->twoAlphaToCountryName("bi")); + mCountries.insert(855, kl->twoAlphaToCountryName("kh")); + mCountries.insert(237, kl->twoAlphaToCountryName("cm")); + mCountries.insert(107, kl->twoAlphaToCountryName("ca")); + mCountries.insert(238, kl->twoAlphaToCountryName("cv")); + mCountries.insert(108, kl->twoAlphaToCountryName("ky")); + mCountries.insert(236, kl->twoAlphaToCountryName("cf")); + mCountries.insert(235, kl->twoAlphaToCountryName("td")); + mCountries.insert(56, kl->twoAlphaToCountryName("cl")); + mCountries.insert(86, kl->twoAlphaToCountryName("cn")); + mCountries.insert(672, kl->twoAlphaToCountryName("cx")); + mCountries.insert(6101, kl->twoAlphaToCountryName("c")); + mCountries.insert(57, kl->twoAlphaToCountryName("co")); + mCountries.insert(2691, kl->twoAlphaToCountryName("km")); + mCountries.insert(242, kl->twoAlphaToCountryName("cg")); + mCountries.insert(682, kl->twoAlphaToCountryName("ck")); + mCountries.insert(506, kl->twoAlphaToCountryName("cr")); + mCountries.insert(385, kl->twoAlphaToCountryName("hr")); + mCountries.insert(53, kl->twoAlphaToCountryName("cu")); + mCountries.insert(357, kl->twoAlphaToCountryName("cy")); + mCountries.insert(42, kl->twoAlphaToCountryName("cz")); + mCountries.insert(45, kl->twoAlphaToCountryName("dk")); + mCountries.insert(246, i18n("Diego Garcia")); + mCountries.insert(253, kl->twoAlphaToCountryName("dj")); + mCountries.insert(109, kl->twoAlphaToCountryName("dm")); + mCountries.insert(110, kl->twoAlphaToCountryName("do")); + mCountries.insert(593, kl->twoAlphaToCountryName("ec")); + mCountries.insert(20, kl->twoAlphaToCountryName("eg")); + mCountries.insert(503, kl->twoAlphaToCountryName("sv")); + mCountries.insert(240, kl->twoAlphaToCountryName("gq")); + mCountries.insert(291, kl->twoAlphaToCountryName("er")); + mCountries.insert(372, kl->twoAlphaToCountryName("ee")); + mCountries.insert(251, kl->twoAlphaToCountryName("et")); + mCountries.insert(298, kl->twoAlphaToCountryName("fo")); + mCountries.insert(500, kl->twoAlphaToCountryName("fk")); + mCountries.insert(679, kl->twoAlphaToCountryName("fj")); + mCountries.insert(358, kl->twoAlphaToCountryName("fi")); + mCountries.insert(33, kl->twoAlphaToCountryName("fr")); + mCountries.insert(5901, i18n("French Antilles")); + mCountries.insert(594, kl->twoAlphaToCountryName("gf")); + mCountries.insert(689, kl->twoAlphaToCountryName("pf")); + mCountries.insert(241, kl->twoAlphaToCountryName("ga")); + mCountries.insert(220, kl->twoAlphaToCountryName("gm")); + mCountries.insert(995, kl->twoAlphaToCountryName("ge")); + mCountries.insert(49, kl->twoAlphaToCountryName("de")); + mCountries.insert(233, kl->twoAlphaToCountryName("gh")); + mCountries.insert(350, kl->twoAlphaToCountryName("gi")); + mCountries.insert(30, kl->twoAlphaToCountryName("gr")); + mCountries.insert(299, kl->twoAlphaToCountryName("gl")); + mCountries.insert(111, kl->twoAlphaToCountryName("gd")); + mCountries.insert(590, kl->twoAlphaToCountryName("gp")); + mCountries.insert(671, kl->twoAlphaToCountryName("gu")); + mCountries.insert(5399, i18n("Guantanamo Bay")); + mCountries.insert(502, kl->twoAlphaToCountryName("gt")); + mCountries.insert(224, kl->twoAlphaToCountryName("gn")); + mCountries.insert(245, kl->twoAlphaToCountryName("gw")); + mCountries.insert(592, kl->twoAlphaToCountryName("gy")); + mCountries.insert(509, kl->twoAlphaToCountryName("ht")); + mCountries.insert(504, kl->twoAlphaToCountryName("hn")); + mCountries.insert(852, kl->twoAlphaToCountryName("hk")); + mCountries.insert(36, kl->twoAlphaToCountryName("hu")); + mCountries.insert(871, i18n("INMARSAT (Atlantic-East)")); + mCountries.insert(874, i18n("INMARSAT (Atlantic-West)")); + mCountries.insert(873, i18n("INMARSAT (Indian)")); + mCountries.insert(872, i18n("INMARSAT (Pacific)")); + mCountries.insert(870, i18n("INMARSAT")); + mCountries.insert(354, kl->twoAlphaToCountryName("is")); + mCountries.insert(91, kl->twoAlphaToCountryName("in")); + mCountries.insert(62, kl->twoAlphaToCountryName("id")); + mCountries.insert(800, i18n("International Freephone Service")); + mCountries.insert(98, kl->twoAlphaToCountryName("ir")); + mCountries.insert(964, kl->twoAlphaToCountryName("iq")); + mCountries.insert(353, kl->twoAlphaToCountryName("ie")); + mCountries.insert(972, kl->twoAlphaToCountryName("il")); + mCountries.insert(39, kl->twoAlphaToCountryName("it")); + mCountries.insert(225, i18n("Ivory Coast")); + mCountries.insert(112, kl->twoAlphaToCountryName("jm")); + mCountries.insert(81, kl->twoAlphaToCountryName("jp")); + mCountries.insert(962, kl->twoAlphaToCountryName("jo")); + mCountries.insert(705, kl->twoAlphaToCountryName("kz")); + mCountries.insert(254, kl->twoAlphaToCountryName("ke")); + mCountries.insert(686, kl->twoAlphaToCountryName("ki")); + mCountries.insert(850, kl->twoAlphaToCountryName("kp")); + mCountries.insert(82, kl->twoAlphaToCountryName("kr")); + mCountries.insert(965, kl->twoAlphaToCountryName("kw")); + mCountries.insert(706, kl->twoAlphaToCountryName("kg")); + mCountries.insert(856, kl->twoAlphaToCountryName("la")); + mCountries.insert(371, kl->twoAlphaToCountryName("lv")); + mCountries.insert(961, kl->twoAlphaToCountryName("kb")); + mCountries.insert(266, kl->twoAlphaToCountryName("ls")); + mCountries.insert(231, kl->twoAlphaToCountryName("lr")); + mCountries.insert(218, kl->twoAlphaToCountryName("ly")); + mCountries.insert(4101, kl->twoAlphaToCountryName("li")); + mCountries.insert(370, kl->twoAlphaToCountryName("lt")); + mCountries.insert(352, kl->twoAlphaToCountryName("lu")); + mCountries.insert(853, kl->twoAlphaToCountryName("mo")); + mCountries.insert(261, kl->twoAlphaToCountryName("mg")); + mCountries.insert(265, kl->twoAlphaToCountryName("mw")); + mCountries.insert(60, kl->twoAlphaToCountryName("my")); + mCountries.insert(960, kl->twoAlphaToCountryName("mv")); + mCountries.insert(223, kl->twoAlphaToCountryName("ml")); + mCountries.insert(356, kl->twoAlphaToCountryName("mt")); + mCountries.insert(692, kl->twoAlphaToCountryName("mh")); + mCountries.insert(596, kl->twoAlphaToCountryName("mq")); + mCountries.insert(222, kl->twoAlphaToCountryName("mr")); + mCountries.insert(230, kl->twoAlphaToCountryName("mu")); + mCountries.insert(269, kl->twoAlphaToCountryName("yt")); + mCountries.insert(52, kl->twoAlphaToCountryName("mx")); + mCountries.insert(691, kl->twoAlphaToCountryName("fm")); + mCountries.insert(373, kl->twoAlphaToCountryName("md")); + mCountries.insert(377, kl->twoAlphaToCountryName("mc")); + mCountries.insert(976, kl->twoAlphaToCountryName("mn")); + mCountries.insert(113, kl->twoAlphaToCountryName("ms")); + mCountries.insert(212, kl->twoAlphaToCountryName("ma")); + mCountries.insert(258, kl->twoAlphaToCountryName("mz")); + mCountries.insert(95, kl->twoAlphaToCountryName("mm")); + mCountries.insert(264, kl->twoAlphaToCountryName("na")); + mCountries.insert(674, kl->twoAlphaToCountryName("nr")); + mCountries.insert(977, kl->twoAlphaToCountryName("np")); + mCountries.insert(599, kl->twoAlphaToCountryName("an")); + mCountries.insert(31, kl->twoAlphaToCountryName("nl")); + mCountries.insert(114, i18n("Nevis")); + mCountries.insert(687, kl->twoAlphaToCountryName("nc")); + mCountries.insert(64, kl->twoAlphaToCountryName("nz")); + mCountries.insert(505, kl->twoAlphaToCountryName("ni")); + mCountries.insert(227, kl->twoAlphaToCountryName("ne")); + mCountries.insert(234, kl->twoAlphaToCountryName("ng")); + mCountries.insert(683, kl->twoAlphaToCountryName("nu")); + mCountries.insert(6722, kl->twoAlphaToCountryName("nf")); + mCountries.insert(47, kl->twoAlphaToCountryName("no")); + mCountries.insert(968, kl->twoAlphaToCountryName("om")); + mCountries.insert(92, kl->twoAlphaToCountryName("pk")); + mCountries.insert(680, kl->twoAlphaToCountryName("pw")); + mCountries.insert(507, kl->twoAlphaToCountryName("pa")); + mCountries.insert(675, kl->twoAlphaToCountryName("pg")); + mCountries.insert(595, kl->twoAlphaToCountryName("py")); + mCountries.insert(51, kl->twoAlphaToCountryName("pe")); + mCountries.insert(63, kl->twoAlphaToCountryName("ph")); + mCountries.insert(48, kl->twoAlphaToCountryName("pl")); + mCountries.insert(351, kl->twoAlphaToCountryName("pt")); + mCountries.insert(121, kl->twoAlphaToCountryName("pr")); + mCountries.insert(974, kl->twoAlphaToCountryName("qa")); + mCountries.insert(389, kl->twoAlphaToCountryName("mk")); + mCountries.insert(262, i18n("Reunion Island")); + mCountries.insert(40, kl->twoAlphaToCountryName("ro")); + mCountries.insert(6701, i18n("Rota Island")); + mCountries.insert(7, kl->twoAlphaToCountryName("ru")); + mCountries.insert(250, kl->twoAlphaToCountryName("rw")); + mCountries.insert(122, kl->twoAlphaToCountryName("lc")); + mCountries.insert(670, i18n("Ivory Coast")); + mCountries.insert(378, kl->twoAlphaToCountryName("sm")); + mCountries.insert(239, kl->twoAlphaToCountryName("st")); + mCountries.insert(966, kl->twoAlphaToCountryName("sa")); + mCountries.insert(221, kl->twoAlphaToCountryName("sn")); + mCountries.insert(248, kl->twoAlphaToCountryName("sc")); + mCountries.insert(232, kl->twoAlphaToCountryName("sl")); + mCountries.insert(65, kl->twoAlphaToCountryName("sg")); + mCountries.insert(4201, kl->twoAlphaToCountryName("sk")); + mCountries.insert(386, kl->twoAlphaToCountryName("si")); + mCountries.insert(677, kl->twoAlphaToCountryName("sb")); + mCountries.insert(252, kl->twoAlphaToCountryName("so")); + mCountries.insert(27, kl->twoAlphaToCountryName("za")); + mCountries.insert(34, kl->twoAlphaToCountryName("es")); + mCountries.insert(94, kl->twoAlphaToCountryName("lk")); + mCountries.insert(290, kl->twoAlphaToCountryName("sh")); + mCountries.insert(115, kl->twoAlphaToCountryName("kn")); + mCountries.insert(508, kl->twoAlphaToCountryName("pm")); + mCountries.insert(116, kl->twoAlphaToCountryName("vc")); + mCountries.insert(249, kl->twoAlphaToCountryName("sd")); + mCountries.insert(597, kl->twoAlphaToCountryName("sr")); + mCountries.insert(268, kl->twoAlphaToCountryName("sz")); + mCountries.insert(46, kl->twoAlphaToCountryName("se")); + mCountries.insert(41, kl->twoAlphaToCountryName("ch")); + mCountries.insert(963, kl->twoAlphaToCountryName("sy")); + mCountries.insert(886, kl->twoAlphaToCountryName("tw")); + mCountries.insert(708, kl->twoAlphaToCountryName("tj")); + mCountries.insert(255, kl->twoAlphaToCountryName("tz")); + mCountries.insert(66, kl->twoAlphaToCountryName("th")); + mCountries.insert(6702, i18n("Tinian Island")); + mCountries.insert(228, kl->twoAlphaToCountryName("tg")); // Togo + mCountries.insert(690, kl->twoAlphaToCountryName("tk")); // Tokelau + mCountries.insert(676, kl->twoAlphaToCountryName("to")); // Tonga + mCountries.insert(117, kl->twoAlphaToCountryName("tt")); // Trinidad and Tobago + mCountries.insert(216, kl->twoAlphaToCountryName("tn")); // Tunisia + mCountries.insert(90, kl->twoAlphaToCountryName("tr")); + mCountries.insert(709, kl->twoAlphaToCountryName("tm")); + mCountries.insert(118, kl->twoAlphaToCountryName("tc")); // Turks and Caicos Island + mCountries.insert(688, kl->twoAlphaToCountryName("tv")); // Tuvalu + mCountries.insert(1, kl->twoAlphaToCountryName("us")); // United States of America + mCountries.insert(256, kl->twoAlphaToCountryName("ug")); // Uganda + mCountries.insert(380, kl->twoAlphaToCountryName("ua")); // Ukraine + mCountries.insert(971, kl->twoAlphaToCountryName("ae")); // United Arab Emirates + mCountries.insert(44, kl->twoAlphaToCountryName("gb")); // United Kingdom + mCountries.insert(123, kl->twoAlphaToCountryName("vi")); // United States Virgin Islands + mCountries.insert(598, kl->twoAlphaToCountryName("uy")); // Uruguay + mCountries.insert(711, kl->twoAlphaToCountryName("uz")); // Uzbekistan + mCountries.insert(678, kl->twoAlphaToCountryName("vu")); // Vanuatu + mCountries.insert(379, kl->twoAlphaToCountryName("va")); // Vatican City + mCountries.insert(58, kl->twoAlphaToCountryName("ve")); // Venezuela + mCountries.insert(84, kl->twoAlphaToCountryName("vn")); // Vietnam + mCountries.insert(681, kl->twoAlphaToCountryName("wf")); // Wallis and Futuna Islands + mCountries.insert(685, kl->twoAlphaToCountryName("eh")); + mCountries.insert(967, kl->twoAlphaToCountryName("ye")); + mCountries.insert(381, kl->twoAlphaToCountryName("yu")); + mCountries.insert(243, kl->twoAlphaToCountryName("zr")); + mCountries.insert(260, kl->twoAlphaToCountryName("zm")); + mCountries.insert(263, kl->twoAlphaToCountryName("zw")); +} + +void ICQProtocol::initLang() +{ + + KLocale *kl = KGlobal::locale(); //KLocale(QString::fromLatin1("kopete")); + + mLanguages.insert(0 , ""); + mLanguages.insert(1 , kl->twoAlphaToLanguageName("ar") /*i18n("Arabic")*/); + mLanguages.insert(2 , i18n("Bhojpuri")); + mLanguages.insert(3 , kl->twoAlphaToLanguageName("bg") /*i18n("Bulgarian")*/); + mLanguages.insert(4 , kl->twoAlphaToLanguageName("my") /*i18n("Burmese")*/); + mLanguages.insert(5 , i18n("Cantonese")); + mLanguages.insert(6 , kl->twoAlphaToLanguageName("ca") /*i18n("Catalan")*/); + mLanguages.insert(7 , kl->twoAlphaToLanguageName("zh") /*i18n("Chinese")*/); + mLanguages.insert(8 , kl->twoAlphaToLanguageName("hr") /*i18n("Croatian")*/); + mLanguages.insert(9 , kl->twoAlphaToLanguageName("cs") /*i18n("Czech")*/); + mLanguages.insert(10, kl->twoAlphaToLanguageName("da") /*i18n("Danish")*/); + mLanguages.insert(11, kl->twoAlphaToLanguageName("nl") /*i18n("Dutch")*/); + mLanguages.insert(12, kl->twoAlphaToLanguageName("en") /*i18n("English")*/); + mLanguages.insert(13, kl->twoAlphaToLanguageName("eo") /*i18n("Esperanto")*/); + mLanguages.insert(14, kl->twoAlphaToLanguageName("et") /*i18n("Estonian")*/); + mLanguages.insert(15, i18n("Farsi")); + mLanguages.insert(16, kl->twoAlphaToLanguageName("fi") /*i18n("Finnish")*/); + mLanguages.insert(17, kl->twoAlphaToLanguageName("fr") /*i18n("French")*/); + mLanguages.insert(18, kl->twoAlphaToLanguageName("gd") /*i18n("Gaelic")*/); + mLanguages.insert(19, kl->twoAlphaToLanguageName("de") /*i18n("German")*/); + mLanguages.insert(20, kl->twoAlphaToLanguageName("el") /*i18n("Greek")*/); + mLanguages.insert(21, kl->twoAlphaToLanguageName("he") /*i18n("Hebrew")*/); + mLanguages.insert(22, kl->twoAlphaToLanguageName("hi") /*i18n("Hindi")*/); + mLanguages.insert(23, kl->twoAlphaToLanguageName("hu") /*i18n("Hungarian")*/); + mLanguages.insert(24, kl->twoAlphaToLanguageName("is") /*i18n("Icelandic")*/); + mLanguages.insert(25, kl->twoAlphaToLanguageName("id") /*i18n("Indonesian")*/); + mLanguages.insert(26, kl->twoAlphaToLanguageName("it") /*i18n("Italian")*/); + mLanguages.insert(27, kl->twoAlphaToLanguageName("ja") /*i18n("Japanese")*/); + mLanguages.insert(28, kl->twoAlphaToLanguageName("km") /*i18n("Khmer")*/); + mLanguages.insert(29, kl->twoAlphaToLanguageName("ko") /*i18n("Korean")*/); + mLanguages.insert(30, kl->twoAlphaToLanguageName("lo") /*i18n("Lao")*/); + mLanguages.insert(31, kl->twoAlphaToLanguageName("lv") /*i18n("Latvian")*/); + mLanguages.insert(32, kl->twoAlphaToLanguageName("lt") /*i18n("Lithuanian")*/); + mLanguages.insert(33, kl->twoAlphaToLanguageName("ms") /*i18n("Malay")*/); + mLanguages.insert(34, kl->twoAlphaToLanguageName("no") /*i18n("Norwegian")*/); + mLanguages.insert(35, kl->twoAlphaToLanguageName("pl") /*i18n("Polish")*/); + mLanguages.insert(36, kl->twoAlphaToLanguageName("pt") /*i18n("Portuguese")*/); + mLanguages.insert(37, kl->twoAlphaToLanguageName("ro") /*i18n("Romanian")*/); + mLanguages.insert(38, kl->twoAlphaToLanguageName("ru") /*i18n("Russian")*/); + mLanguages.insert(39, kl->twoAlphaToLanguageName("sr") /*i18n("Serbian")*/); + mLanguages.insert(40, kl->twoAlphaToLanguageName("sk") /*i18n("Slovak")*/); + mLanguages.insert(41, kl->twoAlphaToLanguageName("sl") /*i18n("Slovenian")*/); + mLanguages.insert(42, kl->twoAlphaToLanguageName("so") /*i18n("Somali")*/); + mLanguages.insert(43, kl->twoAlphaToLanguageName("es") /*i18n("Spanish")*/); + mLanguages.insert(44, kl->twoAlphaToLanguageName("sw") /*i18n("Swahili")*/); + mLanguages.insert(45, kl->twoAlphaToLanguageName("sv") /*i18n("Swedish")*/); + mLanguages.insert(46, kl->twoAlphaToLanguageName("tl") /*i18n("Tagalog")*/); + mLanguages.insert(47, kl->twoAlphaToLanguageName("tt") /*i18n("Tatar")*/); + mLanguages.insert(48, kl->twoAlphaToLanguageName("th") /*i18n("Thai")*/); + mLanguages.insert(49, kl->twoAlphaToLanguageName("tr") /*i18n("Turkish")*/); + mLanguages.insert(50, kl->twoAlphaToLanguageName("uk") /*i18n("Ukrainian")*/); + mLanguages.insert(51, kl->twoAlphaToLanguageName("ur") /*i18n("Urdu")*/); + mLanguages.insert(52, kl->twoAlphaToLanguageName("vi") /*i18n("Vietnamese")*/); + mLanguages.insert(53, kl->twoAlphaToLanguageName("yi") /*i18n("Yiddish")*/); + mLanguages.insert(54, kl->twoAlphaToLanguageName("yo") /*i18n("Yoruba")*/); + mLanguages.insert(55, i18n("Taiwanese")); + mLanguages.insert(56, kl->twoAlphaToLanguageName("af") /*i18n("Afrikaans")*/); + mLanguages.insert(57, kl->twoAlphaToLanguageName("fa") /*i18n("Persian")*/); + mLanguages.insert(58, kl->twoAlphaToLanguageName("sq") /*i18n("Albanian")*/); + mLanguages.insert(59, kl->twoAlphaToLanguageName("hy") /*i18n("Armenian")*/); +} + +void ICQProtocol::initEncodings() +{ + mEncodings.insert(2026, i18n("Big5")); + mEncodings.insert(2101, i18n("Big5-HKSCS")); + mEncodings.insert(18, i18n("euc-JP Japanese")); + mEncodings.insert(38, i18n("euc-KR Korean")); + mEncodings.insert(57, i18n("GB-2312 Chinese")); + mEncodings.insert(113, i18n("GBK Chinese")); + mEncodings.insert(114, i18n("GB18030 Chinese")); + + mEncodings.insert(16, i18n("JIS Japanese")); + mEncodings.insert(17, i18n("Shift-JIS Japanese")); + + mEncodings.insert(2084, i18n("KOI8-R Russian")); + mEncodings.insert(2088, i18n("KOI8-U Ukrainian")); + + mEncodings.insert(4, i18n("ISO-8859-1 Western")); + mEncodings.insert(5, i18n("ISO-8859-2 Central European")); + mEncodings.insert(6, i18n("ISO-8859-3 Central European")); + mEncodings.insert(7, i18n("ISO-8859-4 Baltic")); + mEncodings.insert(8, i18n("ISO-8859-5 Cyrillic")); + mEncodings.insert(9, i18n("ISO-8859-6 Arabic")); + mEncodings.insert(10, i18n("ISO-8859-7 Greek")); + mEncodings.insert(11, i18n("ISO-8859-8 Hebrew, visually ordered")); + mEncodings.insert(85, i18n("ISO-8859-8-I Hebrew, logically ordered")); + mEncodings.insert(12, i18n("ISO-8859-9 Turkish")); + mEncodings.insert(13, i18n("ISO-8859-10")); + mEncodings.insert(109, i18n("ISO-8859-13")); + mEncodings.insert(110, i18n("ISO-8859-14")); + mEncodings.insert(111, i18n("ISO-8859-15 Western")); + + mEncodings.insert(2250, i18n("Windows-1250 Central European")); + mEncodings.insert(2251, i18n("Windows-1251 Cyrillic")); + mEncodings.insert(2252, i18n("Windows-1252 Western")); + mEncodings.insert(2253, i18n("Windows-1253 Greek")); + mEncodings.insert(2254, i18n("Windows-1254 Turkish")); + mEncodings.insert(2255, i18n("Windows-1255 Hebrew")); + mEncodings.insert(2256, i18n("Windows-1256 Arabic")); + mEncodings.insert(2257, i18n("Windows-1257 Baltic")); + mEncodings.insert(2258, i18n("Windows-1258 Viet Nam")); + + mEncodings.insert(2009, i18n("IBM 850")); + mEncodings.insert(2085, i18n("IBM 866")); + + mEncodings.insert(2259, i18n("TIS-620 Thai")); + + mEncodings.insert(106, i18n("UTF-8 Unicode")); + mEncodings.insert(1015, i18n("UTF-16 Unicode")); + +/* +Missing ones (copied from qtextcodec doc): +TSCII -- Tamil +utf8 -- Unicode, 8-bit +utf16 -- Unicode +CP874 +Apple Roman +*/ +} +void ICQProtocol::initMaritals() +{ + mMarital.insert(0 , ""); + mMarital.insert(10 , i18n("Single")); + mMarital.insert(11 , i18n("Long term relationship")); + mMarital.insert(12 , i18n("Engaged")); + mMarital.insert(20 , i18n("Married")); + mMarital.insert(30 , i18n("Divorced")); + mMarital.insert(31 , i18n("Separated")); + mMarital.insert(40 , i18n("Widowed")); + +} + +void ICQProtocol::initInterests() +{ + mInterests.insert(0 , ""); + mInterests.insert(100, i18n("Art")); + mInterests.insert(101, i18n("Cars")); + mInterests.insert(102, i18n("Celebrities")); + mInterests.insert(103, i18n("Collections")); + mInterests.insert(104, i18n("Computers")); + mInterests.insert(105, i18n("Culture")); + mInterests.insert(106, i18n("Fitness")); + mInterests.insert(107, i18n("Games")); + mInterests.insert(108, i18n("Hobbies")); + mInterests.insert(109, i18n("ICQ - Help")); + mInterests.insert(110, i18n("Internet")); + mInterests.insert(111, i18n("Lifestyle")); + mInterests.insert(112, i18n("Movies")); + mInterests.insert(113, i18n("Music")); + mInterests.insert(114, i18n("Outdoors")); + mInterests.insert(115, i18n("Parenting")); + mInterests.insert(116, i18n("Pets and animals")); + mInterests.insert(117, i18n("Religion")); + mInterests.insert(118, i18n("Science")); + mInterests.insert(119, i18n("Skills")); + mInterests.insert(120, i18n("Sports")); + mInterests.insert(121, i18n("Web design")); + mInterests.insert(122, i18n("Ecology")); + mInterests.insert(123, i18n("News and media")); + mInterests.insert(124, i18n("Government")); + mInterests.insert(125, i18n("Business")); + mInterests.insert(126, i18n("Mystics")); + mInterests.insert(127, i18n("Travel")); + mInterests.insert(128, i18n("Astronomy")); + mInterests.insert(129, i18n("Space")); + mInterests.insert(130, i18n("Clothing")); + mInterests.insert(131, i18n("Parties")); + mInterests.insert(132, i18n("Women")); + mInterests.insert(133, i18n("Social science")); + mInterests.insert(134, i18n("60's")); + mInterests.insert(135, i18n("70's")); + mInterests.insert(136, i18n("40's")); + mInterests.insert(137, i18n("50's")); + mInterests.insert(138, i18n("Finance and corporate")); + mInterests.insert(139, i18n("Entertainment")); + mInterests.insert(140, i18n("Consumer electronics")); + mInterests.insert(141, i18n("Retail stores")); + mInterests.insert(142, i18n("Health and beauty")); + mInterests.insert(143, i18n("Media")); + mInterests.insert(144, i18n("Household products")); + mInterests.insert(145, i18n("Mail order catalog")); + mInterests.insert(146, i18n("Business services")); + mInterests.insert(147, i18n("Audio and visual")); + mInterests.insert(148, i18n("Sporting and athletic")); + mInterests.insert(149, i18n("Publishing")); + mInterests.insert(150, i18n("Home automation")); + +} + +void ICQProtocol::fillComboFromTable(QComboBox *box, const QMap<int, QString> &map) +{ +// kdDebug(14153) << k_funcinfo << "Called." << endl; + + QStringList list = map.values(); + list.sort(); + box->insertStringList(list); +} + +void ICQProtocol::setComboFromTable(QComboBox *box, const QMap<int, QString> &map, int value) +{ +// kdDebug(14153) << k_funcinfo << "Called." << endl; + QMap<int, QString>::ConstIterator it; + it = map.find(value); + if (!(*it)) + return; + + for(int i=0; i<box->count(); i++) + { + if((*it) == box->text(i)) + { + box->setCurrentItem(i); + return; + } + } +} + +int ICQProtocol::getCodeForCombo(QComboBox *cmb, const QMap<int, QString> &map) +{ + const QString curText = cmb->currentText(); + + QMap<int, QString>::ConstIterator it; + for(it = map.begin(); it != map.end(); ++it) + { + if(it.data() == curText) + return it.key(); + } + return 0; // unspecified is always first 0 +} +#if 0 + +void ICQProtocol::fillTZCombo(QComboBox *combo) +{ + QTime time(12, 0); + QTime done(0, 0); + + while(time > done) + { + combo->insertItem("GMT-" + time.toString("h:mm")); + // subtract 30 minutes + time = time.addSecs(-30 * 60); + } + + time = QTime(0, 0); + done = QTime(12, 0); + + while(time <= done) + { + combo->insertItem("GMT+" + time.toString("h:mm")); + // add 30 minutes + time = time.addSecs(30 * 60); + } +} + +void ICQProtocol::setTZComboValue(QComboBox *combo, const char &tz) +{ + kdDebug(14153) << k_funcinfo << "tz=" << int(tz) << endl; + if ((tz < -24) || (tz > 24)) + combo->setCurrentItem(24); // GMT+0:00 as default + else + combo->setCurrentItem(24 + tz); +} + +char ICQProtocol::getTZComboValue(QComboBox *combo) +{ + char ret = combo->currentItem() - 24; +// kdDebug(14153) << k_funcinfo << "return value=" << int(ret) << endl; + return ret; +} + +#endif +ICQProtocol *ICQProtocol::protocol() +{ + return protocolStatic_; +} + +bool ICQProtocol::canSendOffline() const +{ + return true; +} + +Kopete::Contact *ICQProtocol::deserializeContact( Kopete::MetaContact *metaContact, + const QMap<QString, QString> &serializedData, + const QMap<QString, QString> &/*addressBookData*/ ) +{ + QString accountId = serializedData["accountId"]; + QDict<Kopete::Account> accounts = Kopete::AccountManager::self()->accounts(this); + ICQAccount *account = static_cast<ICQAccount*>(accounts[accountId]); + + if(!account) + { + kdWarning(14153) << k_funcinfo << + "WARNING: Account for contact does not exist, skipping " << accountId << endl; + return 0; + } + + QString contactId=serializedData["contactId"]; + uint ssiGid = 0, ssiBid = 0, ssiType = 0xFFFF; + QString ssiName; + bool ssiWaitingAuth = false; + if ( serializedData.contains( "ssi_name" ) ) + ssiName = serializedData["ssi_name"]; + + if ( serializedData.contains( "ssi_waitingAuth" ) ) + { + QString authStatus = serializedData["ssi_waitingAuth"]; + if ( authStatus == "true" ) + ssiWaitingAuth = true; + } + + if ( serializedData.contains( "ssi_gid" ) ) + ssiGid = serializedData["ssi_gid"].toUInt(); + if ( serializedData.contains( "ssi_bid" ) ) + ssiBid = serializedData["ssi_bid"].toUInt(); + if ( serializedData.contains( "ssi_type" ) ) + ssiType = serializedData["ssi_type"].toUInt(); + + Oscar::SSI item( ssiName, ssiGid, ssiBid, ssiType, QValueList<TLV>(), 0 ); + item.setWaitingAuth( ssiWaitingAuth ); + ICQContact *c = new ICQContact( account, contactId, metaContact, QString::null, item ); + return c; +} + +AddContactPage *ICQProtocol::createAddContactWidget(QWidget *parent, Kopete::Account *account) +{ + return new ICQAddContactPage( static_cast<ICQAccount*>( account ), parent); +} + +KopeteEditAccountWidget *ICQProtocol::createEditAccountWidget(Kopete::Account *account, QWidget *parent) +{ + return new ICQEditAccountWidget(this, account, parent); +} + +Kopete::Account *ICQProtocol::createNewAccount(const QString &accountId) +{ + return new ICQAccount(this, accountId); +} + +ICQ::OnlineStatusManager *ICQProtocol::statusManager() +{ + return statusManager_; +} + +//END class ICQProtocol + +#include "icqprotocol.moc" +// kate: indent-mode csands; +// vim: set noet ts=4 sts=4 sw=4: diff --git a/kopete/protocols/oscar/icq/icqprotocol.h b/kopete/protocols/oscar/icq/icqprotocol.h new file mode 100644 index 00000000..8e3c1be9 --- /dev/null +++ b/kopete/protocols/oscar/icq/icqprotocol.h @@ -0,0 +1,106 @@ +/* + oscarprotocol.h - Oscar Protocol Plugin + + Copyright (c) 2003 by Olivier Goffart <ogoffart @ kde.org> + 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 ICQPROTOCOL_H +#define ICQPROTOCOL_H + +#include "kopeteprotocol.h" +#include "kopetemimetypehandler.h" +#include "kopeteonlinestatus.h" + +class QComboBox; +/*class ICQUserInfoWidget; +class ICQContact;*/ + +namespace ICQ { class OnlineStatusManager; } + +class ICQProtocolHandler : public Kopete::MimeTypeHandler +{ +public: + ICQProtocolHandler(); + void handleURL(const QString &mimeType, const KURL & url) const; +}; + + +class ICQProtocol : public Kopete::Protocol +{ +Q_OBJECT + +public: + ICQProtocol(QObject *parent, const char *name, const QStringList &args); + virtual ~ICQProtocol(); + + /** + * Return the active instance of the protocol + */ + static ICQProtocol *protocol(); + + virtual bool canSendOffline() const; + + 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); + + ICQ::OnlineStatusManager *statusManager(); + + + const Kopete::ContactPropertyTmpl firstName; + const Kopete::ContactPropertyTmpl lastName; + const Kopete::ContactPropertyTmpl awayMessage; + const Kopete::ContactPropertyTmpl emailAddress; + const Kopete::ContactPropertyTmpl ipAddress; + const Kopete::ContactPropertyTmpl clientFeatures; + const Kopete::ContactPropertyTmpl buddyIconHash; + const Kopete::ContactPropertyTmpl contactEncoding; + + const QMap<int, QString> &genders() { return mGenders; } + const QMap<int, QString> &countries() { return mCountries; } + const QMap<int, QString> &languages() { return mLanguages; } + const QMap<int, QString> &encodings() { return mEncodings; } + const QMap<int, QString> &maritals() { return mMarital; } + const QMap<int, QString> &interests() { return mInterests; } + + void fillComboFromTable( QComboBox*, const QMap<int, QString>& ); + void setComboFromTable( QComboBox*, const QMap<int, QString>&, int ); + int getCodeForCombo( QComboBox*, const QMap<int, QString>& ); + /* void fillTZCombo(QComboBox *combo); + void setTZComboValue(QComboBox *combo, const char &tz); + char getTZComboValue(QComboBox *combo); */ + +private: + void initGenders(); + void initLang(); + void initCountries(); + void initEncodings(); + void initMaritals(); + void initInterests(); + +private: + static ICQProtocol* protocolStatic_; + ICQ::OnlineStatusManager* statusManager_; + QMap<int, QString> mGenders; + QMap<int, QString> mCountries; + QMap<int, QString> mLanguages; + QMap<int, QString> mEncodings; + QMap<int, QString> mMarital; + QMap<int, QString> mInterests; + ICQProtocolHandler protohandler; +}; +#endif +// vim: set noet ts=4 sts=4 sw=4: diff --git a/kopete/protocols/oscar/icq/icqreadaway.cpp b/kopete/protocols/oscar/icq/icqreadaway.cpp new file mode 100644 index 00000000..94cccafd --- /dev/null +++ b/kopete/protocols/oscar/icq/icqreadaway.cpp @@ -0,0 +1,106 @@ +/* + icqreadaway.cpp - ICQ Protocol Plugin + + Copyright (c) 2003 by Stefan Gehn <metz AT gehn.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. * + * * + ************************************************************************* +*/ + +#include "icqreadaway.h" + +#include "icqprotocol.h" +#include "icqaccount.h" +#include "icqcontact.h" + +#include <qvbox.h> + +#include <ktextbrowser.h> +#include <klocale.h> +#include <krun.h> + +#include <assert.h> + + +ICQReadAway::ICQReadAway(ICQContact *c, QWidget *parent, const char* name) + : KDialogBase(parent, name, false, QString::null, Close | User1, + Close, false, i18n("&Fetch Again")) +{ + assert(c); + + mAccount = static_cast<ICQAccount*>(c->account()); + mContact = c; + setCaption(i18n("'%2' Message for %1").arg(c->displayName()).arg(c->onlineStatus().description())); + + QVBox *mMainWidget = makeVBoxMainWidget(); + + awayMessageBrowser = new KTextBrowser(mMainWidget, "userInfoView"); + awayMessageBrowser->setTextFormat(AutoText); + awayMessageBrowser->setNotifyClick(true); + awayMessageBrowser->setText(mContact->awayMessage()); + + QObject::connect( + awayMessageBrowser, SIGNAL(urlClick(const QString&)), + this, SLOT(slotUrlClicked(const QString&))); + QObject::connect( + awayMessageBrowser, SIGNAL(mailClick(const QString&, const QString&)), + this, SLOT(slotMailClicked(const QString&, const QString&))); + + connect(this, SIGNAL(user1Clicked()), + this, SLOT(slotFetchAwayMessage())); + connect(this, SIGNAL(closeClicked()), + this, SLOT(slotCloseClicked())); + + connect(c, SIGNAL(awayMessageChanged()), + this, SLOT(slotAwayMessageChanged())); + + slotFetchAwayMessage(); +} + +void ICQReadAway::slotFetchAwayMessage() +{ + if(!mAccount->isConnected()) + return; + + awayMessageBrowser->setDisabled(true); + enableButton(User1,false); + + mAccount->engine()->requestAwayMessage(mContact); + + setCaption(i18n("Fetching '%2' Message for %1...").arg(mContact->displayName()).arg(mContact->onlineStatus().description())); +} // END slotFetchAwayMessage() + +void ICQReadAway::slotAwayMessageChanged() +{ + setCaption(i18n("'%2' Message for %1").arg(mContact->displayName()).arg(mContact->onlineStatus().description())); + awayMessageBrowser->setText(mContact->awayMessage()); + + awayMessageBrowser->setDisabled(false); + enableButton(User1,true); + +} // END slotAwayMessageChanged() + +void ICQReadAway::slotCloseClicked() +{ + emit closing(); +} + +void ICQReadAway::slotUrlClicked(const QString &url) +{ + new KRun(KURL(url)); +} + +void ICQReadAway::slotMailClicked(const QString&, const QString &address) +{ + new KRun(KURL(address)); +} + +#include "icqreadaway.moc" +// vim: set noet ts=4 sts=4 sw=4: diff --git a/kopete/protocols/oscar/icq/icqreadaway.h b/kopete/protocols/oscar/icq/icqreadaway.h new file mode 100644 index 00000000..7e62588e --- /dev/null +++ b/kopete/protocols/oscar/icq/icqreadaway.h @@ -0,0 +1,52 @@ +/* + icqreadaway.h - ICQ Protocol Plugin + + Copyright (c) 2003 by Stefan Gehn <metz AT gehn.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 ICQREADAWAY_H +#define ICQREADAWAY_H + +#include <kdebug.h> +#include <kdialogbase.h> + +class ICQAccount; +class ICQContact; +class KTextBrowser; +class QVBox; + +class ICQReadAway : public KDialogBase +{ + Q_OBJECT + + public: + ICQReadAway(ICQContact *, QWidget *parent = 0, const char* name = "ICQReadAway"); + + private slots: + void slotFetchAwayMessage(); + void slotAwayMessageChanged(); + void slotCloseClicked(); + void slotUrlClicked(const QString &url); + void slotMailClicked(const QString&, const QString &address); + + signals: + void closing(); + + private: + ICQAccount *mAccount; + ICQContact *mContact; + QVBox *mMainWidget; + KTextBrowser *awayMessageBrowser; +}; +#endif +// vim: set noet ts=4 sts=4 sw=4: diff --git a/kopete/protocols/oscar/icq/kopete_icq.desktop b/kopete/protocols/oscar/icq/kopete_icq.desktop new file mode 100644 index 00000000..c774afde --- /dev/null +++ b/kopete/protocols/oscar/icq/kopete_icq.desktop @@ -0,0 +1,78 @@ +[Desktop Entry] +Type=Service +X-Kopete-Version=1000900 +Icon=icq_protocol +ServiceTypes=Kopete/Protocol +X-KDE-Library=kopete_icq +X-Kopete-Messaging-Protocol=messaging/icq +X-KDE-PluginInfo-Author=Kopete Developers +X-KDE-PluginInfo-Email=kopete-devel@kde.org +X-KDE-PluginInfo-Name=kopete_icq +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=ICQ +Name[bn]=আই-সি-কিউ +Name[hi]=आईसीक्यू +Name[ne]=आईसीक्यू +Comment=Protocol to connect to ICQ +Comment[ar]=البرتوكول سيتصل بـ ICQ +Comment[be]=Пратакол ICQ +Comment[bg]=Протокол за връзка с ICQ +Comment[bn]=আই-সি-কিউতে সংযোগ করতে প্রোটোকল +Comment[br]=Komenad kevreañ ouzh AIM +Comment[bs]=ICQ protokol +Comment[ca]=Protocol per a connectar-se a ICQ +Comment[cs]=Protokol k připojení k ICQ +Comment[cy]=Protocol i gysylltu ag ICQ +Comment[da]=Protokol til at forbinde til ICQ +Comment[de]=Protokoll zur Verbindung mit ICQ +Comment[el]=Πρωτόκολλο για σύνδεση στο ICQ +Comment[es]=Protocolo de conexión de ICQ +Comment[et]=Protokoll ühendumiseks ICQ-ga +Comment[eu]=ICQ-ra konektatzeko protokoloa +Comment[fa]=قرارداد برای اتصال به ICQ +Comment[fi]=Yhteyskäytäntö ICQ-verkkoon kytkeytymiseen +Comment[fr]=Protocole pour se connecter sur ICQ +Comment[ga]=Prótacal chun ceangal le ICQ +Comment[gl]=Protocolo para se conectar á rede ICQ +Comment[he]=פרוטוקול התחברות ל- ICQ +Comment[hi]=आईसीक्यू से जुड़ने का प्रोटोकॉल +Comment[hr]=Protokol za povezivanje na ICQ +Comment[hu]=Protokoll az ICQ használatához +Comment[is]=Samskiptamáti til að tengjast ICQ +Comment[it]=Protocollo per connessione a ICQ +Comment[ja]=ICQ に接続するプロトコル +Comment[ka]=ICQ დაკავშირების ოქმი +Comment[kk]=ICQ-ге қосылу протоколы +Comment[km]=ពិធីការភ្ជាប់ទៅ ICQ +Comment[lt]=Protokolas prisijungimui prie ICQ +Comment[mk]=Протокол за поврзување на ICQ +Comment[nb]=Protokoll for å koble til ICQ +Comment[nds]=Protokoll för't Tokoppeln na ICQ +Comment[ne]=आईसीक्यू मा जडान गर्नुपर्ने प्रोटोकल +Comment[nl]=Protocol voor ICQ +Comment[nn]=Protokoll for å kopla til ICQ +Comment[pl]=Protokół połączenia z serwerem ICQ +Comment[pt]=Um protocolo para se ligar ao ICQ +Comment[pt_BR]=Protocolo de conexão ao ICQ +Comment[ro]=Protocol de conectare la ICQ +Comment[ru]=Протокол для подключения к ICQ +Comment[sk]=Protokol pre pripojenie k ICQ +Comment[sl]=Protokol za povezavo na ICQ +Comment[sr]=Протокол за повезивање на ICQ +Comment[sr@Latn]=Protokol za povezivanje na ICQ +Comment[sv]=Protokoll för att ansluta till ICQ +Comment[ta]=ICQ உடன் இணைக்க விதிமுறை +Comment[tg]=Қарордоди пайвастшавӣ ба ICQ +Comment[tr]=ICQ'a bağlantı iletişim kuralı +Comment[uk]=Протокол для з'єднання з ICQ +Comment[uz]=ICQ bilan aloqa oʻrnatish uchun protokol +Comment[uz@cyrillic]=ICQ билан алоқа ўрнатиш учун протокол +Comment[zh_CN]=连接到 ICQ 协议 +Comment[zh_HK]=用來連接至 ICQ 的通訊協定 +Comment[zh_TW]=連線到 ICQ 的協定 + diff --git a/kopete/protocols/oscar/icq/ui/Makefile.am b/kopete/protocols/oscar/icq/ui/Makefile.am new file mode 100644 index 00000000..24a726f2 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/Makefile.am @@ -0,0 +1,17 @@ +METASOURCES = AUTO +AM_CPPFLAGS = -I$(srcdir)/../ \ + -I$(srcdir)/../../ \ + -I$(srcdir)/ui/ \ + -I$(srcdir)/../../liboscar \ + -I$(srcdir)/../../../../ \ + $(KOPETE_INCLUDES) $(all_includes) + +noinst_LTLIBRARIES = libkopeteicqui.la + +libkopeteicqui_la_SOURCES = icqadd.ui icqeditaccountui.ui \ + icqeditaccountwidget.cpp icqgeneralinfo.ui icqotherinfowidget.ui icqworkinfowidget.ui icqinterestinfowidget.ui\ + icquserinfowidget.cpp icqauthreplyui.ui icqauthreplydialog.cpp icqaddcontactpage.cpp \ + icqsearchbase.ui icqsearchdialog.cpp icqsearchdialog.h + +libkopeteicqui_la_LIBADD = $(top_builddir)/kopete/libkopete/libkopete.la + diff --git a/kopete/protocols/oscar/icq/ui/icqadd.ui b/kopete/protocols/oscar/icq/ui/icqadd.ui new file mode 100644 index 00000000..ef793fbb --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqadd.ui @@ -0,0 +1,122 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>icqAddUI</class> +<widget class="QWidget"> + <property name="name"> + <cstring>icqAddUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>452</width> + <height>88</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>UIN #:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>uinEdit</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Alternatively, you can search the ICQ Whitepages :</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>47</width> + <height>26</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>searchButton</cstring> + </property> + <property name="text"> + <string>&Search</string> + </property> + <property name="iconSet"> + <iconset>image0</iconset> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<images> + <image name="image0"> + <data format="PNG" length="736">89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000002a749444154388d7d91cd4b945114c69f73ef3b33ea7ca838a6a32681501194d2975050b4c82f92dc042e5a550b5bf60744bb16b58a8268218144d026da64da228a0a2b52d1c8c8c48f2c54669c19df79df793fefbd2d662469860e1cb870cef3e339cf2500989b5b88e56cb78b0857f2b6d3e67b0e0b0503baf4e57bdbb21eb8b6fadedf7fda4599a2e999f9bdb66b5fb75db79b3164b8c6b3504af8426852885adff3272dc31cb14c313e38d827fe0568593d77225811b8d8d810475555a89e88e0791e0c330f2515cc7c9e6ccb822f8d6f00964a009e6b5f8ed554211a0d235c5501ce1874c30411414a89582cdc0625c3e964e64c3900b35de768301000e70c1ae7608c81738e80a6a1b2b202b16814cd4d8946ced550b90c98e33a158c113ccf47ceccc3cc5b080534282591d94c637d6d1d5bd92c2ccb3af2f0d1e8bd92135cd7370184018088c0350ec639a291086291083ccf432e6740d3822c994cc54a1c5886f5d1755d48a920a584520a4a291000251508844c3a83baf82e1051e90996e5dc5959fe0d21fd4270424208015184e9ba8e0f139350d050460fd6de7ec80e5786313b3307c33021a484effb104222994c61ecc52b380ec1cbfcc281fcd33dd3379af7ec04d0f497c5ae8977afc77b7acf6262620a7a2e0d2505a0181a1a1388d735209f5a41647504bb833fdcad8de4e896c9864edd5edb00006d9bd49468c4c0406f318b420b2121a440eaf324226d3588b79c0f6a536303d6fc2a9e5d4d5c1bb8bfb6cc769829f7cd2010aaf77741f7dbb095d1517bb81b0dadf57dd1907bf3f1a5448b5656b52d2ea6c62b6bf076ad09355f17cc939d84face736185d10bd9d9541dfbbb5c1010018c1158f14d44205600ad878ebdf9f47cfceec6a6e5b0d6e39a1139d8a5b1e2707878e47f660a15aaddfcb9a4df4a3f79d921abf7f52cda1d737f0030624881b39160420000000049454e44ae426082</data> + </image> +</images> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/kopete/protocols/oscar/icq/ui/icqaddcontactpage.cpp b/kopete/protocols/oscar/icq/ui/icqaddcontactpage.cpp new file mode 100644 index 00000000..b1ab2eb4 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqaddcontactpage.cpp @@ -0,0 +1,126 @@ + /* + icqaddcontactpage.cpp - ICQ Protocol Plugin + + Copyright (c) 2002 by Stefan Gehn <metz AT gehn.net> + 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 "icqaddcontactpage.h" + +#include <ctype.h> + +#include <qlayout.h> +#include <qpushbutton.h> +#include <qcombobox.h> +#include <qcheckbox.h> +#include <qlineedit.h> +#include <qtabwidget.h> +#include <qlabel.h> + +#include <kdebug.h> +#include <kiconloader.h> +#include <klistview.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <kmessagebox.h> + +#include "icqadd.h" +#include "icqaccount.h" +#include "icqprotocol.h" +#include "icqsearchdialog.h" + + +ICQAddContactPage::ICQAddContactPage(ICQAccount *owner, QWidget *parent, const char *name) + : AddContactPage(parent,name) +{ + kdDebug(14153) << k_funcinfo << "called" << endl; + mAccount = owner; + m_searchDialog = 0L; + + (new QVBoxLayout(this))->setAutoAdd(true); + addUI = new icqAddUI(this); + connect( addUI->searchButton, SIGNAL( clicked() ), this, SLOT( showSearchDialog() ) ); +} + +ICQAddContactPage::~ICQAddContactPage() +{ +} + +void ICQAddContactPage::setUINFromSearch( const QString& uin ) +{ + addUI->uinEdit->setText( uin ); +} + +void ICQAddContactPage::showEvent(QShowEvent *e) +{ +// slotSelectionChanged(); + AddContactPage::showEvent(e); +} + +bool ICQAddContactPage::apply(Kopete::Account* , Kopete::MetaContact *parentContact ) +{ + kdDebug(14153) << k_funcinfo << "called; adding contact..." << endl; + + QString contactId = addUI->uinEdit->text(); + kdDebug(14153) << k_funcinfo << "uin=" << contactId << endl; + return mAccount->addContact(contactId, parentContact, Kopete::Account::ChangeKABC ); + +} + +bool ICQAddContactPage::validateData() +{ + if(!mAccount->isConnected()) + { + // Account currently offline + addUI->searchButton->setEnabled( false ); + addUI->uinEdit->setEnabled( false ); + KMessageBox::sorry( this, i18n("You must be online to add a contact."), i18n("ICQ Plugin") ); + return false; + } + + Q_ULONG uin = addUI->uinEdit->text().toULong(); + if ( uin < 1000 ) + { + // Invalid (or missing) UIN + KMessageBox::sorry( this, i18n("You must enter a valid UIN."), i18n("ICQ Plugin") ); + return false; + } + else + { + // UIN is valid + return true; + } +} + +void ICQAddContactPage::showSearchDialog() +{ + if ( m_searchDialog ) + m_searchDialog->raise(); + else + { + m_searchDialog = new ICQSearchDialog( mAccount, this, "icqSearchDialog" ); + m_searchDialog->show(); + connect( m_searchDialog, SIGNAL( finished() ), this, SLOT( searchDialogDestroyed() ) ); + } +} + +void ICQAddContactPage::searchDialogDestroyed() +{ + QObject::disconnect( this, 0, m_searchDialog, 0 ); + m_searchDialog->delayedDestruct(); + m_searchDialog = NULL; +} + + +#include "icqaddcontactpage.moc" +// vim: set noet ts=4 sts=4 sw=4: +// kate: indent-mode csands; space-indent off; replace-tabs off; diff --git a/kopete/protocols/oscar/icq/ui/icqaddcontactpage.h b/kopete/protocols/oscar/icq/ui/icqaddcontactpage.h new file mode 100644 index 00000000..e9285b79 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqaddcontactpage.h @@ -0,0 +1,60 @@ + /* + icqaddcontactpage.h - ICQ Protocol Plugin + + Copyright (c) 2002 by Stefan Gehn <metz AT gehn.net> + Copyright (c) 2004-2005 by Matt Rogers <mattr@kde.org> + Kopete (c) 2002-2005 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 ICQADDCONTACTPAGE_H +#define ICQADDCONTACTPAGE_H + +#include <qwidget.h> +#include <addcontactpage.h> + +/** + *@author Matt Rogers + *@author Stefan Gehn + */ +class icqAddUI; +class ICQAccount; +class ICQSearchDialog; + +class ICQAddContactPage : public AddContactPage +{ +Q_OBJECT + +public: + ICQAddContactPage(ICQAccount *owner, QWidget *parent = 0, const char *name = 0); + ~ICQAddContactPage(); + + virtual bool validateData(); + virtual bool apply(Kopete::Account* , Kopete::MetaContact *parentContact); + + void setUINFromSearch( const QString& ); + +protected: + void showEvent(QShowEvent *e); + +private slots: + void showSearchDialog(); + void searchDialogDestroyed(); +private: + + ICQAccount *mAccount; + icqAddUI *addUI; + ICQSearchDialog* m_searchDialog; +}; + +#endif + +//kate: space-indent off; replace-tabs off; indent-mode csands; diff --git a/kopete/protocols/oscar/icq/ui/icqauthreplydialog.cpp b/kopete/protocols/oscar/icq/ui/icqauthreplydialog.cpp new file mode 100644 index 00000000..76b56fba --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqauthreplydialog.cpp @@ -0,0 +1,73 @@ +/* + Kopete Oscar Protocol + icqauthreplydialog.cpp - ICQ authorization reply dialog + + Copyright (c) 2004 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net> + + Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org> + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + ************************************************************************* +*/ +#include "icqauthreplydialog.h" +#include "icqauthreplyui.h" + +#include <klocale.h> + +#include <qlabel.h> +#include <qradiobutton.h> +#include <qlineedit.h> + +ICQAuthReplyDialog::ICQAuthReplyDialog( QWidget *parent, const char *name, bool wasRequested ) + : KDialogBase( parent, name, true, i18n( "Authorization Reply" ), KDialogBase::Ok | KDialogBase::Cancel ) +{ + m_ui = new ICQAuthReplyUI( this ); + setMainWidget( m_ui ); + m_wasRequested = wasRequested; + + if ( !m_wasRequested ) + { + m_ui->lblReqReason->hide(); + m_ui->lblRequestReason->hide(); + } + else + { + this->setWFlags( this->getWFlags() | Qt::WDestructiveClose ); + } +} + +ICQAuthReplyDialog::~ICQAuthReplyDialog() +{ +} + +void ICQAuthReplyDialog::setUser( const QString & user ) +{ + if ( m_wasRequested ) + m_ui->lblUserReq->setText( + i18n( "<b>%1</b> requested authorization to add you to his/her contact list." ).arg( user ) ); + else + m_ui->lblUserReq->setText( i18n( "Authorization reply to <b>%1</b>." ).arg( user ) ); +} + +void ICQAuthReplyDialog::setRequestReason( const QString & reason ) +{ + m_ui->lblRequestReason->setText( reason ); +} + +QString ICQAuthReplyDialog::reason() +{ + return m_ui->leReason->text(); +} + +bool ICQAuthReplyDialog::grantAuth() +{ + return m_ui->rbGrant->isChecked(); +} + +#include "icqauthreplydialog.moc" diff --git a/kopete/protocols/oscar/icq/ui/icqauthreplydialog.h b/kopete/protocols/oscar/icq/ui/icqauthreplydialog.h new file mode 100644 index 00000000..da27b241 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqauthreplydialog.h @@ -0,0 +1,45 @@ +/* + Kopete Oscar Protocol + icqauthreplydialog.h - ICQ authorization reply dialog + + Copyright (c) 2004 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net> + + Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org> + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + ************************************************************************* +*/ +#ifndef ICQAUTHREPLYDIALOG_H +#define ICQAUTHREPLYDIALOG_H + +#include <kdialogbase.h> + +class ICQAuthReplyUI; + +/** + * A dialog to ask user what to do when a contact requests authorization + * @author Gustavo Pichorim Boiko + */ +class ICQAuthReplyDialog : public KDialogBase +{ +Q_OBJECT +public: + ICQAuthReplyDialog(QWidget *parent = 0, const char *name = 0, bool wasRequested = true); + ~ICQAuthReplyDialog(); + + void setUser( const QString& user ); + void setRequestReason( const QString& reason ); + QString reason(); + bool grantAuth(); +private: + bool m_wasRequested; + ICQAuthReplyUI *m_ui; +}; + +#endif diff --git a/kopete/protocols/oscar/icq/ui/icqauthreplyui.ui b/kopete/protocols/oscar/icq/ui/icqauthreplyui.ui new file mode 100644 index 00000000..12607856 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqauthreplyui.ui @@ -0,0 +1,196 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICQAuthReplyUI</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICQAuthReplyUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>412</width> + <height>148</height> + </rect> + </property> + <property name="caption"> + <string>ICQ Authorization Reply</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>layout22</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>lblReason</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Reason:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>leReason</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>layout23</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer14</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>50</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>bgAction</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="title"> + <string></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton" row="0" column="0"> + <property name="name"> + <cstring>rbGrant</cstring> + </property> + <property name="text"> + <string>&Grant authorization</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton" row="0" column="1"> + <property name="name"> + <cstring>rbDecline</cstring> + </property> + <property name="text"> + <string>&Decline authorization</string> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>spacer12</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>220</width> + <height>21</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>lblUserReq</cstring> + </property> + <property name="text"> + <string>%1 requested authorization to add you to his/her contact list.</string> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout24</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>lblReqReason</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Request Reason:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>lblRequestReason</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Some reason...</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kopete/protocols/oscar/icq/ui/icqeditaccountui.ui b/kopete/protocols/oscar/icq/ui/icqeditaccountui.ui new file mode 100644 index 00000000..3ecc91cb --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqeditaccountui.ui @@ -0,0 +1,486 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICQEditAccountUI</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICQEditAccountUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>592</width> + <height>404</height> + </rect> + </property> + <property name="caption"> + <string>Account Preferences - ICQ</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget7</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>&Basic Setup</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>Account Preferences</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>lblAccountId</cstring> + </property> + <property name="text"> + <string>IC&Q UIN:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>edtAccountId</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The user ID of your ICQ account.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The user ID of your ICQ account. This should be in the form of a number (no decimals, no spaces).</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>edtAccountId</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The user ID of your ICQ account.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The user ID of your ICQ account. This should be in the form of a number (no decimals, no spaces).</string> + </property> + </widget> + </hbox> + </widget> + <widget class="Kopete::UI::PasswordWidget"> + <property name="name"> + <cstring>mPasswordWidget</cstring> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>chkAutoLogin</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>E&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> + <widget class="QCheckBox"> + <property name="name"> + <cstring>chkGlobalIdentity</cstring> + </property> + <property name="text"> + <string>Exclu&de from Global Identity</string> + </property> + </widget> + </vbox> + </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 ICQ network, you will need an ICQ account.<br><br> +If you do not currently have an ICQ account, 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&gister New Account</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacerBasicSetup</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Accou&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>groupBox2</cstring> + </property> + <property name="title"> + <string>Connection Preferences</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSpinBox" row="1" column="3"> + <property name="name"> + <cstring>edtServerPort</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 ICQ server that you would like to connect to.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The port on the ICQ server that you would like to connect to. Normally this is 5190.</string> + </property> + </widget> + <widget class="QLineEdit" row="1" column="2"> + <property name="name"> + <cstring>edtServerAddress</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>login.icq.com</string> + </property> + <property name="toolTip" stdset="0"> + <string>The IP address or hostmask of the ICQ server you wish to connect to.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The IP address or hostmask of the ICQ server you wish to connect to. Normally you will want the default (login.icq.com).</string> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>lblServerPort</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Po&rt:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>edtServerPort</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The port on the ICQ server that you would like to connect to.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The port on the ICQ server that you would like to connect to. Normally this is 5190.</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>lblServer</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Ser&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 ICQ server you wish to connect to.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The IP address or hostmask of the ICQ server you wish to connect to. Normally you will want the default (login.icq.com).</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>optionOverrideServer</cstring> + </property> + <property name="text"> + <string>&Override default server information</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>groupBox65</cstring> + </property> + <property name="title"> + <string>Privacy Options</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>chkRequireAuth</cstring> + </property> + <property name="text"> + <string>&Require authorization before someone can add you to their contact list</string> + </property> + <property name="toolTip" stdset="0"> + <string>Enable authorization requirement, which will not allow users to add you to their contact list without authorization from you.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Enable authorization requirement, which will not allow users to add you to their contact list without authorization from you. Check this box, and you will have to confirm any users who add you to their list before they may see your online status.</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>chkHideIP</cstring> + </property> + <property name="text"> + <string>Hide &IP address</string> + </property> + <property name="toolTip" stdset="0"> + <string>Check this to hide your IP address from people when they view your user info</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Checking this box will not allow people to see what your IP address if they view your ICQ user details such as name, address, or age.</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>chkWebAware</cstring> + </property> + <property name="text"> + <string>Make my status available via &ICQ's unified messaging center</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Check this box to enable Web Aware functionality.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Check this box to enable ICQ's Web Aware functionality, which allows people to see your online status from ICQ's web page, and send you a message without necessarily having ICQ themselves.</string> + </property> + </widget> + </grid> + </widget> + <spacer row="3" column="0"> + <property name="name"> + <cstring>spacerPreferences</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + <widget class="QComboBox" row="2" column="1"> + <property name="name"> + <cstring>encodingCombo</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Default to the following &encoding for messages:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>encodingCombo</cstring> + </property> + </widget> + </grid> + </widget> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>labelStatusMessage</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + </vbox> +</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>lblServerPort</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>edtServerPort</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>tabWidget7</tabstop> + <tabstop>edtAccountId</tabstop> + <tabstop>chkAutoLogin</tabstop> + <tabstop>buttonRegister</tabstop> + <tabstop>optionOverrideServer</tabstop> + <tabstop>edtServerAddress</tabstop> + <tabstop>edtServerPort</tabstop> + <tabstop>chkRequireAuth</tabstop> + <tabstop>chkHideIP</tabstop> + <tabstop>chkWebAware</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kopetepasswordwidget.h</includehint> +</includehints> +</UI> diff --git a/kopete/protocols/oscar/icq/ui/icqeditaccountwidget.cpp b/kopete/protocols/oscar/icq/ui/icqeditaccountwidget.cpp new file mode 100644 index 00000000..e4b308be --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqeditaccountwidget.cpp @@ -0,0 +1,190 @@ +/* + icqeditaccountwidget.cpp - ICQ 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. * + * * + ************************************************************************* +*/ + +#include "icqeditaccountwidget.h" +#include "icqeditaccountui.h" + +#include <qlayout.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qlineedit.h> +#include <qtextedit.h> +#include <qspinbox.h> +#include <qpushbutton.h> + +#include <kconfig.h> +#include <kdebug.h> +#include <kdialog.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kjanuswidget.h> +#include <kurllabel.h> +#include <kdatewidget.h> +#include <krun.h> +#include <kpassdlg.h> + +#include "kopetepassword.h" +#include "kopetepasswordwidget.h" + +#include "icqprotocol.h" +#include "icqaccount.h" +#include "icqcontact.h" + +ICQEditAccountWidget::ICQEditAccountWidget(ICQProtocol *protocol, + Kopete::Account *account, QWidget *parent, const char *name) + : QWidget(parent, name), KopeteEditAccountWidget(account) +{ + kdDebug(14153) << k_funcinfo << "Called." << endl; + + mAccount=dynamic_cast<ICQAccount*>(account); + mProtocol=protocol; + + (new QVBoxLayout(this))->setAutoAdd(true); + mAccountSettings = new ICQEditAccountUI( this ); + + mProtocol->fillComboFromTable( mAccountSettings->encodingCombo, mProtocol->encodings() ); + + // Read in the settings from the account if it exists + if(mAccount) + { + mAccountSettings->edtAccountId->setText(mAccount->accountId()); + + // TODO: Remove me after we can change Account IDs (Matt) + mAccountSettings->edtAccountId->setDisabled(true); + mAccountSettings->mPasswordWidget->load(&mAccount->password()); + mAccountSettings->chkAutoLogin->setChecked(mAccount->excludeConnect()); + + QString serverEntry = mAccount->configGroup()->readEntry("Server", "login.oscar.aol.com"); + int portEntry = mAccount->configGroup()->readNumEntry("Port", 5190); + if ( serverEntry != "login.oscar.aol.com" || ( portEntry != 5190) ) + mAccountSettings->optionOverrideServer->setChecked( true ); + + mAccountSettings->edtServerAddress->setText( serverEntry ); + mAccountSettings->edtServerPort->setValue( portEntry ); + + bool configValue = mAccount->configGroup()->readBoolEntry( "RequireAuth", false ); + mAccountSettings->chkRequireAuth->setChecked( configValue ); + + configValue = mAccount->configGroup()->readBoolEntry( "HideIP", true ); + mAccountSettings->chkHideIP->setChecked( configValue ); + + configValue = mAccount->configGroup()->readBoolEntry( "WebAware", false ); + mAccountSettings->chkWebAware->setChecked( configValue ); + + int encodingValue = mAccount->configGroup()->readNumEntry( "DefaultEncoding", 4 ); + mProtocol->setComboFromTable( mAccountSettings->encodingCombo, + mProtocol->encodings(), + encodingValue ); + + // Global Identity + mAccountSettings->chkGlobalIdentity->setChecked( mAccount->configGroup()->readBoolEntry("ExcludeGlobalIdentity", false) ); + } + else + { + mProtocol->setComboFromTable( mAccountSettings->encodingCombo, + mProtocol->encodings(), + 4 ); + } + + QObject::connect(mAccountSettings->buttonRegister, SIGNAL(clicked()), this, SLOT(slotOpenRegister())); + + /* Set tab order to password custom widget correctly */ + QWidget::setTabOrder( mAccountSettings->edtAccountId, mAccountSettings->mPasswordWidget->mRemembered ); + QWidget::setTabOrder( mAccountSettings->mPasswordWidget->mRemembered, mAccountSettings->mPasswordWidget->mPassword ); + QWidget::setTabOrder( mAccountSettings->mPasswordWidget->mPassword, mAccountSettings->chkAutoLogin ); + +} + +Kopete::Account *ICQEditAccountWidget::apply() +{ + kdDebug(14153) << k_funcinfo << "Called." << endl; + + // If this is a new account, create it + if (!mAccount) + { + kdDebug(14153) << k_funcinfo << "Creating a new account" << endl; + mAccount = new ICQAccount(mProtocol, mAccountSettings->edtAccountId->text()); + if(!mAccount) + return NULL; + } + + mAccountSettings->mPasswordWidget->save(&mAccount->password()); + mAccount->setExcludeConnect(mAccountSettings->chkAutoLogin->isChecked()); + + bool configValue = mAccountSettings->chkRequireAuth->isChecked(); + mAccount->configGroup()->writeEntry( "RequireAuth", configValue ); + + configValue = mAccountSettings->chkHideIP->isChecked(); + mAccount->configGroup()->writeEntry( "HideIP", configValue ); + + configValue = mAccountSettings->chkWebAware->isChecked(); + mAccount->configGroup()->writeEntry( "WebAware", configValue ); + + int encodingMib = mProtocol->getCodeForCombo( mAccountSettings->encodingCombo, + mProtocol->encodings() ); + mAccount->configGroup()->writeEntry( "DefaultEncoding", encodingMib ); + + if ( mAccountSettings->optionOverrideServer->isChecked() ) + { + mAccount->setServerAddress(mAccountSettings->edtServerAddress->text()); + mAccount->setServerPort(mAccountSettings->edtServerPort->value()); + } + else + { + mAccount->setServerAddress("login.oscar.aol.com"); + mAccount->setServerPort(5190); + } + + // Global Identity + mAccount->configGroup()->writeEntry( "ExcludeGlobalIdentity", mAccountSettings->chkGlobalIdentity->isChecked() ); + + return mAccount; +} + +bool ICQEditAccountWidget::validateData() +{ + kdDebug(14153) << k_funcinfo << "Called." << endl; + + QString userName = mAccountSettings->edtAccountId->text(); + + if (userName.isEmpty()) + return false; + + for (unsigned int i=0; i<userName.length(); i++) + { + if(!(userName[i]).isNumber()) + return false; + } + + // No need to check port, min and max values are properly defined in .ui + + if (mAccountSettings->edtServerAddress->text().isEmpty()) + return false; + + // Seems good to me + kdDebug(14153) << k_funcinfo << + "Account data validated successfully." << endl; + return true; +} + +void ICQEditAccountWidget::slotOpenRegister() +{ + KRun::runURL( "http://go.icq.com/register/", "text/html" ); +} + +#include "icqeditaccountwidget.moc" +// vim: set noet ts=4 sts=4 sw=4: +// kate: indent-mode csands; space-indent off; replace-tabs off; diff --git a/kopete/protocols/oscar/icq/ui/icqeditaccountwidget.h b/kopete/protocols/oscar/icq/ui/icqeditaccountwidget.h new file mode 100644 index 00000000..fc5c6d38 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqeditaccountwidget.h @@ -0,0 +1,52 @@ +/* + icqeditaccountwidget.h - ICQ Account Widget + + Copyright (c) 2003 by Chris TenHarmsel <tenharmsel@staticmethod.net> + Copyright (c) 2004-2005 by Matt Rogers <mattr@kde.org> + Kopete (c) 2002-2005 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 ICQEDITACCOUNTWIDGET_H +#define ICQEDITACCOUNTWIDGET_H + +#include <qwidget.h> +#include <qdatetime.h> +#include "editaccountwidget.h" + +namespace Kopete { class Account; } + +class ICQAccount; +class ICQProtocol; +class ICQEditAccountUI; + +class ICQEditAccountWidget : public QWidget, public KopeteEditAccountWidget +{ +Q_OBJECT + +public: + ICQEditAccountWidget(ICQProtocol *, Kopete::Account *, + QWidget *parent=0, const char *name=0); + + virtual bool validateData(); + virtual Kopete::Account *apply(); + +private slots: + void slotOpenRegister(); + +protected: + ICQAccount *mAccount; + ICQProtocol *mProtocol; + ICQEditAccountUI *mAccountSettings; +}; +#endif +// vim: set noet ts=4 sts=4 sw=4: +// kate: indent-mode csands; space-indent off; replace-tabs off; diff --git a/kopete/protocols/oscar/icq/ui/icqgeneralinfo.ui b/kopete/protocols/oscar/icq/ui/icqgeneralinfo.ui new file mode 100644 index 00000000..6383bec1 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqgeneralinfo.ui @@ -0,0 +1,611 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICQGeneralInfoWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICQGeneralInfoWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>488</width> + <height>572</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Location && Contact Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>&City:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cityEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&Address:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>addressEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>&Phone:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>phoneEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>&State:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>stateEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>cityEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>textLabel8</cstring> + </property> + <property name="text"> + <string>Countr&y:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>countryEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="6" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>homepageEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>textLabel9</cstring> + </property> + <property name="text"> + <string>&Email:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>emailEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="5" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>emailEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="6" column="0"> + <property name="name"> + <cstring>textLabel10_2</cstring> + </property> + <property name="text"> + <string>&Homepage:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>homepageEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="3" column="3"> + <property name="name"> + <cstring>cellEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="2" column="3"> + <property name="name"> + <cstring>countryEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="1" column="3"> + <property name="name"> + <cstring>stateEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel7_2</cstring> + </property> + <property name="text"> + <string>Fa&x:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>faxEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="4" column="1"> + <property name="name"> + <cstring>faxEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="3" column="1"> + <property name="name"> + <cstring>phoneEdit</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="3" column="2"> + <property name="name"> + <cstring>textLabel6_2</cstring> + </property> + <property name="text"> + <string>Ce&ll:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cellEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>addressEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>&Zip:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>zipEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1"> + <property name="name"> + <cstring>zipEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>groupBox4</cstring> + </property> + <property name="title"> + <string>Personal Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit" row="0" column="3"> + <property name="name"> + <cstring>uinEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>fullNameLabel</cstring> + </property> + <property name="text"> + <string>&Full name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>fullNameEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="1" column="3"> + <property name="name"> + <cstring>ipEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>125</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="2" column="3"> + <property name="name"> + <cstring>timezoneEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>nickNameEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>2</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>nickNameLabel</cstring> + </property> + <property name="text"> + <string>&Nickname:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nickNameEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>uinLabel</cstring> + </property> + <property name="text"> + <string>&UIN #:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>uinEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>birthdayLabel</cstring> + </property> + <property name="text"> + <string>&Birthday:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>birthday</cstring> + </property> + </widget> + <widget class="QSpinBox" row="3" column="3"> + <property name="name"> + <cstring>ageSpinBox</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string>Gen&der:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>genderEdit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="3" column="1"> + <property name="name"> + <cstring>birthday</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>fullNameEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1"> + <property name="name"> + <cstring>genderEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>ipLabel</cstring> + </property> + <property name="text"> + <string>&IP:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>ipEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>textLabel7</cstring> + </property> + <property name="text"> + <string>&Timezone:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>timezoneEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>maritalLabel</cstring> + </property> + <property name="text"> + <string>Marital status:</string> + </property> + </widget> + <widget class="QLabel" row="3" column="2"> + <property name="name"> + <cstring>textLabel10</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>A&ge:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>ageSpinBox</cstring> + </property> + </widget> + <widget class="QLineEdit" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>marital</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="2" column="0"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>Origin</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>oStateEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1"> + <property name="name"> + <cstring>oCountryEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>oCityEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>City:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3_2</cstring> + </property> + <property name="text"> + <string>Country:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>State:</string> + </property> + </widget> + </grid> + </widget> + <spacer row="3" column="0"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<tabstops> + <tabstop>nickNameEdit</tabstop> + <tabstop>fullNameEdit</tabstop> + <tabstop>genderEdit</tabstop> + <tabstop>uinEdit</tabstop> + <tabstop>ipEdit</tabstop> + <tabstop>timezoneEdit</tabstop> + <tabstop>ageSpinBox</tabstop> + <tabstop>addressEdit</tabstop> + <tabstop>cityEdit</tabstop> + <tabstop>stateEdit</tabstop> + <tabstop>zipEdit</tabstop> + <tabstop>countryEdit</tabstop> + <tabstop>phoneEdit</tabstop> + <tabstop>faxEdit</tabstop> + <tabstop>cellEdit</tabstop> + <tabstop>emailEdit</tabstop> + <tabstop>homepageEdit</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kopete/protocols/oscar/icq/ui/icqinterestinfowidget.ui b/kopete/protocols/oscar/icq/ui/icqinterestinfowidget.ui new file mode 100644 index 00000000..ce4041c9 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqinterestinfowidget.ui @@ -0,0 +1,116 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICQInterestInfoWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICQInterestInfoWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>660</width> + <height>572</height> + </rect> + </property> + <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>Interests</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>desc1</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>desc2</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1"> + <property name="name"> + <cstring>desc3</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="1" column="0"> + <property name="name"> + <cstring>topic2</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="0" column="0"> + <property name="name"> + <cstring>topic1</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="2" column="0"> + <property name="name"> + <cstring>topic3</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="3" column="0"> + <property name="name"> + <cstring>topic4</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="3" column="1"> + <property name="name"> + <cstring>desc4</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <spacer row="1" column="0"> + <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>220</height> + </size> + </property> + </spacer> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kopete/protocols/oscar/icq/ui/icqotherinfowidget.ui b/kopete/protocols/oscar/icq/ui/icqotherinfowidget.ui new file mode 100644 index 00000000..4e5a3a34 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqotherinfowidget.ui @@ -0,0 +1,68 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICQOtherInfoWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICQOtherInfoWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>289</width> + <height>473</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="4" column="1"> + <property name="name"> + <cstring>spacer8</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>30</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel12</cstring> + </property> + <property name="text"> + <string>Email addresses:</string> + </property> + </widget> + <widget class="QListBox" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>emailListBox</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>textLabel13</cstring> + </property> + <property name="text"> + <string>Contact notes:</string> + </property> + </widget> + <widget class="QTextEdit" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>notesEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kopete/protocols/oscar/icq/ui/icqsearchbase.ui b/kopete/protocols/oscar/icq/ui/icqsearchbase.ui new file mode 100644 index 00000000..68e59281 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqsearchbase.ui @@ -0,0 +1,493 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICQSearchBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICQSearchBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>603</width> + <height>465</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton" row="4" column="1"> + <property name="name"> + <cstring>clearButton</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>C&lear</string> + </property> + <property name="stdItem" stdset="0"> + <number>10</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Clear the results</string> + </property> + </widget> + <widget class="KPushButton" row="7" column="1"> + <property name="name"> + <cstring>closeButton</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + <property name="stdItem" stdset="0"> + <number>13</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Close this dialog</string> + </property> + </widget> + <widget class="KPushButton" row="3" column="1"> + <property name="name"> + <cstring>stopButton</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Stop</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="stdItem" stdset="0"> + <number>26</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Stops the search</string> + </property> + </widget> + <widget class="KPushButton" row="5" column="1"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Add</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="stdItem" stdset="0"> + <number>27</number> + </property> + <property name="whatsThis" stdset="0"> + <string>Add the selected user to your contact list</string> + </property> + </widget> + <widget class="KPushButton" row="6" column="1"> + <property name="name"> + <cstring>userInfoButton</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>User Info</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="whatsThis" stdset="0"> + <string>Show information about the selected contact</string> + </property> + </widget> + <spacer row="0" column="1"> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>41</width> + <height>190</height> + </size> + </property> + </spacer> + <widget class="QTabWidget" row="0" column="0"> + <property name="name"> + <cstring>tabWidget3</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>UIN Search</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>&UIN #:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>uin</cstring> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>uin</cstring> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>105</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>ICQ Whitepages Search</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit" row="1" column="3"> + <property name="name"> + <cstring>lastName</cstring> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>nickName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>&Last name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>lastName</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>&First name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>firstName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string>&Email:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>email</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>&Nickname:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>nickName</cstring> + </property> + </widget> + <widget class="QComboBox" row="3" column="3"> + <property name="name"> + <cstring>country</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel9</cstring> + </property> + <property name="text"> + <string>Lan&guage:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>language</cstring> + </property> + </widget> + <widget class="QComboBox" row="3" column="1"> + <property name="name"> + <cstring>language</cstring> + </property> + </widget> + <widget class="QLineEdit" row="2" column="3"> + <property name="name"> + <cstring>city</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>textLabel10</cstring> + </property> + <property name="text"> + <string>&City:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>city</cstring> + </property> + </widget> + <widget class="QLineEdit" row="0" column="3"> + <property name="name"> + <cstring>firstName</cstring> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>email</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel8</cstring> + </property> + <property name="text"> + <string>&Gender:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>gender</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <property name="name"> + <cstring>gender</cstring> + </property> + </widget> + <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>onlyOnline</cstring> + </property> + <property name="text"> + <string>Only search for online contacts</string> + </property> + </widget> + <widget class="QLabel" row="3" column="2"> + <property name="name"> + <cstring>textLabel11</cstring> + </property> + <property name="text"> + <string>C&ountry:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>country</cstring> + </property> + </widget> + <spacer row="5" column="1"> + <property name="name"> + <cstring>spacer5</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> + <spacer row="4" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>166</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="KListView" row="1" column="0" rowspan="7" colspan="1"> + <column> + <property name="text"> + <string>UIN</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Nickname</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>First Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Last Name</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Email</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Requires Authorization?</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>searchResults</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="whatsThis" stdset="0"> + <string>This is where the results from your search are displayed. If you double-click a result, the search window will close and pass the UIN of the contact you wish to add back to the Add Contact Wizard. You can only add one contact at a time.</string> + </property> + </widget> + <widget class="KPushButton" row="1" column="1"> + <property name="name"> + <cstring>searchButton</cstring> + </property> + <property name="text"> + <string>&Search</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Search the ICQ Whitepages with your search criteria</string> + </property> + </widget> + <widget class="KPushButton" row="2" column="1"> + <property name="name"> + <cstring>newSearchButton</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>New Search</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Clears both search fields and results</string> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>tabWidget3</tabstop> + <tabstop>uin</tabstop> + <tabstop>nickName</tabstop> + <tabstop>firstName</tabstop> + <tabstop>email</tabstop> + <tabstop>lastName</tabstop> + <tabstop>gender</tabstop> + <tabstop>city</tabstop> + <tabstop>language</tabstop> + <tabstop>country</tabstop> + <tabstop>onlyOnline</tabstop> + <tabstop>searchButton</tabstop> + <tabstop>stopButton</tabstop> + <tabstop>clearButton</tabstop> + <tabstop>addButton</tabstop> + <tabstop>userInfoButton</tabstop> + <tabstop>closeButton</tabstop> + <tabstop>searchResults</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistview.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/kopete/protocols/oscar/icq/ui/icqsearchdialog.cpp b/kopete/protocols/oscar/icq/ui/icqsearchdialog.cpp new file mode 100644 index 00000000..0010166a --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqsearchdialog.cpp @@ -0,0 +1,320 @@ +/* + Kopete Oscar Protocol + icqsearchdialog.cpp - search for people + + Copyright (c) 2005 Matt Rogers <mattr@kde.org> + + Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org> + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + ************************************************************************* +*/ + +#include "icqsearchdialog.h" + +#include <qlineedit.h> +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qlayout.h> +#include <qtextcodec.h> +#include <qtabwidget.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <klistview.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <kmessagebox.h> + +#include "kopeteuiglobal.h" + +#include "icqaccount.h" +#include "icqaddcontactpage.h" +#include "icqprotocol.h" +#include "icqsearchbase.h" +#include "oscartypes.h" +#include "icqcontact.h" +#include "icquserinfowidget.h" + +ICQSearchDialog::ICQSearchDialog( ICQAccount* account, QWidget* parent, const char* name ) +: KDialogBase( parent, name, true, i18n( "ICQ User Search" ), 0, NoDefault ) +{ + m_account = account; + m_searchUI = new ICQSearchBase( this, name ); + setMainWidget( m_searchUI ); + connect( m_searchUI->searchButton, SIGNAL( clicked() ), this, SLOT( startSearch() ) ); + connect( m_searchUI->searchResults, SIGNAL( selectionChanged() ), this, SLOT( resultSelectionChanged() ) ); + connect( m_searchUI->addButton, SIGNAL( clicked() ), this, SLOT( addContact() ) ); + connect( m_searchUI->clearButton, SIGNAL( clicked() ), this, SLOT( clearResults() ) ); + connect( m_searchUI->stopButton, SIGNAL( clicked() ), this, SLOT( stopSearch() ) ); + connect( m_searchUI->closeButton, SIGNAL( clicked() ), this, SLOT( closeDialog() ) ); + connect( m_searchUI->userInfoButton, SIGNAL( clicked() ), this, SLOT( userInfo() ) ); + connect( m_searchUI->newSearchButton, SIGNAL( clicked() ), this, SLOT( newSearch() ) ); + + ICQProtocol *p = ICQProtocol::protocol(); + p->fillComboFromTable( m_searchUI->gender, p->genders() ); + p->fillComboFromTable( m_searchUI->country, p->countries() ); + p->fillComboFromTable( m_searchUI->language, p->languages() ); + + m_contact = NULL; + m_infoWidget = NULL; + + m_contact = NULL; + m_infoWidget = NULL; +} + + +ICQSearchDialog::~ICQSearchDialog() +{ +} + +void ICQSearchDialog::startSearch() +{ + // Doing the search only if the account is online, otherwise warn the user + if(!m_account->isConnected()) + { + // Account currently offline + m_searchUI->searchButton->setEnabled( false ); + KMessageBox::sorry( this, i18n("You must be online to search the ICQ Whitepages."), i18n("ICQ Plugin") ); + } + else + { + // Account is online + clearResults(); + + m_searchUI->stopButton->setEnabled( true ); + m_searchUI->searchButton->setEnabled( false ); + m_searchUI->newSearchButton->setEnabled( false ); + + connect( m_account->engine(), SIGNAL( gotSearchResults( const ICQSearchResult& ) ), + this, SLOT( newResult( const ICQSearchResult& ) ) ); + connect( m_account->engine(), SIGNAL( endOfSearch( int ) ), + this, SLOT( searchFinished( int ) ) ); + + const QWidget* currentPage = m_searchUI->tabWidget3->currentPage(); + + if ( currentPage == m_searchUI->tab ) + { + if( m_searchUI->uin->text().isEmpty() || m_searchUI->uin->text().toULong() == 0 ) + { + // Invalid UIN + stopSearch(); + clearResults(); + KMessageBox::sorry( this, i18n("You must enter a valid UIN."), i18n("ICQ Plugin") ); + kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Search aborted: invalid UIN " << m_searchUI->uin->text() << endl; + } + else + { + //doing a uin search + m_account->engine()->uinSearch( m_searchUI->uin->text() ); + } + } + else if ( currentPage == m_searchUI->tab_2 ) + { + //create a ICQWPSearchInfo struct and send it + ICQProtocol* p = ICQProtocol::protocol(); + ICQWPSearchInfo info; + QTextCodec* codec = m_account->defaultCodec(); + info.firstName = codec->fromUnicode( m_searchUI->firstName->text() ); + info.lastName = codec->fromUnicode( m_searchUI->lastName->text() ); + info.nickName = codec->fromUnicode( m_searchUI->nickName->text() ); + info.email = codec->fromUnicode( m_searchUI->email->text() ); + info.city = codec->fromUnicode( m_searchUI->city->text() ); // City + info.gender = p->getCodeForCombo(m_searchUI->gender, p->genders()); // Gender + info.language = p->getCodeForCombo(m_searchUI->language, p->languages()); // Lang + info.country =p->getCodeForCombo(m_searchUI->country, p->countries()); // country code + info.onlineOnly = m_searchUI->onlyOnline->isChecked(); + + // Check if the user has actually entered things to search + if( info.firstName.isEmpty() && + info.lastName.isEmpty() && + info.nickName.isEmpty() && + info.email.isEmpty() && + info.city.isEmpty() && + (info.gender == 0) && + (info.language == 0) && + (info.country == 0) + ) + { + // All fields were blank + stopSearch(); + clearResults(); + KMessageBox::information(this, i18n("You must enter search criteria."), i18n("ICQ Plugin") ); + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "Search aborted: all fields were blank" << endl; + } + else + { + // Start the search + m_account->engine()->whitePagesSearch( info ); + kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Starting whitepage search" << endl; + } + } + } +} + +void ICQSearchDialog::stopSearch() +{ + disconnect( m_account->engine(), SIGNAL( gotSearchResults( const ICQSearchResult& ) ), + this, SLOT( newResult( const ICQSearchResult& ) ) ); + disconnect( m_account->engine(), SIGNAL( endOfSearch( int ) ), + this, SLOT( searchFinished( int ) ) ); + + m_searchUI->stopButton->setEnabled( false ); + m_searchUI->searchButton->setEnabled( true ); + m_searchUI->newSearchButton->setEnabled( true ); +} + +void ICQSearchDialog::addContact() +{ + ICQAddContactPage* iacp = dynamic_cast<ICQAddContactPage*>( parent() ); + if ( !iacp ) + { + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "The ICQ ACP is not our parent!!" << endl; + } + else + { + QString uin = m_searchUI->searchResults->selectedItem()->text( 0 ); + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "Passing " << uin << " back to the ACP" << endl; + iacp->setUINFromSearch( uin ); + + // Closing the dialog + closeDialog(); + } +} + +void ICQSearchDialog::userInfo() +{ + // Lookup user info only if the account is online, otherwise warn the user + if(!m_account->isConnected()) + { + // Account currently offline + KMessageBox::sorry( this, i18n("You must be online to display user info."), i18n("ICQ Plugin") ); + } + else + { + // Account currently online + m_contact = new ICQContact( m_account, + m_searchUI->searchResults->selectedItem()->text( 0 ), + NULL); + + m_infoWidget = new ICQUserInfoWidget( Kopete::UI::Global::mainWidget(), "icq info" ); + QObject::connect( m_infoWidget, SIGNAL( finished() ), this, SLOT( closeUserInfo() ) ); + + m_infoWidget->setContact( m_contact ); + m_infoWidget->setModal(true); + m_infoWidget->show(); + if ( m_contact->account()->isConnected() ) + m_account->engine()->requestFullInfo( m_contact->contactId() ); + kdDebug(OSCAR_ICQ_DEBUG) << k_funcinfo << "Displaying user info" << endl; + } +} + +void ICQSearchDialog::closeUserInfo() +{ + // Free the ICQUserInfoWidget + QObject::disconnect( this, 0, m_infoWidget, 0 ); + m_infoWidget->delayedDestruct(); + m_infoWidget = NULL; + + // Free the ICQContact + delete m_contact; + m_contact = NULL; +} + +void ICQSearchDialog::clearResults() +{ + stopSearch(); + m_searchUI->searchResults->clear(); + m_searchUI->addButton->setEnabled( false ); + m_searchUI->userInfoButton->setEnabled( false ); + m_searchUI->searchButton->setEnabled( true ); +} + +void ICQSearchDialog::closeDialog() +{ + stopSearch(); + clearResults(); + clearFields(); + + slotClose(); +} + +void ICQSearchDialog::resultSelectionChanged() +{ + if ( !m_searchUI->searchResults->selectedItem() ) + { + m_searchUI->addButton->setEnabled( false ); + m_searchUI->userInfoButton->setEnabled( false ); + } + else + { + m_searchUI->addButton->setEnabled( true ); + m_searchUI->userInfoButton->setEnabled( true ); + } +} + +void ICQSearchDialog::newResult( const ICQSearchResult& info ) +{ + if ( info.uin == 1 ) + { + //TODO update progress + return; + } + + QTextCodec* codec = m_account->defaultCodec(); + + QListViewItem *item = new QListViewItem( m_searchUI->searchResults, QString::number( info.uin ), + codec->toUnicode( info.nickName ), + codec->toUnicode( info.firstName ), + codec->toUnicode( info.lastName ), + codec->toUnicode( info.email ), + info.auth ? i18n( "Yes" ) : i18n( "No" ) ); + + if ( !item ) + return; + + if ( info.online ) + item->setPixmap( 0, SmallIcon( "icq_online" ) ); + else + item->setPixmap( 0, SmallIcon( "icq_offline" ) ); + +} + +void ICQSearchDialog::searchFinished( int numLeft ) +{ + kdWarning(OSCAR_ICQ_DEBUG) << k_funcinfo << "There are " << numLeft << "contact left out of this search" << endl; + m_searchUI->stopButton->setEnabled( false ); + m_searchUI->clearButton->setEnabled( true ); + m_searchUI->searchButton->setEnabled( true ); + m_searchUI->newSearchButton->setEnabled( true ); +} + +void ICQSearchDialog::clearFields() +{ + m_searchUI->uin->setText( QString::null ); + + m_searchUI->firstName->setText( QString::null ); + m_searchUI->lastName->setText( QString::null ); + m_searchUI->nickName->setText( QString::null ); + m_searchUI->email->setText( QString::null ); + m_searchUI->city->setText( QString::null ); + m_searchUI->gender->setCurrentItem( 0 ); // Unspecified + m_searchUI->country->setCurrentItem( 0 ); + m_searchUI->language->setCurrentItem( 0 ); + m_searchUI->onlyOnline->setChecked( false ); +} + +void ICQSearchDialog::newSearch() +{ + clearResults(); + clearFields(); +} + +//kate: indent-mode csands; space-indent off; replace-tabs off; tab-width 4; + +#include "icqsearchdialog.moc" diff --git a/kopete/protocols/oscar/icq/ui/icqsearchdialog.h b/kopete/protocols/oscar/icq/ui/icqsearchdialog.h new file mode 100644 index 00000000..b14aa2a1 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqsearchdialog.h @@ -0,0 +1,69 @@ +/* + Kopete Oscar Protocol + icqsearchdialog.h - search for people + + Copyright (c) 2005 Matt Rogers <mattr@kde.org> + + Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org> + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + ************************************************************************* +*/ + +#ifndef ICQSEARCHDIALOG_H +#define ICQSEARCHDIALOG_H + +#include <kdialogbase.h> +#include "icquserinfo.h" + +class ICQAccount; +class ICQSearchBase; +class ICQContact; +class ICQUserInfoWidget; +/** +@author Kopete Developers +*/ +class ICQSearchDialog : public KDialogBase +{ +Q_OBJECT +public: + ICQSearchDialog( ICQAccount* account, QWidget* parent = 0, const char* name = 0 ); + ~ICQSearchDialog(); + +private slots: + void startSearch(); + void stopSearch(); + void addContact(); + void clearResults(); + void closeDialog(); + void userInfo(); + void closeUserInfo(); + void newSearch(); + + /// Enable/disable buttons when the selection changes + void resultSelectionChanged(); + + /// Add a search result to the listview + void newResult( const ICQSearchResult& info ); + + /// The search is finished + void searchFinished( int numLeft ); + +private: + ICQAccount* m_account; + ICQSearchBase* m_searchUI; + ICQContact* m_contact; + ICQUserInfoWidget* m_infoWidget; + + void clearFields(); +}; + +#endif + +//kate: indent-mode csands; space-indent off; replace-tabs off; tab-width 4; diff --git a/kopete/protocols/oscar/icq/ui/icquserinfowidget.cpp b/kopete/protocols/oscar/icq/ui/icquserinfowidget.cpp new file mode 100644 index 00000000..3830e05f --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icquserinfowidget.cpp @@ -0,0 +1,190 @@ +/* + Kopete Oscar Protocol + icquserinfowidget.cpp - Display ICQ user info + + Copyright (c) 2005 Matt Rogers <mattr@kde.org> + + Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org> + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + ************************************************************************* +*/ + +#include "icquserinfowidget.h" + +#include <qlayout.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qcombobox.h> +#include <qobject.h> +#include <qtextcodec.h> + +#include <kdatewidget.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kjanuswidget.h> +#include <klocale.h> + +#include "icqgeneralinfo.h" +#include "icqcontact.h" +#include "icqprotocol.h" +#include "icqworkinfowidget.h" +#include "icqotherinfowidget.h" +#include "icqinterestinfowidget.h" + + +ICQUserInfoWidget::ICQUserInfoWidget( QWidget * parent, const char * name ) +: KDialogBase( KDialogBase::IconList, 0, parent, name, false, i18n( "ICQ User Information" ), Ok ) +{ + kdDebug(14153) << k_funcinfo << "Creating new icq user info widget" << endl; + + QFrame* genInfo = addPage( i18n( "General Info" ), + i18n( "General ICQ Information" ), + KGlobal::iconLoader()->loadIcon( QString::fromLatin1( "identity" ), KIcon::Desktop ) ); + QVBoxLayout* genLayout = new QVBoxLayout( genInfo ); + m_genInfoWidget = new ICQGeneralInfoWidget( genInfo, "Basic Information" ); + genLayout->addWidget( m_genInfoWidget ); + + QFrame* workInfo = addPage( i18n( "Work Info" ), + i18n( "Work Information" ), + KGlobal::iconLoader()->loadIcon( QString::fromLatin1( "attach" ), KIcon::Desktop ) ); + QVBoxLayout* workLayout = new QVBoxLayout( workInfo ); + m_workInfoWidget = new ICQWorkInfoWidget( workInfo, "Work Information" ); + workLayout->addWidget( m_workInfoWidget ); + + QFrame* otherInfo = addPage( i18n( "Other Info" ), + i18n( "Other ICQ Information" ), + KGlobal::iconLoader()->loadIcon( QString::fromLatin1( "email" ), KIcon::Desktop ) ); + QVBoxLayout* otherLayout = new QVBoxLayout( otherInfo ); + m_otherInfoWidget = new ICQOtherInfoWidget( otherInfo, "Other Information" ); + otherLayout->addWidget( m_otherInfoWidget ); + + QFrame* interestInfo = addPage( i18n( "Interest Info" ), + i18n( "Interest" ), + KGlobal::iconLoader()->loadIcon( QString::fromLatin1( "email" ), KIcon::Desktop ) ); + QVBoxLayout* interestLayout = new QVBoxLayout( interestInfo ); + m_interestInfoWidget = new ICQInterestInfoWidget( interestInfo, "Other Information" ); + interestLayout->addWidget( m_interestInfoWidget ); + +} + +void ICQUserInfoWidget::setContact( ICQContact* contact ) +{ + m_contact = contact; + QObject::connect( contact, SIGNAL( haveBasicInfo( const ICQGeneralUserInfo& ) ), + this, SLOT( fillBasicInfo( const ICQGeneralUserInfo& ) ) ); + QObject::connect( contact, SIGNAL( haveWorkInfo( const ICQWorkUserInfo& ) ), + this, SLOT( fillWorkInfo( const ICQWorkUserInfo& ) ) ); + QObject::connect( contact, SIGNAL( haveEmailInfo( const ICQEmailInfo& ) ), + this, SLOT( fillEmailInfo( const ICQEmailInfo& ) ) ); + QObject::connect( contact, SIGNAL( haveMoreInfo( const ICQMoreUserInfo& ) ), + this, SLOT( fillMoreInfo( const ICQMoreUserInfo& ) ) ); + QObject::connect( contact, SIGNAL( haveInterestInfo( const ICQInterestInfo& ) ), + this, SLOT( fillInterestInfo( const ICQInterestInfo& ) ) ); +} + +void ICQUserInfoWidget::fillBasicInfo( const ICQGeneralUserInfo& ui ) +{ + QTextCodec* codec = m_contact->contactCodec(); + m_genInfoWidget->uinEdit->setText( m_contact->contactId() ); + m_genInfoWidget->nickNameEdit->setText( codec->toUnicode( ui.nickname ) ); + m_genInfoWidget->fullNameEdit->setText( codec->toUnicode( ui.firstName ) + " " + codec->toUnicode( ui.lastName ) ); + m_genInfoWidget->ipEdit->setText( m_contact->property( "ipAddress" ).value().toString() ); + m_genInfoWidget->emailEdit->setText( codec->toUnicode( ui.email ) ); + m_genInfoWidget->cityEdit->setText( codec->toUnicode( ui.city ) ); + m_genInfoWidget->stateEdit->setText( codec->toUnicode( ui.state ) ); + m_genInfoWidget->phoneEdit->setText( codec->toUnicode( ui.phoneNumber ) ); + m_genInfoWidget->faxEdit->setText( codec->toUnicode( ui.faxNumber ) ); + m_genInfoWidget->addressEdit->setText( codec->toUnicode( ui.address ) ); + m_genInfoWidget->cellEdit->setText( codec->toUnicode( ui.cellNumber ) ); + m_genInfoWidget->zipEdit->setText( codec->toUnicode( ui.zip ) ); + + QString country = static_cast<ICQProtocol*>( m_contact->protocol() )->countries()[ui.country]; + m_genInfoWidget->countryEdit->setText( country ); +} + +void ICQUserInfoWidget::fillWorkInfo( const ICQWorkUserInfo& ui ) +{ + QTextCodec* codec = m_contact->contactCodec(); + m_workInfoWidget->cityEdit->setText( codec->toUnicode( ui.city ) ); + m_workInfoWidget->stateEdit->setText( codec->toUnicode( ui.state ) ); + m_workInfoWidget->phoneEdit->setText( codec->toUnicode( ui.phone ) ); + m_workInfoWidget->faxEdit->setText( codec->toUnicode( ui.fax ) ); + m_workInfoWidget->addressEdit->setText( codec->toUnicode( ui.address ) ); + m_workInfoWidget->zipEdit->setText( codec->toUnicode( ui.zip ) ); + m_workInfoWidget->companyEdit->setText( codec->toUnicode( ui.company ) ); + m_workInfoWidget->departmentEdit->setText( codec->toUnicode( ui.department ) ); + m_workInfoWidget->positionEdit->setText( codec->toUnicode( ui.position ) ); + m_workInfoWidget->homepageEdit->setText( codec->toUnicode( ui.homepage ) ); + + ICQProtocol* p = static_cast<ICQProtocol*>( m_contact->protocol() ); + QString country = p->countries()[ui.country]; + m_workInfoWidget->countryEdit->setText( country ); + + //TODO handle the occupation +} + +void ICQUserInfoWidget::fillEmailInfo( const ICQEmailInfo& ) +{ +} + +void ICQUserInfoWidget::fillInterestInfo( const ICQInterestInfo& info) +{ + QTextCodec* codec = m_contact->contactCodec(); + if (info.count>0) { + QString topic = static_cast<ICQProtocol*>( m_contact->protocol() )->interests()[info.topics[0]]; + m_interestInfoWidget->topic1->setText( topic ); + m_interestInfoWidget->desc1->setText( codec->toUnicode( info.descriptions[0] ) ); + } + if (info.count>1) { + QString topic = static_cast<ICQProtocol*>( m_contact->protocol() )->interests()[info.topics[1]]; + m_interestInfoWidget->topic2->setText( topic ); + m_interestInfoWidget->desc2->setText( codec->toUnicode( info.descriptions[1] ) ); + } + if (info.count>2) { + QString topic = static_cast<ICQProtocol*>( m_contact->protocol() )->interests()[info.topics[2]]; + m_interestInfoWidget->topic3->setText( topic ); + m_interestInfoWidget->desc3->setText( codec->toUnicode( info.descriptions[2] ) ); + } + if (info.count>3) { + QString topic = static_cast<ICQProtocol*>( m_contact->protocol() )->interests()[info.topics[3]]; + m_interestInfoWidget->topic4->setText( topic ); + m_interestInfoWidget->desc4->setText( codec->toUnicode( info.descriptions[3] ) ); + } +} + +void ICQUserInfoWidget::fillMoreInfo( const ICQMoreUserInfo& ui ) +{ + QTextCodec* codec = m_contact->contactCodec(); + m_genInfoWidget->ageSpinBox->setValue( ui.age ); + if ( ui.birthday.isValid() ) + m_genInfoWidget->birthday->setText( KGlobal::locale()->formatDate( ui.birthday,true ) ); + + QString gender = static_cast<ICQProtocol*>( m_contact->protocol() )->genders()[ui.gender]; + m_genInfoWidget->genderEdit->setText( gender ); + m_genInfoWidget->homepageEdit->setText( codec->toUnicode( ui.homepage ) ); + + QString ms = static_cast<ICQProtocol*>( m_contact->protocol() )->maritals()[ui.marital]; + m_genInfoWidget->marital->setText( ms ); + + m_genInfoWidget->oCityEdit->setText( codec->toUnicode( ui.ocity) ); + m_genInfoWidget->oStateEdit->setText( codec->toUnicode( ui.ostate) ); + + QString ocountry = static_cast<ICQProtocol*>( m_contact->protocol() )->countries()[ui.ocountry]; + m_genInfoWidget->oCountryEdit->setText( ocountry ); + + //TODO languages +} + + +#include "icquserinfowidget.moc" + +//kate: indent-mode csands; tab-width 4; space-indent off; replace-tabs off; + diff --git a/kopete/protocols/oscar/icq/ui/icquserinfowidget.h b/kopete/protocols/oscar/icq/ui/icquserinfowidget.h new file mode 100644 index 00000000..ef478e59 --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icquserinfowidget.h @@ -0,0 +1,58 @@ +/* + Kopete Oscar Protocol + icquserinfowidget.h - Display ICQ user info + + Copyright (c) 2005 Matt Rogers <mattr@kde.org> + + Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org> + + ************************************************************************* + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + ************************************************************************* +*/ + +#ifndef _ICQUSERINFOWIDGET_H_ +#define _ICQUSERINFOWIDGET_H_ + +#include <kdialogbase.h> +#include <icquserinfo.h> + +class KJanusWidget; +class ICQGeneralInfoWidget; +class ICQWorkInfoWidget; +class ICQOtherInfoWidget; +class ICQInterestInfoWidget; +class ICQContact; + +class ICQUserInfoWidget : public KDialogBase +{ +Q_OBJECT +public: + ICQUserInfoWidget( QWidget* parent = 0, const char* name = 0 ); + void setContact( ICQContact* contact ); + +public slots: + void fillBasicInfo( const ICQGeneralUserInfo& ); + void fillWorkInfo( const ICQWorkUserInfo& ); + void fillEmailInfo( const ICQEmailInfo& ); + void fillMoreInfo( const ICQMoreUserInfo& ); + void fillInterestInfo( const ICQInterestInfo& ); + +private: + ICQGeneralInfoWidget* m_genInfoWidget; + ICQWorkInfoWidget* m_workInfoWidget; + ICQOtherInfoWidget* m_otherInfoWidget; + ICQInterestInfoWidget * m_interestInfoWidget; + KJanusWidget* m_janusWidget; + ICQContact* m_contact; + +}; + +#endif + +//kate: indent-mode csands; tab-width 4; space-indent off; replace-tabs off; diff --git a/kopete/protocols/oscar/icq/ui/icqworkinfowidget.ui b/kopete/protocols/oscar/icq/ui/icqworkinfowidget.ui new file mode 100644 index 00000000..a31021ba --- /dev/null +++ b/kopete/protocols/oscar/icq/ui/icqworkinfowidget.ui @@ -0,0 +1,249 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ICQWorkInfoWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ICQWorkInfoWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>328</width> + <height>480</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>Personal Work Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel10</cstring> + </property> + <property name="text"> + <string>Phone:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>textLabel11</cstring> + </property> + <property name="text"> + <string>Fax:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel6</cstring> + </property> + <property name="text"> + <string>Department:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>departmentEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>textLabel7</cstring> + </property> + <property name="text"> + <string>Position:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="3"> + <property name="name"> + <cstring>positionEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>phoneEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="1" column="3"> + <property name="name"> + <cstring>faxEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup1</cstring> + </property> + <property name="title"> + <string>Company Location Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel8</cstring> + </property> + <property name="text"> + <string>Homepage:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Address:</string> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Zip:</string> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>State:</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>City:</string> + </property> + </widget> + <widget class="QLabel" row="6" column="0"> + <property name="name"> + <cstring>textLabel9</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Country:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>companyEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>homepageEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1"> + <property name="name"> + <cstring>addressEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="3" column="1"> + <property name="name"> + <cstring>cityEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="4" column="1"> + <property name="name"> + <cstring>stateEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="5" column="1"> + <property name="name"> + <cstring>zipEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLineEdit" row="6" column="1"> + <property name="name"> + <cstring>countryEdit</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + <spacer> + <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>70</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/kopete/protocols/oscar/icq/x-icq.desktop b/kopete/protocols/oscar/icq/x-icq.desktop new file mode 100644 index 00000000..1d8b3eb2 --- /dev/null +++ b/kopete/protocols/oscar/icq/x-icq.desktop @@ -0,0 +1,60 @@ +[Desktop Entry] +Comment=ICQ Contact +Comment[ar]=جهة اتصال على ICQ +Comment[be]=ICQ +Comment[bg]=Връзка с ICQ Contact +Comment[bn]=আই-সি-কিউ যোগাযোগ +Comment[br]=Darempred ICQ +Comment[bs]=ICQ kontakt +Comment[ca]=Contacte ICQ +Comment[cs]=ICQ kontakt +Comment[cy]=Cysylltiad ICQ +Comment[da]=ICQ-Kontakt +Comment[de]=ICQ-Kontakt +Comment[el]=Επαφή ICQ +Comment[eo]=ICQ-kontakto +Comment[es]=Contacto de ICQ +Comment[et]=ICQ kontakt +Comment[eu]=ICQ kontaktua +Comment[fa]=تماس ICQ +Comment[fi]=ICQ-kontakti +Comment[fr]=Contact ICQ +Comment[gl]=Contacto ICQ +Comment[he]=איש-קשר ICQ +Comment[hi]=आईसीक्यू सम्पर्क +Comment[hr]=ICQ kontakt +Comment[hu]=ICQ-kapcsolat +Comment[is]=ICQ tengiliður +Comment[it]=Contatto ICQ +Comment[ja]=ICQ コンタクト +Comment[ka]=ICQ მეგობარი +Comment[kk]=ICQ байланыс +Comment[km]=ទំនាក់ទំនង ICQ +Comment[lt]=ICQ kontaktas +Comment[mk]=Контакт на ICQ +Comment[nb]=ICQ kontakt +Comment[nds]=ICQ-Kontakt +Comment[ne]=आईसीक्यू सम्पर्क +Comment[nl]=ICQ contact +Comment[nn]=ICQ-kontakt +Comment[pl]=Kontakt ICQ +Comment[pt]=Contacto de ICQ +Comment[pt_BR]=Contato ICQ +Comment[ru]=Контакт ICQ +Comment[se]=ICQ-oktavuohta +Comment[sk]=Kontakt ICQ +Comment[sl]=Stik ICQ +Comment[sr]=ICQ контакт +Comment[sr@Latn]=ICQ kontakt +Comment[sv]=ICQ-kontakt +Comment[ta]=ICQ தொடர்பு +Comment[tg]=Пайвастшавии ICQ +Comment[tr]=ICQ Bağlantısı +Comment[uk]=Контакт ICQ +Comment[zh_CN]=ICQ 联系人 +Comment[zh_HK]=ICQ 聯絡人 +Comment[zh_TW]=ICQ 聯絡人 +Type=MimeType +MimeType=application/x-icq +Patterns=*.uin;*.icq +Icon=licq |