summaryrefslogtreecommitdiffstats
path: root/interfaces/kimproxy
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /interfaces/kimproxy
downloadtdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz
tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'interfaces/kimproxy')
-rw-r--r--interfaces/kimproxy/Makefile.am1
-rw-r--r--interfaces/kimproxy/TODO10
-rw-r--r--interfaces/kimproxy/interface/Makefile.am13
-rw-r--r--interfaces/kimproxy/interface/dcopinstantmessenger.desktop72
-rw-r--r--interfaces/kimproxy/interface/kcm_instantmessenger.desktop138
-rw-r--r--interfaces/kimproxy/interface/kimiface.h500
-rw-r--r--interfaces/kimproxy/library/Makefile.am26
-rw-r--r--interfaces/kimproxy/library/icons/Makefile.am1
-rw-r--r--interfaces/kimproxy/library/icons/cr16-action-presence_away.pngbin0 -> 852 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr16-action-presence_offline.pngbin0 -> 549 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr16-action-presence_online.pngbin0 -> 922 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr16-action-presence_unknown.pngbin0 -> 822 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr32-action-presence_away.pngbin0 -> 2402 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr32-action-presence_offline.pngbin0 -> 1407 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr32-action-presence_online.pngbin0 -> 2547 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr32-action-presence_unknown.pngbin0 -> 2483 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr48-action-presence_away.pngbin0 -> 3328 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr48-action-presence_offline.pngbin0 -> 1717 bytes
-rw-r--r--interfaces/kimproxy/library/icons/cr48-action-presence_online.pngbin0 -> 3370 bytes
-rw-r--r--interfaces/kimproxy/library/kimproxy.cpp653
-rw-r--r--interfaces/kimproxy/library/kimproxy.h654
-rw-r--r--interfaces/kimproxy/library/kimproxyiface.h38
22 files changed, 2106 insertions, 0 deletions
diff --git a/interfaces/kimproxy/Makefile.am b/interfaces/kimproxy/Makefile.am
new file mode 100644
index 000000000..105f84291
--- /dev/null
+++ b/interfaces/kimproxy/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = interface library \ No newline at end of file
diff --git a/interfaces/kimproxy/TODO b/interfaces/kimproxy/TODO
new file mode 100644
index 000000000..fc66130fe
--- /dev/null
+++ b/interfaces/kimproxy/TODO
@@ -0,0 +1,10 @@
+For the future, the following modifications need to be done:
+
+Currently there is a function :
+ virtual QString presenceString( const QString & uid ) = 0;
+This needs to be broken into:
+ virtual QString presenceString( const QString & uid ) = 0;
+ virtual QString presenceLongString( const QString & uid ) = 0;
+
+The former returning, say "Away", the latter returning the long away
+message.
diff --git a/interfaces/kimproxy/interface/Makefile.am b/interfaces/kimproxy/interface/Makefile.am
new file mode 100644
index 000000000..348130e46
--- /dev/null
+++ b/interfaces/kimproxy/interface/Makefile.am
@@ -0,0 +1,13 @@
+INCLUDES = $(all_includes)
+
+kimifaceinclude_HEADERS = kimiface.h
+kimifaceincludedir = $(includedir)
+
+servicetypedir = $(kde_servicetypesdir)
+servicetype_DATA = dcopinstantmessenger.desktop
+
+kcm_instantmessenger_DATA = kcm_instantmessenger.desktop
+kcm_instantmessengerdir = $(kde_datadir)/kcm_componentchooser
+
+include $(top_srcdir)/admin/Doxyfile.am
+DOXYGEN_REFERENCES = kabc
diff --git a/interfaces/kimproxy/interface/dcopinstantmessenger.desktop b/interfaces/kimproxy/interface/dcopinstantmessenger.desktop
new file mode 100644
index 000000000..406c4e979
--- /dev/null
+++ b/interfaces/kimproxy/interface/dcopinstantmessenger.desktop
@@ -0,0 +1,72 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=DCOP/InstantMessenger
+Comment=Instant Messenger with a DCOP interface
+Comment[af]=Oombliklike Boodskapper met DCOP intervlak
+Comment[be]=Імгненны абвестнік з інтэрфэйсам DCOP
+Comment[bg]=Програма за съобщения в реално време с интерфейс DCOP
+Comment[bn]=ডিকপ (DCOP) ইন্টারফেস সহ ইনস্ট্যান্ট মেসেঞ্জার
+Comment[bs]=Instant poruke sa DCOP interfejsom
+Comment[ca]=Missatgeria instantània amb una interfície DCOP
+Comment[cs]=Komunikátor s DCOP rozhraním
+Comment[csb]=Internetowi kòmùnikator z interfejsã DCOP
+Comment[cy]=Negesydd Chwim efo rhyngwyneb DCOP
+Comment[da]=Instant Messenger med en DCOP-grænseflade
+Comment[de]=Instant Messenger mit DCOP-Schnittstelle
+Comment[el]=Στιγμιαίος αποστολέας με διασύνδεση DCOP
+Comment[eo]=Tujmesaĝilo kun DCOP-interfaco
+Comment[es]=Instant Messenger con un interfaz DCOP
+Comment[et]=Kiirsuhtlemisrakendus DCOP-liidesega
+Comment[eu]=Berehalako mezularitza DCOP interfazearekin
+Comment[fa]=پیام‌رسان فوری با یک واسط DCOP
+Comment[fi]=Pikaviestiohjelma, jossa on DCOP-rajapinta
+Comment[fr]=Messagerie instantanée munie d'une interface DCOP
+Comment[fy]=Instant Messenger mei in DCOP-interface
+Comment[ga]=Clár teachtaireachtaí meandaracha le comhéadan DCOP
+Comment[gl]=Mensaxeria Instantánea con interface DCOP
+Comment[he]=תכנת מסרים מידיים עם ממשק DCOP
+Comment[hi]=डीकॉप इंटरफेस सहित इंस्टैंट मैसेंजर
+Comment[hr]=Trenutne poruke s DCOP sučeljem
+Comment[hsb]=Instant Messenger z DCOP-interfejsom
+Comment[hu]=Azonnali üzenetküldő DCOP-felülettel
+Comment[id]=Instant Messenger dengan antarmuka DCOP
+Comment[is]=Spjallforrit með DCOP viðmóti
+Comment[it]=Messaggistica istantanea con un'interfaccia DCOP
+Comment[ja]=DCOP インターフェースをもつインスタントメッセンジャー
+Comment[ka]=DCOP ინტერფეისთან შეტყობინებების გაცვლის შიკრიკი
+Comment[kk]=DCOP интерфейсті жедел хабарласу бағдарламасы
+Comment[km]=​កម្មវិធី​ជជែក​កំសាន្ត​ដែល​មាន​ចំណុច​ប្រទាក់ DCOP
+Comment[lb]=Instant Messenger mat engem DCOP-Interface
+Comment[lt]=Momentinių žinučių klientas su DCOP sąsaja
+Comment[mk]=Инстант Гласник (Messenger) со DCOP интерфејс
+Comment[ms]=Utusan Segera dengan antaramuka DCOP
+Comment[nb]=Lynmeldingsprogram med DCOP-grensesnitt
+Comment[nds]=Kortnarichten-Maker mit DCOP-Koppelsteed
+Comment[ne]=DCOP इन्टरफेससँग आवश्यक मेसेन्जर
+Comment[nl]=Instant messenger met een DCOP interface
+Comment[nn]=Lynmeldingsprogram med DCOP-grensesnitt
+Comment[pa]=ਇੱਕ DCOP ਇੰਟਰਫੇਸ ਲਈ ਇੱਕ ਮੌਕਾ ਸੁਨੇਹਾਕਾਰ
+Comment[pl]=Komunikator internetowy z interfejsem DCOP
+Comment[pt]=Mensageiro Instantâneo com interface DCOP
+Comment[pt_BR]=Mensageiro Instantâneo com uma interface DCOP
+Comment[ro]=Aplicaţie de mesaje instantanee cu interfaţă DCOP
+Comment[ru]=Клиент обмена сообщениями с интерфейсом DCOP
+Comment[rw]=Intumwa y'Akokanya ifite imigaragarire DCOP
+Comment[se]=Šleađgadiehtoprográmma mas lea DCOP-lákta
+Comment[sk]=Instant Messanger s rozhraním DCOP
+Comment[sl]=Takojšni sporočilnik z vmesnikom DCOP
+Comment[sr]=Брзи гласник са DCOP интерфејсом
+Comment[sr@Latn]=Brzi glasnik sa DCOP interfejsom
+Comment[sv]=Direktmeddelanden med ett DCOP-gränssnitt
+Comment[ta]=உடனடி செய்தியாளர் DCOP இடைமுகத்தோடு
+Comment[te]=డిసిఓపి ఇంటర్ఫెస్ కలిగివున్న ఇంస్టెంట్ మెస్సెన్జర్
+Comment[tg]=Мубодилаи паёмҳо бо интерфейси DCOP
+Comment[th]=โปรแกรมส่งข้อความแบบทันที ด้วยส่วนติดต่อกับ DCOP
+Comment[tr]=DCOP arayüzüyle Anında Mesajlaşma
+Comment[tt]=DCOP protokolı belän Aşığıç Xäbärçe
+Comment[uk]=Програма для миттєвого зв'язку через DCOP
+Comment[vi]=Bộ tin nhắn tức khắc có giao diện DCOP
+Comment[wa]=Messaedjreye sol moumint avou ene eterface DCOP
+Comment[zh_CN]=带 DCOP 接口的即时通讯程序
+Comment[zh_HK]=附有 DCOP 介面的即時通訊軟件
+Comment[zh_TW]=DCOP 介面的即時通訊系統
diff --git a/interfaces/kimproxy/interface/kcm_instantmessenger.desktop b/interfaces/kimproxy/interface/kcm_instantmessenger.desktop
new file mode 100644
index 000000000..860f82944
--- /dev/null
+++ b/interfaces/kimproxy/interface/kcm_instantmessenger.desktop
@@ -0,0 +1,138 @@
+Name=Instant Messenger
+Name[af]=Oombliklike Boodskapper
+Name[be]=Імгненны абвеснік
+Name[bg]=Съобщения в реално време
+Name[bn]=ইনস্ট্যান্ট মেসেঞ্জার
+Name[br]=Posteler a-benn-kaer
+Name[bs]=Instant poruke
+Name[ca]=Missatgeria instantània
+Name[cs]=Komunikátor
+Name[csb]=Internetowi kòmùnikator
+Name[cy]=Negesydd Chwim
+Name[el]=Στιγμιαίος αποστολέας
+Name[eo]=Tujmesaĝilo
+Name[et]=Kiirsuhtlus
+Name[eu]=Berehalako mezularitza
+Name[fa]=پیام‌رسان فوری
+Name[fi]=Pikaviestiohjelma
+Name[fr]=Messagerie instantanée
+Name[ga]=Clár teachtaireachtaí meandaracha
+Name[gl]=Mensaxeria Instantánea
+Name[he]=מסרים מידיים
+Name[hi]=इंस्टैंट मैसेंजर
+Name[hu]=Azonnali üzenetküldő
+Name[is]=Spjallforrit
+Name[it]=Messaggistica istantanea
+Name[ja]=インスタントメッセンジャー
+Name[ka]=შიკრიკი
+Name[kk]=Жедел хабарласу
+Name[km]=កម្មវិធី​វិធីជជែក​កំសាន្ត
+Name[lt]=Momentinių žinučių klientas
+Name[mk]=Инстант Гласник (Messenger)
+Name[ms]=Mesej Segera
+Name[nb]=Lynmelding
+Name[nds]=Kortnarichten-Maker
+Name[ne]=आवश्यक मेसेन्जर
+Name[nl]=Instant messenger
+Name[nn]=Lynmelding
+Name[pa]=ਮੌਕਾ ਸੁਨੇਹਾਕਾਰ
+Name[pl]=Komunikator internetowy
+Name[pt]=Mensageiro Instantâneo
+Name[pt_BR]=Mensagem Instantâneo
+Name[ro]=Mesaje instantanee
+Name[ru]=Обмен сообщениями
+Name[se]=Šleađgadieđut
+Name[sl]=Takojšni sporočilnik
+Name[sr]=Брзи гласник
+Name[sr@Latn]=Brzi glasnik
+Name[sv]=Direktmeddelanden
+Name[ta]=உடனடி செய்தியாளர்
+Name[te]=ఇంస్టెంట్ మెస్సెన్జర్
+Name[tg]=Мубодилаи паёмҳо
+Name[th]=โปรแกรมส่งข้อความทันที
+Name[tr]=Anında Mesajlaşma
+Name[tt]=Aşığıç Xäbärçe
+Name[uk]=Програма для миттєвого зв'язку через DCOP
+Name[uz]=Xabar almashish vositasi
+Name[uz@cyrillic]=Хабар алмашиш воситаси
+Name[vi]=Bộ tin nhắn tức khắc
+Name[wa]=Messaedjreye sol moumint
+Name[zh_CN]=即时通讯程序
+Name[zh_HK]=即時通訊軟件
+Name[zh_TW]=即時通訊
+Comment=The instant messenger allows two-way chat between individuals and groups.
+Comment[af]=Die oombliklike boodskappe laat twee rigting kommunikasie tussen individue en groepe toe.
+Comment[be]=Імгненны абвеснік дазваляе весці размову двум і больш асобам/гуртам.
+Comment[bg]=Разговор между различни хора в реално време.
+Comment[bn]=ইনস্ট্যান্ট মেসেঞ্জার একাধিক ব্যক্তি বা গোষ্ঠীকে দ্বিমুখী বার্তালাপ বা আড্ডার সুযোগ দেয়।
+Comment[bs]=Program za instant poruke omogućuje dvosmjernu komunikaciju između pojedinaca i grupa.
+Comment[ca]=La missatgeria instantània permet converses en dos sentits entre individus i grups.
+Comment[cs]=Komunikátor vám umožňuje obousměrný rozhovor s jednotlivci nebo skupinami.
+Comment[csb]=Internetowi kòmùnikator dôwô mòżnota kôrbionczi midzë lëdzama ë karnama.
+Comment[cy]=Mae'r negesydd chwim yn caniatàu sgwrs dwy-ffordd rhwng unigolion a grwpiau.
+Comment[da]=Instant messenger tillader tovejs chat mellem individer og grupper.
+Comment[de]=Der Instant Messenger ermöglicht Chats zwischen Personen und Gruppen in jede Richtung.
+Comment[el]=Ο στιγμιαίος αποστολέας επιτρέπει τη συζήτηση μεταξύ ατόμων και ομάδων.
+Comment[eo]=La tujmesaĝilo ebligas ambaŭdirekta parolado inter homoj kaj grupoj
+Comment[es]=El Instant Messenger permite conversación en dos sentidos entre indivíduos y grupos.
+Comment[et]=Kiirsuhtlus võimaldab üksikisikute ja gruppide kahepoolset vestlust.
+Comment[eu]=Berehalako mezularitzak banan-banako edo taldeen arteko berriketan aritzeko.
+Comment[fa]=پیام‌رسان فوری امکان گپ دو طرفه بین افراد و گروهها را می‌دهد.
+Comment[fi]=Pikaviestiohjelman avulla voidaan keskustella kahden kesken tai ryhmässä.
+Comment[fr]=La messagerie instantanée permet un dialogue bidirectionnel entre individus et groupes.
+Comment[fy]=Mei de instant messenger kinne jo twaspraak hâlde mei in yndividu en groepen.
+Comment[ga]=Is féidir comhrá déthreoch a dhéanamh idir daoine agus grúpaí leis an gclár teachtaireachtaí meandaracha.
+Comment[gl]=O instant messenger permite conversas nos dous sentidos entre indivíduos e grupos.
+Comment[he]=תוכנת מסרים מידיים מאשרת לשוחח ברשת (לצ'טט) בין יחידים או קבוצות
+Comment[hi]=इंस्टैंट मैसेंजर जो व्यक्तियों या समूहों के बीच दो-तरफा गपशप स्वीकारता है.
+Comment[hr]=Trenutne poruke omogućuju dvosmjerno brbljanje između pojedinaca i grupa.
+Comment[hsb]=Instant messenger zmóžni jednotliwcam a skupinam spěšnu wuměnu zdźělenkow.
+Comment[hu]=Interaktív társalgást tesz lehetővé az interneten keresztül két személy vagy csoport között.
+Comment[id]=Instant messenger memungkinan chat dua-arah antara individu dan grup
+Comment[is]=Spjallforritið gerir einstaklingum og hópum kleyft að spjalla saman á einfaldan máta.
+Comment[it]=La messaggistica istantanea permette di chiacchierare tra due persone o in gruppo.
+Comment[ja]=インスタントメッセンジャーは個人とグループとの双方向チャットを可能にします。
+Comment[ka]=შიკრიკი პიროვნებებსა და ჯგუფებს შორის მყისი შეტყობინებების გაცვლის საშუალებას იძლევა.
+Comment[kk]=Жедел хабарласу жеке тұлға және топтар араларында әңгімелесу мүмкіндігін береді.
+Comment[km]=កម្មវិធី​ជជែក​កំសាន្ត​អនុញ្ញាត​ឲ្យ​ជជែក​តាម​របៀប​ពីរ​បែប​រវាង​បុគ្គល និង​ក្រុម ។
+Comment[lb]=Den Instant Messenger erlaabt eng zwee-Weeër Kommunikatioun tëschent eenzelne Persounen a Gruppen.
+Comment[lt]=Momentinių žinučių klientas kalbėtis individams ir grupėms.
+Comment[mk]=Инстант гласникот овозможува двонасочна комуникација меѓу индивидуи и групи.
+Comment[ms]=Utusan segera membenarkan perbualan di antara individu dan kumpulan.
+Comment[nb]=Et lynmeldingsprogram som tallater toveis samtale mellom enkeltpersoner og grupper.
+Comment[nds]=Mit den Kortnarichten-Maker köönt enkelte Minschen oder Gruppen ünnerenanner snacken.
+Comment[ne]= आवश्यक मेसेन्जरले एकल र समूहहरुबीच दोहोरो कुराकानीलाई अनुमति दिन्छ ।
+Comment[nl]=De instant messenger maakt directe communicatie tussen personen of groepen mogelijk.
+Comment[nn]=Eit lynmeldingsprogram som tillèt tovegsprat mellom enkeltpersonar og grupper.
+Comment[pa]=ਇਹ ਮੌਕਾ ਸੁਨੇਹਾਕਾਰ ਇੱਕਲੇ ਤੇ ਸਮੂਹ ਵਿਚਕਾਰ ਦੋ ਪਾਸੀ ਗਲਬਾਤ ਲਈ ਸਹਾਇਕ ਹੈ
+Comment[pl]=Komunikator internetowy umożliwia pogawędki między dwiema osobami lub grupami osób.
+Comment[pt]=O mensageiro instantâneo permite conversar entre dois extremos com indivíduos e com grupos.
+Comment[pt_BR]=O mensageiro instantâneo permite que exista um bate-papo entre indivíduos e grupos
+Comment[ro]=Aplicaţia de mesaje instantanee permite convorbiri între persoane sau grupuri de persoane.
+Comment[ru]=Клиент обмена сообщениями служит для обмена сообщениями между людьми и группами.
+Comment[rw]=Intumwa y'Akokanya yemerera inzira-zombi z'ikiganiroInterineti hagati y'abantu ubwabo n'amatsinda
+Comment[se]=Šleađgadiehtoprográmma gos olbmot ja joavkkut sáhttet buillardallat (chat).
+Comment[sk]=Instant messenger umožňuje rozhovor medzi rôznymi osobami a skupinami.
+Comment[sl]=Takojšni sporočilnik omogoča dvosmeren klepet med posamezniki in skupinami.
+Comment[sr]=Брзи гласник вам омогућава двосмерно ћаскање између појединаца и група.
+Comment[sr@Latn]=Brzi glasnik vam omogućava dvosmerno ćaskanje između pojedinaca i grupa.
+Comment[sv]=Direktmeddelanden möjliggör tvåvägschatt mellan individer och grupper.
+Comment[ta]=உடனடி தகவல் உங்களை இரண்டு வழியில் தனிநபர் மற்றும் குழுக்கள் இடையே அனுமதிக்கும்.
+Comment[te]=ఇంస్టెంట్ మెస్సెన్జర్ వ్యక్తు లు మరయు గుంపుల తొ ఇరువయపుల నుంచి సంబాషించవచ్చు
+Comment[tg]=Мубодилаи паёмҳо барои сӯҳбат бо шахсони ҷудогона ва гурӯҳӣ иҷозат медиҳад.
+Comment[th]=โปรแกรมส่งข้อความแบบทันที จะอนุญาตให้มีการพูดคุยสองทาง ทั้งระหว่าง บุคคลและกลุ่ม
+Comment[tr]=Anında mesajlaştırıcı iki yollu sohbet sağlar: bireyler ve gruplar.
+Comment[tt]=Bu aşığıç xäbärçe aşa keşe-törkemnär arasında ike-yaqlı aralaşu mömkinlegen birä.
+Comment[uk]=Програма для миттєвого зв'язку дозволяє розмовляти з іншою людиною чи групою людей.
+Comment[vi]=Bộ tin nhắn tức khắc cho phép trò chuyện hai chiều giữa người riêng và nhóm.
+Comment[wa]=Li messaedjreye sol moumint permete di berdeler dins les deus sinses etur deus djins ou e groupe.
+Comment[zh_CN]=允许在个人和群组之间双向聊天的即时通讯程序。
+Comment[zh_HK]=即時通訊軟件可以讓用戶和別的用戶或羣組通訊。
+Comment[zh_TW]=即時通訊系統允許兩個人或兩個群組間的聊天與對話
+ServiceTypeToConfigure=DCOP/InstantMessenger
+MimeTypeOfInterest=DCOP/InstantMessenger
+defaultImplementation=kopete
+storeInFile=default_components
+valueSection=InstantMessenger
+valueName=imClient
+configurationType=component
diff --git a/interfaces/kimproxy/interface/kimiface.h b/interfaces/kimproxy/interface/kimiface.h
new file mode 100644
index 000000000..4cc1d88b5
--- /dev/null
+++ b/interfaces/kimproxy/interface/kimiface.h
@@ -0,0 +1,500 @@
+/*
+ kimiface.h - KDE Instant Messenger DCOP Interface
+
+ Copyright (c) 2004-5 Will Stephenson <lists@stevello.free-online.co.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KIMIFACE_H
+#define KIMIFACE_H
+
+#include <qpixmap.h>
+#include <dcopobject.h>
+#include <qstringlist.h>
+#include <kurl.h>
+
+/**
+ * @brief Generic DCOP interface for KDE instant messenger applications
+ *
+ * The interface has two parts:
+ * - methods to get information about IM-contacts, such as their reachability
+ * or their presence status (if the are online or away, etc)
+ * - methods to initiate communication with IM-contacts, e.g. sending messages
+ *
+ * @note If you are looking for a information about accessing application's
+ * that implement this interface, have a look at the KIMProxy class.
+ *
+ * Contacts are identified using unique identifier strings (UID) used by
+ * KABC, the KDE address book library.
+ * The UID generation is handled by KABC::Addressee so the your application
+ * will either have to access the address book or provide a possibility
+ * for associating a contact of your application with an entry of the address
+ * book.
+ *
+ * @note one omission of this interface is the lack of control over the range
+ * of values used for protocols' names.
+ *
+ * If you are implementing this interface, note that your application must
+ * have the following information in its desktop file, so that it can be
+ * identified as providing KIMIface at runtime:
+ * @code
+ * X-DCOP-ServiceName=<application-name>
+ * ServiceTypes=DCOP/InstantMessenger
+ * @endcode
+ * and the class implementing KIMIface must pass "KIMIface" to the DCOPObject constructor:
+ * @code
+ * // just need QObject inheritance and Q_OBJECT if you want signals and slots
+ * // no need to use K_DCOP macro again
+ *
+ * class MyIMIface : public QObject, public KIMIface
+ * {
+ * Q_OBJECT
+ * public:
+ * MyIMIface(QObject* parent = 0, const char* name) :
+ * DCOPObject("KIMIface"), // <-- passing the interface name as required
+ * QObject(parent, name) {}
+ * };
+ * @endcode
+ *
+ * The DCOP part of the interface needs to be processed by the DCOP IDL
+ * compiler. The KDE autotools framework will do this automatically, all
+ * you have to do is add kimiface.skel and kimiface.stub to the
+ * @c SOURCES list in your @c Makefile.am
+ *
+ * @see KIMProxy
+ * @see KABC::AddressBook
+ * @see KABC::Addressee
+ *
+ * @since 3.3
+ * @author Will Stephenson <lists@stevello.free-online.co.uk>
+ */
+class KIMIface : virtual public DCOPObject
+{
+ K_DCOP
+
+k_dcop:
+// ACCESSORS
+// contact list
+ /**
+ * @brief Obtain a list of IM-contacts that are known to the application
+ *
+ * Return a list of KABC UIDs of all the contacts you have such IDs for.
+ *
+ * @return a list of KABC UIDs known to the application
+ *
+ * @see reachableContacts()
+ * @see onlineContacts()
+ * @see fileTransferContacts()
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QStringList allContacts() = 0;
+
+ /**
+ * @brief Obtain a list of IM-contacts that are currently reachable
+ *
+ * Return a list of KABC UIDs of the contacts that are reachable in the
+ * sense that you are connected to the IM-service they are
+ * associated with.
+ *
+ * For example if your application supports ICQ and AIM and the ICQ account is
+ * active but the AIM account isn't, return just the ICQ contacts.
+ *
+ * @return a list of KABC UIDs who can receive a message, even if offline
+ *
+ * @see allContacts()
+ * @see onlineContacts()
+ * @see fileTransferContacts()
+ * @see messageContact()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QStringList reachableContacts() = 0;
+
+ /**
+ * @brief Obtain a list of IM-contacts that are currently online
+ *
+ * Return a list of KABC UIDs of the contacts you have any presence
+ * information for that indicates that they are connected to the
+ * IM-service they are associated with.
+ *
+ * @return a list of KABC UIDs who are online with unspecified presence
+ *
+ * @see allContacts()
+ * @see reachableContacts()
+ * @see fileTransferContacts()
+ * @see messageContact()
+ * @see chatWithContact()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QStringList onlineContacts() = 0;
+
+ /**
+ * @brief Obtain a list of IM-contacts who may receive file transfers
+ *
+ * Return a list of KABC UIDs of the contacts that are capable of
+ * receiving file transfers based on the IM-service they are associated
+ * with, i.e. if it is technically able to provide this, on their online
+ * state, i.e. can likely not receive files while offline, and perhaps even
+ * information your application has additionally, e.g. a user config that
+ * tells you that the contact is behind a firewall.
+ *
+ * The simplest implementation is to return the same list as
+ * onlineContacts(), provided all the IM-services that are currently used
+ * support it.
+ *
+ * @return a list of KABC UIDs capable of file transfer
+ *
+ * @see allContacts()
+ * @see reachableContacts()
+ * @see onlineContacts()
+ * @see canReceiveFiles()
+ * @see sendFile()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QStringList fileTransferContacts() = 0;
+
+// individual
+ /**
+ * @brief Confirm if a given contact is known to the IM application
+ *
+ * Check if you can map the given KABC UID to one if the IM-contacts, e.g.
+ * the would be part of the list returned by allContacts()
+ *
+ * @param uid the KABC UID you are interested in
+ * @return whether the program knows of this KABC UID
+ *
+ * @see allContacts()
+ * @see presenceString()
+ * @see presenceStatus()
+ * @see KABC::Addressee::uid()
+ */
+ virtual bool isPresent( const QString & uid ) = 0;
+
+ /**
+ * @brief Obtain the IM app's idea of the contact's display name
+ *
+ * Useful if KABC lookups may be too slow. Should return whatever
+ * the application uses in its contact list or similar GUI, e.g.
+ * a nick name, a user configured name string, etc.
+ *
+ * @param uid the KABC UID you are interested in
+ * @return the corresponding display name or QString:null if the
+ * UID is unknown
+ *
+ * @see isPresent()
+ * @see presenceString()
+ * @see presenceStatus()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QString displayName( const QString & uid ) = 0;
+
+ /**
+ * @brief Obtain the IM presence as a i18ned string for the specified
+ * contact
+ *
+ * Return a translated string your application would use when displaying
+ * the contact's presence, e.g. i18n("Online"), i18n("Away")
+ *
+ * @param uid the KABC UID you want the presence for
+ * @return the i18ned string describing the contact's presence or
+ * QString::null if the UID is unknown
+ *
+ * @see isPresent()
+ * @see presenceStatus()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QString presenceString( const QString & uid ) = 0;
+
+ /**
+ * @brief Obtain the IM presence as a number for the specified contact
+ *
+ * Return one of the following values depending on the given contact's
+ * presence:
+ * - 0 - @c Unknown: for contacts where you can not use any of the other
+ * values
+ *
+ * - 1 - @c Offline: for contacts that are offline, i.e. not connected to
+ * their IM-service. If the application itself or the IM-service for the
+ * given contact is offline return @c Unknown instead
+ *
+ * - 2 - @c Connecting
+ *
+ * - 3 - @c Away: for contacts that are connected to their IM-service but
+ * not @c Online
+ *
+ * - 4 - @c Online
+ *
+ * @param uid the KABC UID you want the presence for
+ * @return a numeric representation of presence - currently one of
+ * 0 (Unknown), 1 (Offline), 2 (Connecting), 3 (Away), 4 (Online).
+ * Returns 0 if the given UID is unknown
+ *
+ * @see isPresent()
+ * @see presenceString()
+ * @see KABC::Addressee::uid()
+ */
+ virtual int presenceStatus( const QString & uid ) = 0;
+
+ /**
+ * @brief Indicate if a given contact can receive files
+ *
+ * @param uid the KABC UID you want to the file transfer capability for
+ * @return whether the specified contact can receive files
+ *
+ * @see fileTransferContacts()
+ * @see KABC::Addressee::uid()
+ */
+ virtual bool canReceiveFiles( const QString & uid ) = 0;
+
+ /**
+ * @brief Indicate if a given contact will be able to respond
+ *
+ * Some media are unidirectional (e.g., sending SMS via a web interface).
+ * This refers to the contact's ability to respond as defined by the
+ * medium, not by their presence.
+ *
+ * Someone may appear offline (SMS has no presence) to you but in fact be
+ * able to respond.
+ *
+ * @param uid the KABC UID you are interested in
+ * @return whether the specified contact can respond
+ *
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ virtual bool canRespond( const QString & uid ) = 0;
+
+ /**
+ * @brief Obtain the KABC UID corresponding to the given IM address
+ *
+ * @param contactId the protocol specific identifier for the contact,
+ * e.g. UIN for ICQ, screenname for AIM, nick for IRC
+ * @param protocol the IM protocol/service to check. See protocols()
+ * @return the KABC UID for the given contact or @c QString::null if not
+ * found or either input stream was empty or the protocol is not
+ * supported
+ *
+ * @see protocols()
+ * @see addContact()
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QString locate( const QString & contactId, const QString & protocol ) = 0;
+
+// metadata
+ /**
+ * @brief Obtain the icon representing the IM presence for the specified
+ * contact
+ *
+ * Return the image the application would use to display a contact's presence.
+ * The size and other properties of the image are currently unspecified.
+ *
+ * @param uid the KABC UID you want the presence icon for
+ * @return a pixmap representing the contact's presence or a null pixmap
+ * if the contact is unknown. See QPixmap::isNull()
+ *
+ * @see isPresent()
+ * @see presenceString()
+ * @see presenceStatus()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QPixmap icon( const QString & uid ) = 0;
+
+ /**
+ * @brief Obtain the given contact's current context (home, work, or any)
+ *
+ * Not all IM services/protocols support the concept of contexts. If the
+ * given UID maps to such a service, just return @c QString::null
+ *
+ * @param uid the KABC UID you want the context for
+ * @return a string describing the context, or @c QString::null if not
+ * supported or if the contact is unknown
+ *
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ virtual QString context( const QString & uid ) = 0;
+
+// App capabilities
+ /**
+ * @brief Obtain a list of supported IM services/protocols
+ *
+ * Protocol names are currently of the form "protocol name" + "Protocol"
+ * for example:
+ * - AIMProtocol: AOL instant messenger protocol
+ * - MSNProtocol: Microsoft messanger protocol
+ * - ICQProtocol: AOL (Mirabilis) ICQ protocol
+ * - ....
+ *
+ * The string is currently just an identifier to use with methods such as
+ * locate(), addContact() or messageNewContact()
+ *
+ * @return the set of protocols that the application supports
+ *
+ * @see locate()
+ * @see addContact()
+ * @see messageNewContact
+ */
+ virtual QStringList protocols() = 0;
+
+// ACTORS
+ /**
+ * @brief Send a single message to the specified contact
+ *
+ * Any response will be handled by the IM client as a normal
+ * conversation.
+ *
+ * Implementations might send the message silently, ask the user for
+ * permission or just prefill the usual message input GUI.
+ *
+ * @note As sending any text could potentially be a breach of the user's
+ * privacy it is recommended to let the user know about it.
+ *
+ * @param uid the KABC UID you want to send the message to
+ * @param message the message text to send to the contact
+ *
+ * @see messageNewContact()
+ * @see chatWithContact()
+ * @see sendFile()
+ * @see isPresent()
+ * @see reachableContacts()
+ * @see KABC::Addressee::uid()
+ */
+ virtual void messageContact( const QString &uid, const QString& message ) = 0;
+
+ /**
+ * @brief Send a single message to a contact given only its protocol
+ * specific identifier
+ *
+ * This could be used to send a message without having to know the KABC UID
+ * of the contact or without having to add it first.
+ *
+ * @param contactId the protocol specific identifier for the contact,
+ * e.g. UIN for ICQ, screenname for AIM, nick for IRC
+ * @param protocol the IM protocol/service to check. See protocols()
+ *
+ * @see messageContact()
+ * @see chatWithContact()
+ * @see sendFile()
+ * @see locate()
+ * @see protocols()
+ * @see addContact()
+ */
+ virtual void messageNewContact( const QString &contactId, const QString &protocol ) = 0;
+
+ /**
+ * @brief Start a chat session with the specified contact
+ *
+ * Applications that do not support a chat mode or when the IM-service
+ * of the given contact does not support it, this can also open
+ * a normal message input GUI.
+ *
+ * @param uid the KABC UID you want to chat with
+ *
+ * @see messageContact()
+ * @see messageNewContact()
+ * @see sendFile()
+ * @see isPresent()
+ * @see reachableContacts()
+ * @see KABC::Addressee::uid()
+ */
+ virtual void chatWithContact( const QString &uid ) = 0;
+
+ /**
+ * @brief Send a file to the contact
+ *
+ * Initiates a file transfer with the given contact if possible.
+ *
+ * Implementations might start the transfer right away, ask the user's
+ * permission or just prefill the usual file transfer GUI.
+ *
+ * @note As sending any file could potentially be a breach of the user's
+ * privacy it is recommended to let the user know about it.
+ *
+ * @param uid the KABC UID you want to send to
+ * @param sourceURL a KURL pointing to the file to send
+ * @param altFileName an alternate filename describing the file or a
+ * description or title
+ * @param fileSize file size in bytes
+ *
+ * @see messageContact()
+ * @see messageNewContact()
+ * @see chatWithContact()
+ * @see isPresent()
+ * @see fileTransferContacts()
+ * @see KABC::Addressee::uid()
+ */
+ virtual void sendFile(const QString &uid, const KURL &sourceURL,
+ const QString &altFileName = QString::null, uint fileSize = 0) = 0;
+
+// MUTATORS
+// Contact list
+ /**
+ * @brief Add a new contact given its protocol specific identifier
+ *
+ * Implementations might add the contact silently, including sending an
+ * authorization request if necessary, ask the user for confirmation or
+ * just prefill the usual contact addingGUI.
+ *
+ * @param contactId the protocol specific identifier for the contact
+ * e.g. UIN for ICQ, screenname for AIM, nick for IRC
+ * @param protocol the IM protocol/service to use. See protocols()
+ * @return whether the add succeeded. @c false may signal already present,
+ * protocol not supported, or add operation not supported.
+ *
+ * @see locate()
+ * @see protocols()
+ * @see messageNewContact()
+ */
+ virtual bool addContact( const QString &contactId, const QString &protocol ) = 0;
+
+// SIGNALS
+k_dcop_signals:
+ /**
+ * @brief Indicates that a contact's presence has changed
+ *
+ * Notifies connected DCOP receivers about a change in a contact's
+ * presence.
+ *
+ * Implementations just have to call this method with the appropriate
+ * values to get the DCOP signal emitted.
+ *
+ * @param uid the KABC UID whose presence changed
+ * @param appId the DCOP application ID of the program the signal
+ * originates from
+ * @param presence the new presence's numeric value. See presenceStatus()
+ *
+ * @see presenceStatus()
+ * @see KABC::Addressee::uid()
+ * @see DCOPClient::appId()
+ */
+ void contactPresenceChanged( QString uid, QCString appId, int presence );
+};
+
+#endif
+
+
+
+/*
+ * Local variables:
+ * c-indentation-style: k&r
+ * c-basic-offset: 8
+ * indent-tabs-mode: t
+ * End:
+ */
+// vim: set noet ts=4 sts=4 sw=4:
+
diff --git a/interfaces/kimproxy/library/Makefile.am b/interfaces/kimproxy/library/Makefile.am
new file mode 100644
index 000000000..36cb7ea30
--- /dev/null
+++ b/interfaces/kimproxy/library/Makefile.am
@@ -0,0 +1,26 @@
+SUBDIRS = icons
+
+INCLUDES = $(all_includes)
+
+noinst_HEADERS = kimproxyiface.h
+
+METASOURCES = AUTO
+
+AM_CPPFLAGS = $(all_includes)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kimproxy.pot
+
+kimproxyincludedir = $(includedir)
+kimproxyinclude_HEADERS = kimproxy.h kimproxyiface.h
+
+lib_LTLIBRARIES = libkimproxy.la
+libkimproxy_la_LDFLAGS = -no-undefined $(all_libraries)
+libkimproxy_la_LIBADD = $(LIB_KIO)
+libkimproxy_la_SOURCES = kimproxy.cpp kimiface.stub kimproxyiface.skel
+
+kimiface_DIR = $(top_srcdir)/interfaces/kimproxy/interface
+
+include $(top_srcdir)/admin/Doxyfile.am
+DOXYGEN_REFERENCES = kabc dcop
+
diff --git a/interfaces/kimproxy/library/icons/Makefile.am b/interfaces/kimproxy/library/icons/Makefile.am
new file mode 100644
index 000000000..a4b97f06a
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/Makefile.am
@@ -0,0 +1 @@
+KDE_ICON=AUTO
diff --git a/interfaces/kimproxy/library/icons/cr16-action-presence_away.png b/interfaces/kimproxy/library/icons/cr16-action-presence_away.png
new file mode 100644
index 000000000..f96a9c65f
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr16-action-presence_away.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr16-action-presence_offline.png b/interfaces/kimproxy/library/icons/cr16-action-presence_offline.png
new file mode 100644
index 000000000..f5c53d711
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr16-action-presence_offline.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr16-action-presence_online.png b/interfaces/kimproxy/library/icons/cr16-action-presence_online.png
new file mode 100644
index 000000000..6cb52496b
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr16-action-presence_online.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr16-action-presence_unknown.png b/interfaces/kimproxy/library/icons/cr16-action-presence_unknown.png
new file mode 100644
index 000000000..290bc852a
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr16-action-presence_unknown.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr32-action-presence_away.png b/interfaces/kimproxy/library/icons/cr32-action-presence_away.png
new file mode 100644
index 000000000..086184582
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr32-action-presence_away.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr32-action-presence_offline.png b/interfaces/kimproxy/library/icons/cr32-action-presence_offline.png
new file mode 100644
index 000000000..caadb14d4
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr32-action-presence_offline.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr32-action-presence_online.png b/interfaces/kimproxy/library/icons/cr32-action-presence_online.png
new file mode 100644
index 000000000..41e79ad9d
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr32-action-presence_online.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr32-action-presence_unknown.png b/interfaces/kimproxy/library/icons/cr32-action-presence_unknown.png
new file mode 100644
index 000000000..52ab79ed5
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr32-action-presence_unknown.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr48-action-presence_away.png b/interfaces/kimproxy/library/icons/cr48-action-presence_away.png
new file mode 100644
index 000000000..58e62c1d3
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr48-action-presence_away.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr48-action-presence_offline.png b/interfaces/kimproxy/library/icons/cr48-action-presence_offline.png
new file mode 100644
index 000000000..b69630f33
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr48-action-presence_offline.png
Binary files differ
diff --git a/interfaces/kimproxy/library/icons/cr48-action-presence_online.png b/interfaces/kimproxy/library/icons/cr48-action-presence_online.png
new file mode 100644
index 000000000..52fdad8f9
--- /dev/null
+++ b/interfaces/kimproxy/library/icons/cr48-action-presence_online.png
Binary files differ
diff --git a/interfaces/kimproxy/library/kimproxy.cpp b/interfaces/kimproxy/library/kimproxy.cpp
new file mode 100644
index 000000000..746c6da90
--- /dev/null
+++ b/interfaces/kimproxy/library/kimproxy.cpp
@@ -0,0 +1,653 @@
+/*
+ kimproxy.cpp
+
+ IM service library for KDE
+
+ Copyright (c) 2004 Will Stephenson <lists@stevello.free-online.co.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qglobal.h>
+#include <qpixmapcache.h>
+#include <dcopclient.h>
+#include <kapplication.h>
+#include <kdcopservicestarter.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <ksimpleconfig.h>
+#include <kiconloader.h>
+#include <kservice.h>
+#include <kservicetype.h>
+
+#include "kimiface_stub.h"
+
+#include "kimproxy.h"
+
+static KStaticDeleter<KIMProxy> _staticDeleter;
+
+KIMProxy * KIMProxy::s_instance = 0L;
+
+struct AppPresenceCurrent
+{
+ QCString appId;
+ int presence;
+};
+
+class ContactPresenceListCurrent : public QValueList<AppPresenceCurrent>
+{
+ public:
+ // return value indicates if the supplied parameter was better than any existing presence
+ bool update( const AppPresenceCurrent );
+ AppPresenceCurrent best();
+};
+
+
+struct KIMProxy::Private
+{
+ DCOPClient * dc;
+ // list of the strings in use by KIMIface
+ QStringList presence_strings;
+ // list of the icon names in use by KIMIface
+ QStringList presence_icons;
+ // map of presences
+ PresenceStringMap presence_map;
+};
+
+bool ContactPresenceListCurrent::update( AppPresenceCurrent ap )
+{
+ if ( isEmpty() )
+ {
+ append( ap );
+ return true;
+ }
+
+ bool bestChanged = false;
+ AppPresenceCurrent best;
+ best.presence = -1;
+ ContactPresenceListCurrent::iterator it = begin();
+ const ContactPresenceListCurrent::iterator itEnd = end();
+ ContactPresenceListCurrent::iterator existing = itEnd;
+
+ while ( it != itEnd )
+ {
+ if ( (*it).presence > best.presence )
+ best = (*it);
+ if ( (*it).appId == ap.appId )
+ existing = it;
+ ++it;
+ }
+
+ if ( ap.presence > best.presence ||
+ best.appId == ap.appId )
+ bestChanged = true;
+
+ if ( existing != itEnd )
+ {
+ remove( existing );
+ append( ap );
+ }
+ return bestChanged;
+}
+
+AppPresenceCurrent ContactPresenceListCurrent::best()
+{
+ AppPresenceCurrent best;
+ best.presence = -1;
+ ContactPresenceListCurrent::iterator it = begin();
+ const ContactPresenceListCurrent::iterator itEnd = end();
+ while ( it != itEnd )
+ {
+ if ( (*it).presence > best.presence )
+ best = (*it);
+ ++it;
+ }
+ // if it's still -1 here, we have no presence data, so we return Unknown
+ if ( best.presence == -1 )
+ best.presence = 0;
+ return best;
+}
+
+// int bestPresence( AppPresence* ap )
+// {
+// Q_ASSERT( ap );
+// AppPresence::const_iterator it;
+// it = ap->begin();
+// int best = 0; // unknown
+// if ( it != ap->end() )
+// {
+// best = it.data();
+// ++it;
+// for ( ; it != ap->end(); ++it )
+// {
+// if ( it.data() > best )
+// best = it.data();
+// }
+// }
+// return best;
+// }
+//
+// QCString bestAppId( AppPresence* ap )
+// {
+// Q_ASSERT( ap );
+// AppPresence::const_iterator it;
+// QCString bestAppId;
+// it = ap->begin();
+// if ( it != ap->end() )
+// {
+// int best = it.data();
+// bestAppId = it.key();
+// ++it;
+// for ( ; it != ap->end(); ++it )
+// {
+// if ( it.data() > best )
+// {
+// best = it.data();
+// bestAppId = it.key();
+// }
+// }
+// }
+// return bestAppId;
+// }
+
+KIMProxy * KIMProxy::instance( DCOPClient * client )
+{
+ if ( client )
+ {
+ if ( !s_instance )
+ _staticDeleter.setObject( s_instance, new KIMProxy( client ) );
+ return s_instance;
+ }
+ else
+ return 0L;
+}
+
+KIMProxy::KIMProxy( DCOPClient* dc ) : DCOPObject( "KIMProxyIface" ), QObject(), d( new Private )
+{
+ m_im_client_stubs.setAutoDelete( true );
+
+ d->dc = dc;
+ m_initialized = false;
+ connect( d->dc, SIGNAL( applicationRemoved( const QCString& ) ) , this, SLOT( unregisteredFromDCOP( const QCString& ) ) );
+ connect( d->dc, SIGNAL( applicationRegistered( const QCString& ) ) , this, SLOT( registeredToDCOP( const QCString& ) ) );
+ d->dc->setNotifications( true );
+
+ d->presence_strings.append( "Unknown" );
+ d->presence_strings.append( "Offline" );
+ d->presence_strings.append( "Connecting" );
+ d->presence_strings.append( "Away" );
+ d->presence_strings.append( "Online" );
+
+ d->presence_icons.append( "presence_unknown" );
+ d->presence_icons.append( "presence_offline" );
+ d->presence_icons.append( "presence_connecting" );
+ d->presence_icons.append( "presence_away" );
+ d->presence_icons.append( "presence_online" );
+
+ //QCString senderApp = "Kopete";
+ //QCString senderObjectId = "KIMIface";
+ QCString method = "contactPresenceChanged( QString, QCString, int )";
+ //QCString receiverObjectId = "KIMProxyIface";
+
+ // FIXME: make this work when the sender object id is set to KIMIFace
+ if ( !connectDCOPSignal( 0, 0, method, method, false ) )
+ KMessageBox::information( 0, QString( "Couldn't connect DCOP signal.\nWon't receive any status notifications!" ) );
+}
+
+KIMProxy::~KIMProxy( )
+{
+ //d->dc->setNotifications( false );
+}
+
+bool KIMProxy::initialize()
+{
+ if ( !m_initialized )
+ {
+ m_initialized = true; // we should only do this once, as registeredToDCOP() will catch any new starts
+ // So there is no error from a failed query when using kdelibs 3.2, which don't have this servicetype
+ if ( KServiceType::serviceType( IM_SERVICE_TYPE ) )
+ {
+ //kdDebug( 790 ) << k_funcinfo << endl;
+ QCString dcopObjectId = "KIMIface";
+
+ // see what apps implementing our service type are out there
+ KService::List offers = KServiceType::offers( IM_SERVICE_TYPE );
+ KService::List::iterator offer;
+ typedef QValueList<QCString> QCStringList;
+ QCStringList registeredApps = d->dc->registeredApplications();
+ QCStringList::iterator app;
+ const QCStringList::iterator end = registeredApps.end();
+ // for each registered app
+ for ( app = registeredApps.begin(); app != end; ++app )
+ {
+ //kdDebug( 790 ) << " considering: " << *app << endl;
+ //for each offer
+ for ( offer = offers.begin(); offer != offers.end(); ++offer )
+ {
+ QCString dcopService = (*offer)->property("X-DCOP-ServiceName").toString().latin1();
+ if ( !dcopService.isEmpty() )
+ {
+ //kdDebug( 790 ) << " is it: " << dcopService << "?" << endl;
+ // get the application name ( minus any process ID )
+ QCString instanceName = (*app).left( dcopService.length() );
+ // if the application implements the dcop service, add it
+ if ( instanceName == dcopService )
+ {
+ m_apps_available = true;
+ //kdDebug( 790 ) << " app name: " << (*offer)->name() << ", has instance " << *app << ", dcopService: " << dcopService << endl;
+ if ( !m_im_client_stubs.find( dcopService ) )
+ {
+ kdDebug( 790 ) << "App " << *app << ", dcopObjectId " << dcopObjectId << " found, using it for presence info." << endl;
+ m_im_client_stubs.insert( *app, new KIMIface_stub( d->dc, *app, dcopObjectId ) );
+ pollApp( *app );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return !m_im_client_stubs.isEmpty();
+}
+
+void KIMProxy::registeredToDCOP( const QCString& appId )
+{
+ //kdDebug( 790 ) << k_funcinfo << " appId '" << appId << "'" << endl;
+ // check that appId implements our service
+ // if the appId ends with a number, i.e. a pid like in foobar-12345,
+ if ( appId.isEmpty() )
+ return;
+
+ bool newApp = false;
+ // get an up to date list of offers in case a new app was installed
+ // and check each of the offers that implement the service type we're looking for,
+ // to see if any of them are the app that just registered
+ const KService::List offers = KServiceType::offers( IM_SERVICE_TYPE );
+ KService::List::const_iterator it;
+ for ( it = offers.begin(); it != offers.end(); ++it )
+ {
+ QCString dcopObjectId = "KIMIface";
+ QCString dcopService = (*it)->property("X-DCOP-ServiceName").toString().latin1();
+ if ( appId.left( dcopService.length() ) == dcopService )
+ {
+ // if it's not already known, insert it
+ if ( !m_im_client_stubs.find( appId ) )
+ {
+ newApp = true;
+ kdDebug( 790 ) << "App: " << appId << ", dcopService: " << dcopService << " started, using it for presence info."<< endl;
+ m_im_client_stubs.insert( appId, new KIMIface_stub( d->dc, appId, dcopObjectId ) );
+ }
+ }
+ //else
+ // kdDebug( 790 ) << "App doesn't implement our ServiceType" << endl;
+ }
+ //if ( newApp )
+ // emit sigPresenceInfoExpired();
+}
+
+void KIMProxy::unregisteredFromDCOP( const QCString& appId )
+{
+ //kdDebug( 790 ) << k_funcinfo << appId << endl;
+ if ( m_im_client_stubs.find( appId ) )
+ {
+ kdDebug( 790 ) << appId << " quit, removing its presence info." << endl;
+
+ PresenceStringMap::Iterator it = d->presence_map.begin();
+ const PresenceStringMap::Iterator end = d->presence_map.end();
+ for ( ; it != end; ++it )
+ {
+ ContactPresenceListCurrent list = it.data();
+ ContactPresenceListCurrent::iterator cpIt = list.begin();
+ while( cpIt != list.end() )
+ {
+ ContactPresenceListCurrent::iterator gone = cpIt++;
+ if ( (*gone).appId == appId )
+ {
+ list.remove( gone );
+ }
+ }
+ }
+ m_im_client_stubs.remove( appId );
+ emit sigPresenceInfoExpired();
+ }
+}
+
+void KIMProxy::contactPresenceChanged( QString uid, QCString appId, int presence )
+{
+ // update the presence map
+ //kdDebug( 790 ) << k_funcinfo << "uid: " << uid << " appId: " << appId << " presence " << presence << endl;
+ ContactPresenceListCurrent current;
+ current = d->presence_map[ uid ];
+ //kdDebug( 790 ) << "current best presence from : " << current.best().appId << " is: " << current.best().presence << endl;
+ AppPresenceCurrent newPresence;
+ newPresence.appId = appId;
+ newPresence.presence = presence;
+
+ if ( current.update( newPresence ) )
+ {
+ d->presence_map.insert( uid, current );
+ emit sigContactPresenceChanged( uid );
+ }
+}
+
+int KIMProxy::presenceNumeric( const QString& uid )
+{
+ AppPresenceCurrent ap;
+ ap.presence = 0;
+ if ( initialize() )
+ {
+ ContactPresenceListCurrent presence = d->presence_map[ uid ];
+ ap = presence.best();
+ }
+ return ap.presence;
+}
+
+QString KIMProxy::presenceString( const QString& uid )
+{
+ AppPresenceCurrent ap;
+ ap.presence = 0;
+ if ( initialize() )
+ {
+ ContactPresenceListCurrent presence = d->presence_map[ uid ];
+ ap = presence.best();
+ }
+ if ( ap.appId.isEmpty() )
+ return QString::null;
+ else
+ return d->presence_strings[ ap.presence ];
+}
+
+QPixmap KIMProxy::presenceIcon( const QString& uid )
+{
+ AppPresenceCurrent ap;
+ ap.presence = 0;
+ if ( initialize() )
+ {
+ ContactPresenceListCurrent presence = d->presence_map[ uid ];
+ ap = presence.best();
+ }
+ if ( ap.appId.isEmpty() )
+ {
+ //kdDebug( 790 ) << k_funcinfo << "returning a null QPixmap because we were asked for an icon for a uid we know nothing about" << endl;
+ return QPixmap();
+ }
+ else
+ {
+ //kdDebug( 790 ) << k_funcinfo << "returning this: " << d->presence_icons[ ap.presence ] << endl;
+ return SmallIcon( d->presence_icons[ ap.presence ]);
+ }
+}
+
+QStringList KIMProxy::allContacts()
+{
+ QStringList value = d->presence_map.keys();
+ return value;
+}
+
+QStringList KIMProxy::reachableContacts()
+{
+ QStringList value;
+
+ if ( initialize() )
+ {
+ QDictIterator<KIMIface_stub> it( m_im_client_stubs );
+ for ( ; it.current(); ++it )
+ {
+ value += it.current()->reachableContacts( );
+ }
+ }
+ return value;
+}
+
+QStringList KIMProxy::onlineContacts()
+{
+ QStringList value;
+ PresenceStringMap::iterator it = d->presence_map.begin();
+ const PresenceStringMap::iterator end= d->presence_map.end();
+ for ( ; it != end; ++it )
+ if ( it.data().best().presence > 2 /*Better than Connecting, ie Away or Online*/ )
+ value.append( it.key() );
+
+ return value;
+}
+
+QStringList KIMProxy::fileTransferContacts()
+{
+ QStringList value;
+
+ if ( initialize() )
+ {
+ QDictIterator<KIMIface_stub> it( m_im_client_stubs );
+ for ( ; it.current(); ++it )
+ {
+ value += it.current()->fileTransferContacts( );
+ }
+ }
+ return value;
+}
+
+bool KIMProxy::isPresent( const QString& uid )
+{
+ return ( !d->presence_map[ uid ].isEmpty() );
+}
+
+QString KIMProxy::displayName( const QString& uid )
+{
+ QString name;
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForUid( uid ) )
+ name = s->displayName( uid );
+ }
+ //kdDebug( 790 ) << k_funcinfo << name << endl;
+ return name;
+}
+
+bool KIMProxy::canReceiveFiles( const QString & uid )
+{
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForUid( uid ) )
+ return s->canReceiveFiles( uid );
+ }
+ return false;
+}
+
+bool KIMProxy::canRespond( const QString & uid )
+{
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForUid( uid ) )
+ return s->canRespond( uid );
+ }
+ return false;
+}
+
+QString KIMProxy::context( const QString & uid )
+{
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForUid( uid ) )
+ return s->context( uid );
+ }
+ return QString::null;
+}
+
+void KIMProxy::chatWithContact( const QString& uid )
+{
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForUid( uid ) )
+ {
+ kapp->updateRemoteUserTimestamp( s->app() );
+ s->chatWithContact( uid );
+ }
+ }
+ return;
+}
+
+void KIMProxy::messageContact( const QString& uid, const QString& message )
+{
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForUid( uid ) )
+ {
+ kapp->updateRemoteUserTimestamp( s->app() );
+ s->messageContact( uid, message );
+ }
+ }
+ return;
+}
+
+void KIMProxy::sendFile(const QString &uid, const KURL &sourceURL, const QString &altFileName, uint fileSize )
+{
+ if ( initialize() )
+ {
+ QDictIterator<KIMIface_stub> it( m_im_client_stubs );
+ for ( ; it.current(); ++it )
+ {
+ if ( it.current()->canReceiveFiles( uid ) )
+ {
+ kapp->updateRemoteUserTimestamp( it.current()->app() );
+ it.current()->sendFile( uid, sourceURL, altFileName, fileSize );
+ break;
+ }
+ }
+ }
+ return;
+}
+
+bool KIMProxy::addContact( const QString &contactId, const QString &protocol )
+{
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForProtocol( protocol ) )
+ return s->addContact( contactId, protocol );
+ }
+ return false;
+}
+
+QString KIMProxy::locate( const QString & contactId, const QString & protocol )
+{
+ if ( initialize() )
+ {
+ if ( KIMIface_stub* s = stubForProtocol( protocol ) )
+ return s->locate( contactId, protocol );
+ }
+ return QString::null;
+}
+
+bool KIMProxy::imAppsAvailable()
+{
+ return ( !m_im_client_stubs.isEmpty() );
+}
+
+bool KIMProxy::startPreferredApp()
+{
+ QString preferences = QString("[X-DCOP-ServiceName] = '%1'").arg( preferredApp() );
+ // start/find an instance of DCOP/InstantMessenger
+ QString error;
+ QCString dcopService;
+ // Get a preferred IM client.
+ // The app will notify itself to us using registeredToDCOP, so we don't need to record a stub for it here
+ // FIXME: error in preferences, see debug output
+ preferences = QString::null;
+ int result = KDCOPServiceStarter::self()->findServiceFor( IM_SERVICE_TYPE, QString::null, preferences, &error, &dcopService );
+
+ kdDebug( 790 ) << k_funcinfo << "error was: " << error << ", dcopService: " << dcopService << endl;
+
+ return ( result == 0 );
+}
+
+
+void KIMProxy::pollAll( const QString &uid )
+{
+/* // We only need to call this function if we don't have any data at all
+ // otherwise, the data will be kept fresh by received presence change
+ // DCOP signals
+ if ( !d->presence_map.contains( uid ) )
+ {
+ AppPresence *presence = new AppPresence();
+ // record current presence from known clients
+ QDictIterator<KIMIface_stub> it( m_im_client_stubs );
+ for ( ; it.current(); ++it )
+ {
+ presence->insert( it.currentKey().ascii(), it.current()->presenceStatus( uid ) ); // m_im_client_stubs has qstring keys...
+ }
+ d->presence_map.insert( uid, presence );
+ }*/
+}
+
+void KIMProxy::pollApp( const QCString & appId )
+{
+ //kdDebug( 790 ) << k_funcinfo << endl;
+ KIMIface_stub * appStub = m_im_client_stubs[ appId ];
+ QStringList contacts = m_im_client_stubs[ appId ]->allContacts();
+ QStringList::iterator it = contacts.begin();
+ QStringList::iterator end = contacts.end();
+ for ( ; it != end; ++it )
+ {
+ ContactPresenceListCurrent current = d->presence_map[ *it ];
+ AppPresenceCurrent ap;
+ ap.appId = appId;
+ ap.presence = appStub->presenceStatus( *it );
+ current.append( ap );
+
+ d->presence_map.insert( *it, current );
+ if ( current.update( ap ) )
+ emit sigContactPresenceChanged( *it );
+ //kdDebug( 790 ) << " uid: " << *it << " presence: " << ap.presence << endl;
+ }
+}
+
+KIMIface_stub * KIMProxy::stubForUid( const QString &uid )
+{
+ // get best appPresence
+ AppPresenceCurrent ap = d->presence_map[ uid ].best();
+ // look up the presence string from that app
+ return m_im_client_stubs.find( ap.appId );
+}
+
+KIMIface_stub * KIMProxy::stubForProtocol( const QString &protocol)
+{
+ KIMIface_stub * app;
+ // see if the preferred client supports this protocol
+ QString preferred = preferredApp();
+ if ( ( app = m_im_client_stubs.find( preferred ) ) )
+ {
+ if ( app->protocols().grep( protocol ).count() > 0 )
+ return app;
+ }
+ // preferred doesn't do this protocol, try the first of the others that says it does
+ QDictIterator<KIMIface_stub> it( m_im_client_stubs );
+ for ( ; it.current(); ++it )
+ {
+ if ( it.current()->protocols().grep( protocol ).count() > 0 )
+ return it.current();
+ }
+ return 0L;
+}
+
+QString KIMProxy::preferredApp()
+{
+ KConfig *store = new KSimpleConfig( IM_CLIENT_PREFERENCES_FILE );
+ store->setGroup( IM_CLIENT_PREFERENCES_SECTION );
+ QString preferredApp = store->readEntry( IM_CLIENT_PREFERENCES_ENTRY );
+ //kdDebug( 790 ) << k_funcinfo << "found preferred app: " << preferredApp << endl;
+ return preferredApp;
+}
+
+#include "kimproxy.moc"
diff --git a/interfaces/kimproxy/library/kimproxy.h b/interfaces/kimproxy/library/kimproxy.h
new file mode 100644
index 000000000..6f56a0f13
--- /dev/null
+++ b/interfaces/kimproxy/library/kimproxy.h
@@ -0,0 +1,654 @@
+/*
+ kimproxy.h
+
+ IM service library for KDE
+
+ Copyright (c) 2004 Will Stephenson <lists@stevello.free-online.co.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KIMPROXY_H
+#define KIMPROXY_H
+
+#include <qdict.h>
+#include <qmap.h>
+#include <qptrdict.h>
+#include <qstringlist.h>
+
+
+#define IM_SERVICE_TYPE "DCOP/InstantMessenger"
+#define IM_CLIENT_PREFERENCES_FILE "default_components"
+#define IM_CLIENT_PREFERENCES_SECTION "InstantMessenger"
+#define IM_CLIENT_PREFERENCES_ENTRY "imClient"
+
+#include "kimproxyiface.h"
+
+class DCOPClient;
+class KIMIface_stub;
+class KURL;
+class ContactPresenceListCurrent;
+
+/** FIXME: remove for KDE4, binary compability again. */
+typedef QMap<QCString, int> AppPresence; // appId->presence; contains all applications' ideas of a user's presence
+typedef QDict<AppPresence> PresenceMap; // uid->AppPresence; contains a AppPresences for all users
+/** FIXME: remove presenceMap and call this presenceMap in KDE4. This hack is for binary compatibility */
+typedef QMap<QString, ContactPresenceListCurrent> PresenceStringMap;
+
+/**
+ * @brief Provides access to instant messenger programs which implement KDE's
+ * instant messanger interface KIMIface
+ *
+ * This class provides an easy-to-use interface to all running instant
+ * messengers or chat programs that implement KIMIface.
+ *
+ * It works simultaneously with any running programs that implement the
+ * ServiceType @c DCOP/InstantMessenger.
+ *
+ * IM-contacts are identified using unique identifier strings (UID) used by
+ * KDE's address book framework KABC.
+ * However the use of the address book API is optional, KIMProxy provides
+ * methods to fetch lists of available contact UIDs from the applications.
+ * If a UID is reachable with more than one program, KIMProxy aggregates the
+ * available information and presents the 'best' presence. For example, for a
+ * contact who can be seen to be @c Away in @c IRC on program A but @c Online
+ * using @c ICQ on program B, the information from program B will be used.
+ *
+ * KIMProxy is designed for simple information in a wide number of cases, not
+ * for detailed messaging.
+ *
+ * The class is implemented as a singleton, so whenever you need access to
+ * one of its methods, just retrieve the single instance using instance().
+ * The following code snippet demonstrated how to send a message to all
+ * reachable IM-contacts:
+ * @code
+ * // get proxy instance
+ * KIMProxy* proxy = KIMProxy::instance();
+ *
+ * // check if there are suitable applications reachable
+ * if (!proxy->initialize()) return;
+ *
+ * QString message = "Hi!\nHow are you on this wonderful day?";
+ *
+ * // iterate over the list of reachable contacts
+ * QStringList reachableContacts = proxy->reachableContacts();
+ * for (QStringList::const_iterator it = reachableContacts.begin();
+ * it != reachableContacts.end(); ++it)
+ * {
+ proxy->messageContact(*it, message);
+ * }
+ * @endcode
+ *
+ * @note While it is possible to communicate with each of those application's
+ * by DCOP using KIMProxy has the advantage of communicating with all
+ * applications simultaneously and thus getting an augmented view of
+ * availability, capability and presence (online status) of IM-contacts.
+ *
+ * @see KIMIface
+ * @see KABC::AddressBook
+ * @see KABC::Addressee
+ *
+ * @since 3.3
+ * @author Will Stephenson <lists@stevello.free-online.co.uk>
+ */
+class KIMPROXY_EXPORT KIMProxy : public QObject, virtual public KIMProxyIface
+{
+ Q_OBJECT
+ struct Private;
+
+ template<class> friend class KStaticDeleter;
+ ~KIMProxy();
+
+ public:
+ /**
+ * @brief Obtain an instance of KIMProxy
+ *
+ * Creates a new instance if it is called for the first time.
+ * Call initialize() to check if there are applications available for
+ * communication.
+ *
+ * @note KIMProxy uses DCOPClient::setNotifications() to make sure
+ * it updates its information about IM applications it interacts with,
+ * e.g. that it gets notified about newly available applications or
+ * about applications exiting
+ *
+ * @param client your application's DCOP client
+ * @return the singleton instance of this class
+ */
+ static KIMProxy * instance( DCOPClient * client );
+
+ /**
+ * @brief Get the proxy ready to connect
+ *
+ * Discover any running IM clients and setup communication handlers for
+ * them. The list of available clients is updated automatically
+ * through notification about added or removed DCOP applications as
+ * provided by DCOPClient.
+ *
+ * It is safe to call this method more than once, initialization only
+ * occurs at the first time.
+ *
+ * @return whether the proxy is ready to use.
+ * @c false if there are no suitable apps running
+ */
+ bool initialize();
+
+ /**
+ * @brief Obtain a list of IM-contacts known to IM-applications
+ *
+ * Returns a list of KABC UIDs gathered by merging the lists of
+ * each application the proxy can communicate with.
+ * The method uses cached information to make it fast and not
+ * require actually communicating with the applications every time
+ * it is called.
+ *
+ * @return a list of KABC UIDs known to any IM-application
+ *
+ * @see reachableContacts()
+ * @see onlineContacts()
+ * @see fileTransferContacts()
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ QStringList allContacts();
+
+ /**
+ * @brief Obtain a list of IM-contacts that are currently reachable
+ *
+ * Returns a list of KABC UIDs gathered by merging the lists of
+ * each application the proxy can communicate with.
+ *
+ * @return a list of KABC UIDs who can receive a message, even if offline
+ *
+ * @see allContacts()
+ * @see onlineContacts()
+ * @see fileTransferContacts()
+ * @see messageContact()
+ * @see KABC::Addressee::uid()
+ */
+ QStringList reachableContacts();
+
+ /**
+ * @brief Obtain a list of IM-contacts that are currently online
+ *
+ * Returns a list of KABC UIDs gathered by merging the lists of
+ * each application the proxy can communicate with.
+ * The method uses cached information to make it fast and not
+ * require actually communicating with the applications every time
+ * it is called.
+ *
+ * @return a list of KABC UIDs who are online with unspecified presence
+ *
+ * @see allContacts()
+ * @see reachableContacts()
+ * @see fileTransferContacts()
+ * @see messageContact()
+ * @see chatWithContact()
+ * @see KABC::Addressee::uid()
+ */
+ QStringList onlineContacts();
+
+ /**
+ * @brief Obtain a list of IM-contacts who may receive file transfers
+ *
+ * Returned IM-contacts might not be capable of receiving file
+ * tranfers due to limitations of their clients or because they are
+ * behind a firewall.
+ * KIMProxy doesn't have the possibilities to discover this and will
+ * list them as well.
+ *
+ * Returns a list of KABC UIDs gathered by merging the lists of
+ * each application the proxy can communicate with.
+ *
+ * @return a list of KABC UIDs capable of file transfer
+ *
+ * @see allContacts()
+ * @see reachableContacts()
+ * @see onlineContacts()
+ * @see canReceiveFiles()
+ * @see KABC::Addressee::uid()
+ */
+ QStringList fileTransferContacts();
+
+ /**
+ * @brief Confirm if a given contact is known to the proxy
+ *
+ * A contact is known to the proxy if it is know to at least one
+ * IM-application the proxy is communicating with.
+ *
+ * The method uses cached information to make it fast and not
+ * require actually communicating with the applications every time
+ * it is called.
+ *
+ * @param uid the KABC UID you are interested in
+ * @return whether any IM-program knows of this KABC UID
+ *
+ * @see allContacts()
+ * @see presenceString()
+ * @see presenceNumeric()
+ * @see KABC::Addressee::uid()
+ */
+ bool isPresent( const QString& uid );
+
+ /**
+ * @brief Obtain the proxy's idea of the contact's display name
+ *
+ * If the given KABC UID is known to more than one IM-application
+ * the result of the application which has the best presence for the
+ * contact is taken.
+ * For example if a contact is @c Online on ICQ and @c Away on AIM, the
+ * value returned by the application providing ICQ is taken.
+ *
+ * Useful if KABC lookups may be too slow.
+ *
+ * @param uid the KABC UID you are interested in
+ * @return the corresponding display name or QString:null if the
+ * UID is unknown
+ *
+ * @see isPresent()
+ * @see presenceString()
+ * @see presenceNumeric()
+ * @see KABC::Addressee::uid()
+ */
+ QString displayName( const QString& uid );
+
+ /**
+ * @brief Obtain the IM presence as a number for the specified contact
+ *
+ * Returns one of the following values depending on the given contact's
+ * presence:
+ * - 0 - @c Unknown: for contacts where you can not use any of the
+ * other values
+ *
+ * - 1 - @c Offline: for contacts that are offline, i.e. not connected
+ * to their IM-service.
+ *
+ * - 2 - @c Connecting
+ *
+ * - 3 - @c Away: for contacts that are connected to their IM-service
+ * but not @c Online
+ *
+ * - 4 - @c Online
+ *
+ * If the given KABC UID is known to more than one IM-application
+ * the result of the application which has the best presence for the
+ * contact is taken.
+ * For example if a contact is @c Online on ICQ and Away on AIM, the
+ * value returned by the application providing ICQ is taken.
+ *
+ * The method uses cached information to make it fast and not
+ * require actually communicating with the applications every time
+ * it is called.
+ *
+ * @param uid the KABC UID you want the presence for
+ * @return a numeric representation of presence - currently one of
+ * 0 (Unknown), 1 (Offline), 2 (Connecting), 3 (Away),
+ * 4 (Online). Returns 0 if the given UID is unknown
+ *
+ * @see isPresent()
+ * @see presenceString()
+ * @see presenceIcon()
+ * @see KIMIface::presenceStatus()
+ * @see KABC::Addressee::uid()
+ */
+ int presenceNumeric( const QString& uid );
+
+ /**
+ * @brief Obtain the IM presence as a i18ned string for the specified
+ * contact
+ *
+ * The presence string is one of the following:
+ * - i18n("Unknown")
+ * - i18n("Offline")
+ * - i18n("Connecting")
+ * - i18n("Away")
+ * - i18n("Online")
+ *
+ * If the given KABC UID is known to more than one IM-application
+ * the result of the application which has the best presence for the
+ * contact is taken.
+ * For example if a contact is @c Online on ICQ and Away on AIM, the
+ * value returned by the application providing ICQ is taken.
+ *
+ * @note The presence string is created based on the numerical
+ * presence value returned by the applications. It currently
+ * does not return the presence strings used by the applications.
+ *
+ * The method uses cached information to make it fast and not
+ * require actually communicating with the applications every time
+ * it is called.
+ *
+ * @param uid the KABC UID you want the presence for
+ * @return the i18ned string describing the contact's presence or
+ * QString::null if the UID is unknown
+ *
+ * @see isPresent()
+ * @see presenceNumeric()
+ * @see presenceIcon()
+ * @see KABC::Addressee::uid()
+ */
+ QString presenceString( const QString& uid );
+
+ /**
+ * @brief Obtain the icon representing the IM presence for the
+ * specified contact
+ *
+ * If the given KABC UID is known to more than one IM-application
+ * the result of the application which has the best presence for the
+ * contact is taken.
+ * For example if a contact is @c Online on ICQ and Away on AIM, the
+ * value returned by the application providing ICQ is taken.
+ *
+ * @note The presence icon is chosen based on the numerical
+ * presence value returned by the applications. It currently
+ * does not return the presence icon used by the applications.
+ *
+ * The method uses cached information to make it fast and not
+ * require actually communicating with the applications every time
+ * it is called.
+ *
+ * @param uid the KABC UID you want the presence icon for
+ * @return a pixmap representing the contact's presence or a null
+ * pixmap if the contact is unknown. See QPixmap::isNull()
+ *
+ * @see isPresent()
+ * @see presenceString()
+ * @see presenceNumeric()
+ * @see KABC::Addressee::uid()
+ */
+ QPixmap presenceIcon( const QString& uid );
+
+ /**
+ * @brief Indicate if a given contact can receive files
+ *
+ * If the given KABC UID is known to more than one IM-application
+ * the result of the application which has the best presence for the
+ * contact is taken.
+ * For example if a contact is @c Online on ICQ and Away on AIM, the
+ * value returned by the application providing ICQ is taken.
+ *
+ * @param uid the KABC UID you want to the file transfer capability for
+ * @return whether the specified contact can receive files
+ *
+ * @see fileTransferContacts()
+ * @see KABC::Addressee::uid()
+ */
+ bool canReceiveFiles( const QString & uid );
+
+ /**
+ * @brief Indicate if a given contact will be able to respond
+ *
+ * Some media are unidirectional (e.g., sending SMS via a web
+ * interface).
+ * This refers to the contact's ability to respond as defined by the
+ * medium, not by their presence.
+ *
+ * Someone may appear offline (SMS has no presence) to you but in fact
+ * be able to respond.
+ *
+ * If the given KABC UID is known to more than one IM-application
+ * the result of the application which has the best presence for the
+ * contact is taken.
+ * For example if a contact is @c Online on ICQ and Away on AIM, the
+ * value returned by the application providing ICQ is taken.
+ *
+ * @param uid the KABC UID you are interested in
+ * @return whether the specified contact can respond
+ *
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ bool canRespond( const QString & uid );
+
+ /**
+ * @brief Obtain the KABC UID corresponding to the given IM address
+ *
+ * @param contactId the protocol specific identifier for the contact,
+ * e.g. UIN for ICQ, screenname for AIM, nick for IRC
+ * @param protocol the IM protocol/service to check.
+ * See KIMIface::protocols()
+ * @return the KABC UID for the given contact or @c QString::null if
+ * not found or either input stream was empty or the protocol
+ * is not supported
+ *
+ * @see KIMIface::protocols()
+ * @see addContact()
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ QString locate( const QString & contactId, const QString & protocol );
+
+ /**
+ * @brief Obtain the given contact's current context (home, work, or
+ * any)
+ *
+ * Not all IM services/protocols support the concept of contexts. If the
+ * given UID maps to such a service, @c QString::null will be returned
+ *
+ * If the given KABC UID is known to more than one IM-application
+ * the result of the application which has the best presence for the
+ * contact is taken.
+ * For example if a contact is @c Online on ICQ and Away on AIM, the
+ * value returned by the application providing ICQ is taken.
+ *
+ * @param uid the KABC UID you want the context for
+ * @return a string describing the context, or @c QString::null if not
+ * supported or if the contact is unknown
+ *
+ * @see isPresent()
+ * @see KABC::Addressee::uid()
+ */
+ QString context( const QString & uid );
+
+ /**
+ * @brief Start a chat session with the specified contact
+ *
+ * @param uid the KABC UID you want to chat with
+ *
+ * @see messageContact()
+ * @see sendFile()
+ * @see isPresent()
+ * @see reachableContacts()
+ * @see KABC::Addressee::uid()
+ */
+ void chatWithContact( const QString& uid );
+
+ /**
+ * @brief Send a single message to the specified contact
+ *
+ * Any response will be handled by the IM client as a normal
+ * conversation.
+ *
+ * @param uid the KABC UID you want to send the message to
+ * @param message the message text to send to the contact
+ *
+ * @see chatWithContact()
+ * @see sendFile()
+ * @see isPresent()
+ * @see reachableContacts()
+ * @see KABC::Addressee::uid()
+ */
+ void messageContact( const QString& uid, const QString& message );
+
+ /**
+ * @brief Send a file to the contact
+ *
+ * Initiates a file transfer with the given contact if possible.
+ *
+ * @param uid the KABC UID you want to send to
+ * @param sourceURL a KURL pointing to the file to send
+ * @param altFileName an alternate filename describing the file or a
+ * description or title
+ * @param fileSize file size in bytes
+ *
+ * @see messageContact()
+ * @see chatWithContact()
+ * @see isPresent()
+ * @see fileTransferContacts()
+ * @see KABC::Addressee::uid()
+ */
+ void sendFile(const QString &uid, const KURL &sourceURL,
+ const QString &altFileName = QString::null, uint fileSize = 0);
+
+ /**
+ * @brief Add a new contact given its protocol specific identifier
+ *
+ * @param contactId the protocol specific identifier for the contact
+ * e.g. UIN for ICQ, screenname for AIM, nick for IRC
+ * @param protocol the IM protocol/service to use.
+ * See KIMIface:::protocols()
+ * @return whether the add succeeded. @c false may signal already present,
+ * protocol not supported, or add operation not supported.
+ *
+ * @see locate()
+ * @see KIMIface::protocols()
+ */
+ bool addContact( const QString &contactId, const QString &protocol );
+
+ /**
+ * @brief Checks if there are any compatible instant messaging
+ * applications available
+ *
+ * Available means that they are started and registered with DCOP
+ * and implementing the correct DCOP service.
+ * This information will be updated on the first call to initialize()
+ * and whenever an application registers or unregisters with DCOP,
+ * i.e. the information will be kept up to date.
+ *
+ * @return @c true if there are any apps available
+ */
+ bool imAppsAvailable();
+
+ /**
+ * @brief Start the user's preferred IM application
+ * @return whether a preferred app was found. No guarantee that it
+ * started correctly
+ */
+ bool startPreferredApp();
+
+ /**
+ * Just exists to let the IDL compiler make the DCOP signal for this
+ */
+ void contactPresenceChanged( QString uid, QCString appId, int presence );
+
+ public slots:
+ /**
+ * @brief Updates the proxy's data after a new application registered
+ * with DCOP
+ *
+ * Checks if the application specified by the given DCOP application
+ * identifier implements the instant messenger service.
+ *
+ * @param appId the DCOP application ID of the newly registered
+ * application
+ *
+ * @see DCOPClient::applicationRegistered()
+ */
+ void registeredToDCOP( const QCString& appId );
+
+ /**
+ * @brief Updates the proxy's data after an application unregistered
+ * with DCOP
+ *
+ * If the application specified by the given DCOP application
+ * identifier is one of the instant messenger applications of the
+ * proxy, it will remove the presence information it gathered from it
+ * earlier on.
+ *
+ * Emits sigPresenceInfoExpired() to let the using applcation know
+ * its presence related information might need updating.
+ *
+ * @param appId the DCOP application ID of the now unregistered
+ * application
+ *
+ * @see DCOPClient::applicationRemoved()
+ */
+ void unregisteredFromDCOP( const QCString& appId );
+ signals:
+ /**
+ * @brief Indicates that the specified IM-contact's presence changed
+ *
+ * @param uid the KABC UID whose presence changed
+ *
+ * @see isPresent()
+ * @see presenceNumeric()
+ * @see presenceIcon()
+ * @see KABC::Addressee::uid()
+ */
+ void sigContactPresenceChanged( const QString &uid );
+
+ /**
+ * @brief Indicates that presence information obtained earlier on might
+ * not be valid any longer
+ *
+ * After the sources of presence information have changed so any
+ * previously supplied presence info is invalid.
+ */
+ void sigPresenceInfoExpired();
+ protected:
+ /**
+ * Bootstrap our presence data for a newly registered app
+ */
+ void pollApp( const QCString & appId );
+ /**
+ * Bootstrap our presence data by polling all known apps
+ */
+ void pollAll( const QString &uid );
+
+ /**
+ * Update our records with the given data
+ */
+ bool updatePresence( const QString &uid, const QCString &appId, int presence );
+
+ /**
+ * Get the name of the user's IM application of choice
+ */
+ QString preferredApp();
+
+ /**
+ * Get the app stub best able to reach this uid
+ */
+ KIMIface_stub * stubForUid( const QString &uid );
+
+ /**
+ * Get the app stub for this protocol.
+ * Take the preferred app first, then any other.
+ */
+ KIMIface_stub * stubForProtocol( const QString &protocol );
+
+ private:
+ // client stubs used to get presence
+ // appId (from DCOP) -> KIMIface_stub
+ QDict<KIMIface_stub> m_im_client_stubs;
+ // map containing numeric presence and the originating application ID for each KABC uid we know of
+ // KABC Uid -> (appId, numeric presence )(AppPresence)
+ PresenceMap m_presence_map;
+ // cache of the client strings in use by each application
+ // dictionary of KIMIface_stub -> map of numeric presence -> string presence
+ // FIXME: remove for KDE4 - UNUSED but maintained for binary compatibility in KDE 3.4
+ QPtrDict<int> m_client_presence_strings;
+ Private * d;
+ bool m_apps_available;
+ bool m_initialized;
+ /**
+ * Construct an instance of the proxy library.
+ */
+ KIMProxy( DCOPClient * client);
+ static KIMProxy * s_instance;
+};
+
+#endif
+
diff --git a/interfaces/kimproxy/library/kimproxyiface.h b/interfaces/kimproxy/library/kimproxyiface.h
new file mode 100644
index 000000000..7c99bce4e
--- /dev/null
+++ b/interfaces/kimproxy/library/kimproxyiface.h
@@ -0,0 +1,38 @@
+/*
+ kimproxyiface.cpp
+
+ IM service library for KDE
+
+ DCOP interface to allow us to receive DCOP signals
+
+ Copyright (c) 2004 Will Stephenson <lists@stevello.free-online.co.uk>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KIMPROXYIFACE_H
+#define KIMPROXYIFACE_H
+
+#include <dcopobject.h>
+
+class KIMProxyIface : virtual public DCOPObject
+{
+ K_DCOP
+ k_dcop:
+ virtual void contactPresenceChanged( QString uid, QCString appId, int presence ) = 0;
+};
+
+#endif