diff --git a/amsn2/core/amsn.py b/amsn2/core/amsn.py index 24b46ca6..52e237a4 100644 --- a/amsn2/core/amsn.py +++ b/amsn2/core/amsn.py @@ -29,6 +29,7 @@ from conversation_manager import * from oim_manager import * from theme_manager import * +from smiley_manager import * from personalinfo_manager import * from event_manager import * from userinterface_manager import * @@ -77,6 +78,7 @@ def __init__(self, options = None, extra_args = None): self._backend_manager = aMSNBackendManager(self) self._account_manager = aMSNAccountManager(self, options) self._theme_manager = aMSNThemeManager(self) + self._smiley_manager = aMSNSmileyManager(self) self._contactlist_manager = aMSNContactListManager(self) self._oim_manager = aMSNOIMManager(self) self._conversation_manager = aMSNConversationManager(self) diff --git a/amsn2/core/smiley_manager.py b/amsn2/core/smiley_manager.py new file mode 100644 index 00000000..6b3475b5 --- /dev/null +++ b/amsn2/core/smiley_manager.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- +# +# amsn - a python client for the WLM Network +# +# Copyright (C) 2010 Mehdi KOUHEN +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +class aMSNSmileyManager: + def __init__(self, core): #for now, only a dic of default smileys' shortcuts + self._core = core + self.default_smileys_shortcuts = { + "(ap)": "smiley_airplane", + "(a)": "smiley_angel", + ":-@": "smiley_angry", + ":@": "smiley_angry", + "(so)": "smiley_ball", + ":-[": "smiley_bat", + ":[": "smiley_bat", + "(b)": "smiley_beer", + ":D": "smiley_big_smile", + ":>": "smiley_big_smile", + ":->": "smiley_big_smile", + ":-D": "smiley_big_smile", + "(||)": "smiley_bowl", + "(z)": "smiley_boy", + "(brb)": "smiley_brb", + "(u)": "smiley_broken_heart", + "(^)": "smiley_cake", + "(p)": "smiley_camera", + "(au)": "smiley_car", + "(@)": "smiley_cat", + "(ci)": "smiley_cigarette", + "(h5)": "smiley_clapping_hands", + "(o)": "smiley_clock", + "(c)": "smiley_coffee", + "(co)": "smiley_computer", + ":-s": "smiley_confused", + ":s": "smiley_confused", + "(h)": "smiley_cool_glasses", + ":'(": "smiley_crying", + "(w)": "smiley_dead_rose", + "(6)": "smiley_devil", + ":|": "smiley_disapointed", + ":-|": "smiley_disapointed", + "(&)": "smiley_dog", + ":^)": "smiley_dont_know", + "(d)": "smiley_drink", + "(e)": "smiley_email", + ":$": "smiley_embarrassed", + ":-$": "smiley_embarrassed", + "8-)": "smiley_eye_rolling", + "(~)": "smiley_film", + "(yn)": "smiley_finger_cross", + "(g)": "smiley_gift", + "(x)": "smiley_girl", + "(nah)": "smiley_goat", + "(%)": "smiley_handcuffs", + "(l)": "smiley_heart", + "*red+u": "smiley_im", + "(ip)": "smiley_island", + "(k)": "smiley_kiss", + "({)": "smiley_left_hug", + "(i)": "smiley_light", + "(mp)": "smiley_mobile", + "(mo)": "smiley_money", + "(s)": "smiley_moon", + "(m)": "smiley_msn", + "8-|": "smiley_nerd", + "(8)": "smiley_note", + "<:o)": "smiley_party", + "(t)": "smiley_phone", + "(pi)": "smiley_pizza", + "(pl)": "smiley_plate", + ":-#": "smiley_quiet", + "('.')": "smiley_rabbit", + "(st)": "smiley_rain", + "(r)": "smiley_rainbow", + "(})": "smiley_right_hug", + "(f)": "smiley_rose", + ":(": "smiley_sad", + ":-(": "smiley_sad", + ":-<": "smiley_sad", + ":<": "smiley_sad", + "^o)": "smiley_sarcastic", + ":-*": "smiley_secret", + "(nah)": "smiley_sheep", + ":-o": "smiley_shock", + ":o": "smiley_shock", + "+o(": "smiley_sick", + ":)": "smiley_smile", + ":-)": "smiley_smile", + "(sn)": "smiley_snail", + "(*)": "smiley_star", + "(li)": "smiley_storm", + "(#)": "smiley_sun", + "8o|": "smiley_teeth", + "*-)": "smiley_think", + "(n)": "smiley_thumb_down", + "(y)": "smiley_thumb_up", + "|-)": "smiley_tired", + ":p": "smiley_tongue", + ":-p": "smiley_tongue", + "(tu)": "smiley_turtle", + "(um)": "smiley_umbrella", + ";)": "smiley_wink", + ";-)": "smiley_wink", + "(xx)": "smiley_xbox", + } diff --git a/amsn2/core/theme_manager.py b/amsn2/core/theme_manager.py index 671703c9..a267cde1 100644 --- a/amsn2/core/theme_manager.py +++ b/amsn2/core/theme_manager.py @@ -47,6 +47,7 @@ def load(self): self._statusicons = aMSNStatusIconLoader().load('default') self._displaypic = aMSNDisplayPicLoader().load('default') self._emblems = aMSNEmblemLoader().load('default') + self._smileys = aMSNSmileyLoader().load('default') def get_value(self, key): if (key.startswith('button_')): @@ -57,6 +58,8 @@ def get_value(self, key): return self.get_dp(key) elif (key.startswith('emblem_')): return self.get_emblem(key) + elif (key.startswith('smiley_')): + return self.get_smiley(key) else: # TODO: This should raise a exception return (None, None) @@ -73,6 +76,9 @@ def get_dp(self, key): def get_emblem(self, key): return self.__get(self._emblems, key) + def get_smiley(self, key): + return self.__get(self._smileys, key) + class aMSNGenericLoader: def __init__(self, basedir): self._theme = 'default' @@ -151,3 +157,90 @@ def __init__(self): 'emblem_hidden': 'offline_emblem.png', 'emblem_blocked': 'blocked_emblem.png', } + +class aMSNSmileyLoader(aMSNGenericLoader): + def __init__(self): + aMSNGenericLoader.__init__(self, "smileys") + self._keys = { + 'smiley_airplane': 'airplane.png', + 'smiley_angel': 'angel.png', + 'smiley_angry': 'angry.png', + 'smiley_ball': 'ball.png', + 'smiley_bat': 'bat.png', + 'smiley_beer': 'beer.png', + 'smiley_big_smile': 'big_smile.png', + 'smiley_bowl': 'bowl.png', + 'smiley_boy': 'boy.png', + 'smiley_brb': 'brb.png', + 'smiley_broken_heart': 'broken_heart.png', + 'smiley_cake': 'cake.png', + 'smiley_camera': 'camera.png', + 'smiley_car': 'car.png', + 'smiley_cat': 'cat.png', + 'smiley_cigarette': 'cigarette.png', + 'smiley_clapping_hands': 'clapping_hands.png', + 'smiley_clock': 'clock.png', + 'smiley_coffee': 'coffee.png', + 'smiley_computer': 'computer.png', + 'smiley_confused': 'confused.png', + 'smiley_cool_glasses': 'cool_glasses.png', + 'smiley_crying': 'crying.png', + 'smiley_dead_rose': 'dead_rose.png', + 'smiley_devil': 'devil.png', + 'smiley_disapointed': 'disapointed.png', + 'smiley_dog': 'dog.png', + 'smiley_dont_know': 'dont_know.png', + 'smiley_drink': 'drink.png', + 'smiley_email': 'email.png', + 'smiley_embarrassed': 'embarrassed.png', + 'smiley_eye_rolling': 'eye_rolling.png', + 'smiley_film': 'film.png', + 'smiley_finger_cross': 'finger_cross.png', + 'smiley_gift': 'gift.png', + 'smiley_girl': 'girl.png', + 'smiley_goat': 'goat.png', + 'smiley_handcuffs': 'handcuffs.png', + 'smiley_heart': 'heart.png', + 'smiley_im': 'im.png', + 'smiley_island': 'island.png', + 'smiley_kiss': 'kiss.png', + 'smiley_left_hug': 'left_hug.png', + 'smiley_light': 'light.png', + 'smiley_mobile': 'mobile.png', + 'smiley_money': 'money.png', + 'smiley_moon': 'moon.png', + 'smiley_msn': 'msn.png', + 'smiley_nerd': 'nerd.png', + 'smiley_note': 'note.png', + 'smiley_party': 'party.png', + 'smiley_phone': 'phone.png', + 'smiley_pizza': 'pizza.png', + 'smiley_plate': 'plate.png', + 'smiley_quiet': 'quiet.png', + 'smiley_rabbit': 'rabbit.png', + 'smiley_rain': 'rain.png', + 'smiley_rainbow': 'rainbow.png', + 'smiley_right_hug': 'right_hug.png', + 'smiley_rose': 'rose.png', + 'smiley_sad': 'sad.png', + 'smiley_sarcastic': 'sarcastic.png', + 'smiley_secret': 'secret.png', + 'smiley_sheep': 'sheep.png', + 'smiley_shock': 'shock.png', + 'smiley_sick': 'sick.png', + 'smiley_smile': 'smile.png', + 'smiley_snail': 'snail.png', + 'smiley_star': 'star.png', + 'smiley_storm': 'storm.png', + 'smiley_sun': 'sun.png', + 'smiley_teeth': 'teeth.png', + 'smiley_think': 'think.png', + 'smiley_thumb_down': 'thumb_down.png', + 'smiley_thumb_up': 'thumb_up.png', + 'smiley_tired': 'tired.png', + 'smiley_tongue': 'tongue.png', + 'smiley_turtle': 'turtle.png', + 'smiley_umbrella': 'umbrella.png', + 'smiley_wink': 'wink.png', + 'smiley_xbox': 'xbox.png', + } diff --git a/amsn2/core/userinterface_manager.py b/amsn2/core/userinterface_manager.py index 7b65b1ea..7cf16658 100644 --- a/amsn2/core/userinterface_manager.py +++ b/amsn2/core/userinterface_manager.py @@ -130,32 +130,27 @@ def load_chat_widget(self, conversation, window, cuids): def load_contact_input_window(self, callback, groupviews): win = self._ui.aMSNContactInputWindow(('Contact to add: ', 'Invite message: '), - callback, groupviews) - win.set_title("aMSN 2 - Add a Contact") + callback, groupviews, "aMSN 2 - Add a Contact") win.show() return win def load_contact_delete_window(self, callback, contactviews): - win = self._ui.aMSNContactDeleteWindow(('Contact to remove: ',), callback, contactviews) - win.set_title("aMSN 2 - Delete a Contact") + win = self._ui.aMSNContactDeleteWindow(('Contact to remove: ',), callback, contactviews, "aMSN 2 - Delete a Contact") win.show() return win def load_group_input_window(self, callback, contactviews): - win = self._ui.aMSNGroupInputWindow(('Group to add: ',), callback, contactviews) - win.set_title("aMSN 2 - Add a Group") + win = self._ui.aMSNGroupInputWindow(('Group to add: ',), callback, contactviews, "aMSN 2 - Add a Group") win.show() return win def load_group_delete_window(self, callback, groupviews): - win = self._ui.aMSNGroupDeleteWindow(('Group to remove: ',), callback, groupviews) - win.set_title("aMSN 2 - Delete a Group") + win = self._ui.aMSNGroupDeleteWindow(('Group to remove: ',), callback, groupviews, "aMSN 2 - Delete a Group") win.show() return win def load_DP_chooser_window(self): - win = self._ui.aMSNDPChooserWindow(self._core._account.set_dp ,self._core._backend_manager) - win.set_title("aMSN 2 - Choose a Display Picture") + win = self._ui.aMSNDPChooserWindow(self._core._account.set_dp ,self._core._backend_manager, "aMSN 2 - Choose a Display Picture") win.show() # Common methods for all UI diff --git a/amsn2/smileys/default/airplane.png b/amsn2/themes/smileys/default/airplane.png similarity index 100% rename from amsn2/smileys/default/airplane.png rename to amsn2/themes/smileys/default/airplane.png diff --git a/amsn2/smileys/default/angel.png b/amsn2/themes/smileys/default/angel.png similarity index 100% rename from amsn2/smileys/default/angel.png rename to amsn2/themes/smileys/default/angel.png diff --git a/amsn2/smileys/default/angry.png b/amsn2/themes/smileys/default/angry.png similarity index 100% rename from amsn2/smileys/default/angry.png rename to amsn2/themes/smileys/default/angry.png diff --git a/amsn2/smileys/default/ball.png b/amsn2/themes/smileys/default/ball.png similarity index 100% rename from amsn2/smileys/default/ball.png rename to amsn2/themes/smileys/default/ball.png diff --git a/amsn2/smileys/default/bat.png b/amsn2/themes/smileys/default/bat.png similarity index 100% rename from amsn2/smileys/default/bat.png rename to amsn2/themes/smileys/default/bat.png diff --git a/amsn2/smileys/default/beer.png b/amsn2/themes/smileys/default/beer.png similarity index 100% rename from amsn2/smileys/default/beer.png rename to amsn2/themes/smileys/default/beer.png diff --git a/amsn2/smileys/default/big_smile.png b/amsn2/themes/smileys/default/big_smile.png similarity index 100% rename from amsn2/smileys/default/big_smile.png rename to amsn2/themes/smileys/default/big_smile.png diff --git a/amsn2/smileys/default/bowl.png b/amsn2/themes/smileys/default/bowl.png similarity index 100% rename from amsn2/smileys/default/bowl.png rename to amsn2/themes/smileys/default/bowl.png diff --git a/amsn2/smileys/default/boy.png b/amsn2/themes/smileys/default/boy.png similarity index 100% rename from amsn2/smileys/default/boy.png rename to amsn2/themes/smileys/default/boy.png diff --git a/amsn2/smileys/default/brb.png b/amsn2/themes/smileys/default/brb.png similarity index 100% rename from amsn2/smileys/default/brb.png rename to amsn2/themes/smileys/default/brb.png diff --git a/amsn2/smileys/default/broken_heart.png b/amsn2/themes/smileys/default/broken_heart.png similarity index 100% rename from amsn2/smileys/default/broken_heart.png rename to amsn2/themes/smileys/default/broken_heart.png diff --git a/amsn2/smileys/default/cake.png b/amsn2/themes/smileys/default/cake.png similarity index 100% rename from amsn2/smileys/default/cake.png rename to amsn2/themes/smileys/default/cake.png diff --git a/amsn2/smileys/default/camera.png b/amsn2/themes/smileys/default/camera.png similarity index 100% rename from amsn2/smileys/default/camera.png rename to amsn2/themes/smileys/default/camera.png diff --git a/amsn2/smileys/default/car.png b/amsn2/themes/smileys/default/car.png similarity index 100% rename from amsn2/smileys/default/car.png rename to amsn2/themes/smileys/default/car.png diff --git a/amsn2/smileys/default/cat.png b/amsn2/themes/smileys/default/cat.png similarity index 100% rename from amsn2/smileys/default/cat.png rename to amsn2/themes/smileys/default/cat.png diff --git a/amsn2/smileys/default/cigarette.png b/amsn2/themes/smileys/default/cigarette.png similarity index 100% rename from amsn2/smileys/default/cigarette.png rename to amsn2/themes/smileys/default/cigarette.png diff --git a/amsn2/smileys/default/clapping_hands.png b/amsn2/themes/smileys/default/clapping_hands.png similarity index 100% rename from amsn2/smileys/default/clapping_hands.png rename to amsn2/themes/smileys/default/clapping_hands.png diff --git a/amsn2/smileys/default/clock.png b/amsn2/themes/smileys/default/clock.png similarity index 100% rename from amsn2/smileys/default/clock.png rename to amsn2/themes/smileys/default/clock.png diff --git a/amsn2/smileys/default/coffee.png b/amsn2/themes/smileys/default/coffee.png similarity index 100% rename from amsn2/smileys/default/coffee.png rename to amsn2/themes/smileys/default/coffee.png diff --git a/amsn2/smileys/default/computer.png b/amsn2/themes/smileys/default/computer.png similarity index 100% rename from amsn2/smileys/default/computer.png rename to amsn2/themes/smileys/default/computer.png diff --git a/amsn2/smileys/default/confused.png b/amsn2/themes/smileys/default/confused.png similarity index 100% rename from amsn2/smileys/default/confused.png rename to amsn2/themes/smileys/default/confused.png diff --git a/amsn2/smileys/default/cool_glasses.png b/amsn2/themes/smileys/default/cool_glasses.png similarity index 100% rename from amsn2/smileys/default/cool_glasses.png rename to amsn2/themes/smileys/default/cool_glasses.png diff --git a/amsn2/smileys/default/crying.png b/amsn2/themes/smileys/default/crying.png similarity index 100% rename from amsn2/smileys/default/crying.png rename to amsn2/themes/smileys/default/crying.png diff --git a/amsn2/smileys/default/dead_rose.png b/amsn2/themes/smileys/default/dead_rose.png similarity index 100% rename from amsn2/smileys/default/dead_rose.png rename to amsn2/themes/smileys/default/dead_rose.png diff --git a/amsn2/smileys/default/devil.png b/amsn2/themes/smileys/default/devil.png similarity index 100% rename from amsn2/smileys/default/devil.png rename to amsn2/themes/smileys/default/devil.png diff --git a/amsn2/smileys/default/disapointed.png b/amsn2/themes/smileys/default/disapointed.png similarity index 100% rename from amsn2/smileys/default/disapointed.png rename to amsn2/themes/smileys/default/disapointed.png diff --git a/amsn2/smileys/default/dog.png b/amsn2/themes/smileys/default/dog.png similarity index 100% rename from amsn2/smileys/default/dog.png rename to amsn2/themes/smileys/default/dog.png diff --git a/amsn2/smileys/default/dont_know.png b/amsn2/themes/smileys/default/dont_know.png similarity index 100% rename from amsn2/smileys/default/dont_know.png rename to amsn2/themes/smileys/default/dont_know.png diff --git a/amsn2/smileys/default/drink.png b/amsn2/themes/smileys/default/drink.png similarity index 100% rename from amsn2/smileys/default/drink.png rename to amsn2/themes/smileys/default/drink.png diff --git a/amsn2/smileys/default/email.png b/amsn2/themes/smileys/default/email.png similarity index 100% rename from amsn2/smileys/default/email.png rename to amsn2/themes/smileys/default/email.png diff --git a/amsn2/smileys/default/embarrassed.png b/amsn2/themes/smileys/default/embarrassed.png similarity index 100% rename from amsn2/smileys/default/embarrassed.png rename to amsn2/themes/smileys/default/embarrassed.png diff --git a/amsn2/smileys/default/eye_rolling.png b/amsn2/themes/smileys/default/eye_rolling.png similarity index 100% rename from amsn2/smileys/default/eye_rolling.png rename to amsn2/themes/smileys/default/eye_rolling.png diff --git a/amsn2/smileys/default/film.png b/amsn2/themes/smileys/default/film.png similarity index 100% rename from amsn2/smileys/default/film.png rename to amsn2/themes/smileys/default/film.png diff --git a/amsn2/smileys/default/finger_cross.png b/amsn2/themes/smileys/default/finger_cross.png similarity index 100% rename from amsn2/smileys/default/finger_cross.png rename to amsn2/themes/smileys/default/finger_cross.png diff --git a/amsn2/smileys/default/gift.png b/amsn2/themes/smileys/default/gift.png similarity index 100% rename from amsn2/smileys/default/gift.png rename to amsn2/themes/smileys/default/gift.png diff --git a/amsn2/smileys/default/girl.png b/amsn2/themes/smileys/default/girl.png similarity index 100% rename from amsn2/smileys/default/girl.png rename to amsn2/themes/smileys/default/girl.png diff --git a/amsn2/smileys/default/goat.png b/amsn2/themes/smileys/default/goat.png similarity index 100% rename from amsn2/smileys/default/goat.png rename to amsn2/themes/smileys/default/goat.png diff --git a/amsn2/smileys/default/handcuffs.png b/amsn2/themes/smileys/default/handcuffs.png similarity index 100% rename from amsn2/smileys/default/handcuffs.png rename to amsn2/themes/smileys/default/handcuffs.png diff --git a/amsn2/smileys/default/heart.png b/amsn2/themes/smileys/default/heart.png similarity index 100% rename from amsn2/smileys/default/heart.png rename to amsn2/themes/smileys/default/heart.png diff --git a/amsn2/smileys/default/im.png b/amsn2/themes/smileys/default/im.png similarity index 100% rename from amsn2/smileys/default/im.png rename to amsn2/themes/smileys/default/im.png diff --git a/amsn2/smileys/default/island.png b/amsn2/themes/smileys/default/island.png similarity index 100% rename from amsn2/smileys/default/island.png rename to amsn2/themes/smileys/default/island.png diff --git a/amsn2/smileys/default/kiss.png b/amsn2/themes/smileys/default/kiss.png similarity index 100% rename from amsn2/smileys/default/kiss.png rename to amsn2/themes/smileys/default/kiss.png diff --git a/amsn2/smileys/default/left_hug.png b/amsn2/themes/smileys/default/left_hug.png similarity index 100% rename from amsn2/smileys/default/left_hug.png rename to amsn2/themes/smileys/default/left_hug.png diff --git a/amsn2/smileys/default/light.png b/amsn2/themes/smileys/default/light.png similarity index 100% rename from amsn2/smileys/default/light.png rename to amsn2/themes/smileys/default/light.png diff --git a/amsn2/smileys/default/mobile.png b/amsn2/themes/smileys/default/mobile.png similarity index 100% rename from amsn2/smileys/default/mobile.png rename to amsn2/themes/smileys/default/mobile.png diff --git a/amsn2/smileys/default/money.png b/amsn2/themes/smileys/default/money.png similarity index 100% rename from amsn2/smileys/default/money.png rename to amsn2/themes/smileys/default/money.png diff --git a/amsn2/smileys/default/moon.png b/amsn2/themes/smileys/default/moon.png similarity index 100% rename from amsn2/smileys/default/moon.png rename to amsn2/themes/smileys/default/moon.png diff --git a/amsn2/smileys/default/msn.png b/amsn2/themes/smileys/default/msn.png similarity index 100% rename from amsn2/smileys/default/msn.png rename to amsn2/themes/smileys/default/msn.png diff --git a/amsn2/smileys/default/nerd.png b/amsn2/themes/smileys/default/nerd.png similarity index 100% rename from amsn2/smileys/default/nerd.png rename to amsn2/themes/smileys/default/nerd.png diff --git a/amsn2/smileys/default/note.png b/amsn2/themes/smileys/default/note.png similarity index 100% rename from amsn2/smileys/default/note.png rename to amsn2/themes/smileys/default/note.png diff --git a/amsn2/smileys/default/party.png b/amsn2/themes/smileys/default/party.png similarity index 100% rename from amsn2/smileys/default/party.png rename to amsn2/themes/smileys/default/party.png diff --git a/amsn2/smileys/default/phone.png b/amsn2/themes/smileys/default/phone.png similarity index 100% rename from amsn2/smileys/default/phone.png rename to amsn2/themes/smileys/default/phone.png diff --git a/amsn2/smileys/default/pizza.png b/amsn2/themes/smileys/default/pizza.png similarity index 100% rename from amsn2/smileys/default/pizza.png rename to amsn2/themes/smileys/default/pizza.png diff --git a/amsn2/smileys/default/plate.png b/amsn2/themes/smileys/default/plate.png similarity index 100% rename from amsn2/smileys/default/plate.png rename to amsn2/themes/smileys/default/plate.png diff --git a/amsn2/smileys/default/quiet.png b/amsn2/themes/smileys/default/quiet.png similarity index 100% rename from amsn2/smileys/default/quiet.png rename to amsn2/themes/smileys/default/quiet.png diff --git a/amsn2/smileys/default/rabbit.png b/amsn2/themes/smileys/default/rabbit.png similarity index 100% rename from amsn2/smileys/default/rabbit.png rename to amsn2/themes/smileys/default/rabbit.png diff --git a/amsn2/smileys/default/rain.png b/amsn2/themes/smileys/default/rain.png similarity index 100% rename from amsn2/smileys/default/rain.png rename to amsn2/themes/smileys/default/rain.png diff --git a/amsn2/smileys/default/rainbow.png b/amsn2/themes/smileys/default/rainbow.png similarity index 100% rename from amsn2/smileys/default/rainbow.png rename to amsn2/themes/smileys/default/rainbow.png diff --git a/amsn2/smileys/default/right_hug.png b/amsn2/themes/smileys/default/right_hug.png similarity index 100% rename from amsn2/smileys/default/right_hug.png rename to amsn2/themes/smileys/default/right_hug.png diff --git a/amsn2/smileys/default/rose.png b/amsn2/themes/smileys/default/rose.png similarity index 100% rename from amsn2/smileys/default/rose.png rename to amsn2/themes/smileys/default/rose.png diff --git a/amsn2/smileys/default/sad.png b/amsn2/themes/smileys/default/sad.png similarity index 100% rename from amsn2/smileys/default/sad.png rename to amsn2/themes/smileys/default/sad.png diff --git a/amsn2/smileys/default/sarcastic.png b/amsn2/themes/smileys/default/sarcastic.png similarity index 100% rename from amsn2/smileys/default/sarcastic.png rename to amsn2/themes/smileys/default/sarcastic.png diff --git a/amsn2/smileys/default/secret.png b/amsn2/themes/smileys/default/secret.png similarity index 100% rename from amsn2/smileys/default/secret.png rename to amsn2/themes/smileys/default/secret.png diff --git a/amsn2/smileys/default/sheep.png b/amsn2/themes/smileys/default/sheep.png similarity index 100% rename from amsn2/smileys/default/sheep.png rename to amsn2/themes/smileys/default/sheep.png diff --git a/amsn2/smileys/default/shock.png b/amsn2/themes/smileys/default/shock.png similarity index 100% rename from amsn2/smileys/default/shock.png rename to amsn2/themes/smileys/default/shock.png diff --git a/amsn2/smileys/default/sick.png b/amsn2/themes/smileys/default/sick.png similarity index 100% rename from amsn2/smileys/default/sick.png rename to amsn2/themes/smileys/default/sick.png diff --git a/amsn2/smileys/default/smile.png b/amsn2/themes/smileys/default/smile.png similarity index 100% rename from amsn2/smileys/default/smile.png rename to amsn2/themes/smileys/default/smile.png diff --git a/amsn2/smileys/default/snail.png b/amsn2/themes/smileys/default/snail.png similarity index 100% rename from amsn2/smileys/default/snail.png rename to amsn2/themes/smileys/default/snail.png diff --git a/amsn2/smileys/default/star.png b/amsn2/themes/smileys/default/star.png similarity index 100% rename from amsn2/smileys/default/star.png rename to amsn2/themes/smileys/default/star.png diff --git a/amsn2/smileys/default/storm.png b/amsn2/themes/smileys/default/storm.png similarity index 100% rename from amsn2/smileys/default/storm.png rename to amsn2/themes/smileys/default/storm.png diff --git a/amsn2/smileys/default/sun.png b/amsn2/themes/smileys/default/sun.png similarity index 100% rename from amsn2/smileys/default/sun.png rename to amsn2/themes/smileys/default/sun.png diff --git a/amsn2/smileys/default/teeth.png b/amsn2/themes/smileys/default/teeth.png similarity index 100% rename from amsn2/smileys/default/teeth.png rename to amsn2/themes/smileys/default/teeth.png diff --git a/amsn2/smileys/default/think.png b/amsn2/themes/smileys/default/think.png similarity index 100% rename from amsn2/smileys/default/think.png rename to amsn2/themes/smileys/default/think.png diff --git a/amsn2/smileys/default/thumb_down.png b/amsn2/themes/smileys/default/thumb_down.png similarity index 100% rename from amsn2/smileys/default/thumb_down.png rename to amsn2/themes/smileys/default/thumb_down.png diff --git a/amsn2/smileys/default/thumb_up.png b/amsn2/themes/smileys/default/thumb_up.png similarity index 100% rename from amsn2/smileys/default/thumb_up.png rename to amsn2/themes/smileys/default/thumb_up.png diff --git a/amsn2/smileys/default/tired.png b/amsn2/themes/smileys/default/tired.png similarity index 100% rename from amsn2/smileys/default/tired.png rename to amsn2/themes/smileys/default/tired.png diff --git a/amsn2/smileys/default/tongue.png b/amsn2/themes/smileys/default/tongue.png similarity index 100% rename from amsn2/smileys/default/tongue.png rename to amsn2/themes/smileys/default/tongue.png diff --git a/amsn2/smileys/default/turtle.png b/amsn2/themes/smileys/default/turtle.png similarity index 100% rename from amsn2/smileys/default/turtle.png rename to amsn2/themes/smileys/default/turtle.png diff --git a/amsn2/smileys/default/umbrella.png b/amsn2/themes/smileys/default/umbrella.png similarity index 100% rename from amsn2/smileys/default/umbrella.png rename to amsn2/themes/smileys/default/umbrella.png diff --git a/amsn2/smileys/default/wink.png b/amsn2/themes/smileys/default/wink.png similarity index 100% rename from amsn2/smileys/default/wink.png rename to amsn2/themes/smileys/default/wink.png diff --git a/amsn2/smileys/default/xbox.png b/amsn2/themes/smileys/default/xbox.png similarity index 100% rename from amsn2/smileys/default/xbox.png rename to amsn2/themes/smileys/default/xbox.png diff --git a/amsn2/ui/base/choosers.py b/amsn2/ui/base/choosers.py index 67916937..a054abcf 100644 --- a/amsn2/ui/base/choosers.py +++ b/amsn2/ui/base/choosers.py @@ -4,7 +4,7 @@ class aMSNFileChooserWindow(object): This Interface represent a window used to choose a file, which could be an image for the dp, a file to send, a theme file, etc. """ - def __init__(self, filters, directory, callback): + def __init__(self, filters, directory, callback, title = "aMSN Display Picture Chooser"): """ @type filter: dict of tuple @param filter: A dict whose keys are the names of the filters, diff --git a/amsn2/ui/base/utility.py b/amsn2/ui/base/utility.py index 83b0d9e4..3d289a1a 100644 --- a/amsn2/ui/base/utility.py +++ b/amsn2/ui/base/utility.py @@ -1,9 +1,10 @@ class aMSNErrorWindow(object): """ This Interface represent an error window """ - def __init__(self, error_text): + def __init__(self, error_text, title = "aMSN Error"): """ @type error_text: str + @type title: str """ raise NotImplementedError @@ -18,9 +19,10 @@ class aMSNNotificationWindow(object): This Interface represent a window used to display a notification message, generally when an operation has finished succesfully. """ - def __init__(self, notification_text): + def __init__(self, notification_text, title = "aMSN Notification"): """ @type notification_text: str + @type title: str """ raise NotImplementedError @@ -35,13 +37,14 @@ class aMSNDialogWindow(object): This Interface represent a dialog window, used to ask the user about something to do. """ - def __init__(self, message, actions): + def __init__(self, message, actions, title = "aMSN Dialog"): """ @type message: str @type actions: tuple @param actions: A tuple containing the options between which the user can choose. Every option is a tuple itself, of the form (name, callback), where callback is the function that will be called if the option is selected. + @type title: str """ raise NotImplementedError @@ -55,7 +58,7 @@ class aMSNContactInputWindow(object): """ This Interface represent a window used to get a new contact. """ - def __init__(self, message, callback, groupviews): + def __init__(self, message, callback, groupviews, title = "aMSN Contact Input"): """ @type message: tuple @param message: A tuple with the messages to be shown in the input window, @@ -65,6 +68,7 @@ def __init__(self, message, callback, groupviews): The prototype is callback(email, invite_message, groups). @type groupviews: list @param groupviews: a list of groupviews of existing groups + @type title: str """ raise NotImplementedError @@ -78,7 +82,7 @@ class aMSNGroupInputWindow(object): """ This Interface represent a window used to get a new group. """ - def __init__(self, message, callback, contactviews): + def __init__(self, message, callback, contactviews, title = "aMSN Group Input"): """ @type message: tuple @param message: A tuple with the messages to be shown in the input window. @@ -87,6 +91,7 @@ def __init__(self, message, callback, contactviews): The prototype is callback(name_group, contacts). @type contactviews: list @param contactviews: a list of contactviews of existing contacts + @type title: str """ raise NotImplementedError @@ -100,7 +105,7 @@ class aMSNContactDeleteWindow(object): """ This Interface represent a window used to delete a contact. """ - def __init__(self, message, callback, contactviews): + def __init__(self, message, callback, contactviews, title = "aMSN Delete Contact"): """ @type message: tuple @param message: A tuple with the messages to be shown in the window. @@ -110,6 +115,7 @@ def __init__(self, message, callback, contactviews): @type contactviews: list @param contactviews: a list of contactviews of all the contacts that can be removed from the AddressBook. + @type title: str """ raise NotImplementedError @@ -123,7 +129,7 @@ class aMSNGroupDeleteWindow(object): """ This Interface represent a window used to delete a group. """ - def __init__(self, message, callback, groupviews): + def __init__(self, message, callback, groupviews, title = "aMSN Delete Group"): """ @type message: tuple @param message: A tuple with the messages to be shown in the window. @@ -133,6 +139,7 @@ def __init__(self, message, callback, groupviews): @type groupviews: list @param groupviews: a list of groupviews of all the groups that can be removed from the AddressBook. + @type title: str """ raise NotImplementedError diff --git a/amsn2/ui/front_ends/gtk/chat_window.py b/amsn2/ui/front_ends/gtk/chat_window.py index bed92f91..162682a2 100644 --- a/amsn2/ui/front_ends/gtk/chat_window.py +++ b/amsn2/ui/front_ends/gtk/chat_window.py @@ -23,7 +23,6 @@ import gc import gtk -import cgi import time import pango from htmltextview import * @@ -247,9 +246,6 @@ def __on_changed_text_font(self, button): tag.set_property("family", font_family) buffer.apply_tag_by_name("family", buffer.get_start_iter(), buffer.get_end_iter()) - def __clean_string(self, str): - return cgi.escape(str) - def __on_chat_send(self, entry, event_keyval, event_keymod): if (event_keyval == gtk.keysyms.Return): buffer = entry.get_buffer() @@ -317,7 +313,6 @@ def __typingStopped(self): def on_message_received(self, messageview, formatting=None): text = messageview.to_stringview().to_HTML_string() - text = self.__clean_string(text) nick, msg = text.split('\n', 1) nick = str(nick.replace('\n', '
')) msg = str(msg.replace('\n', '
')) diff --git a/amsn2/ui/front_ends/gtk/utility.py b/amsn2/ui/front_ends/gtk/utility.py index 96163d15..c66f4853 100644 --- a/amsn2/ui/front_ends/gtk/utility.py +++ b/amsn2/ui/front_ends/gtk/utility.py @@ -8,7 +8,7 @@ logger = logging.getLogger('amsn2.gtk.utility') class aMSNErrorWindow(base.aMSNErrorWindow, gtk.Dialog): - def __init__(self, error_text): + def __init__(self, error_text, title = "aMSN Error"): gtk.Dialog.__init__(self, None, None, gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) label = gtk.Label(error_text) @@ -16,6 +16,7 @@ def __init__(self, error_text): self.get_content_area().pack_start(label) label.show() self.connect("response", self.on_response) + gtk.Dialog.set_title(self, title) self.show() def on_response(self, dialog, id): @@ -28,7 +29,7 @@ def set_title(self, title): gtk.Dialog.set_title(self, title) class aMSNNotificationWindow(base.aMSNNotificationWindow, gtk.Dialog): - def __init__(self, notification_text): + def __init__(self, notification_text, title = "aMSN Notification"): gtk.Dialog.__init__(self, None, None, gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) label = gtk.Label(notification_text) @@ -36,6 +37,7 @@ def __init__(self, notification_text): self.get_content_area().pack_start(label) label.show() self.connect("response", self.on_response) + gtk.Dialog.set_title(self, title) self.show() def on_response(self, dialog, id): @@ -48,7 +50,7 @@ def set_title(self, title): gtk.Dialog.set_title(self, title) class aMSNDialogWindow(base.aMSNDialogWindow, gtk.Dialog): - def __init__(self, message, actions): + def __init__(self, message, actions, title = "aMSN Dialog"): gtk.Dialog.__init__(self, None, None, gtk.DIALOG_NO_SEPARATOR, None) label = gtk.Label(message) @@ -65,6 +67,7 @@ def __init__(self, message, actions): self.connect("response", self.on_response) label.show() + gtk.Dialog.set_title(self, title) self.show() def on_response(self, dialog, id): @@ -81,7 +84,7 @@ def set_title(self, title): gtk.Dialog.set_title(self, title) class aMSNContactInputWindow(base.aMSNContactInputWindow, gtk.Dialog): - def __init__(self, message, callback, groups): + def __init__(self, message, callback, groups, title = "aMSN Contact Input"): gtk.Dialog.__init__(self, None, None, gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) @@ -133,6 +136,7 @@ def __init__(self, message, callback, groups): ca.pack_start(inputbox, False) ca.pack_start(scrollwindow, True) + gtk.Dialog.set_title(self, title) self.connect("response", self.on_response) def _row_selected(self, dialog, row, boh): @@ -158,7 +162,7 @@ def set_title(self, title): gtk.Dialog.set_title(self, title) class aMSNGroupInputWindow(base.aMSNGroupInputWindow, gtk.Dialog): - def __init__(self, message, callback, contacts): + def __init__(self, message, callback, contacts, title = "aMSN Group Input"): gtk.Dialog.__init__(self, None, None, gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) @@ -204,6 +208,7 @@ def __init__(self, message, callback, contacts): #ca.pack_start(label1, False) ca.pack_start(scrollwindow, True) + gtk.Dialog.set_title(self, title) self.connect("response", self.on_response) def _row_selected(self, dialog, row, boh): @@ -228,7 +233,7 @@ def set_title(self, title): gtk.Dialog.set_title(self, title) class aMSNContactDeleteWindow(base.aMSNContactDeleteWindow, gtk.Dialog): - def __init__(self, message, callback, contacts): + def __init__(self, message, callback, contacts, title = "aMSN Delete Contact"): gtk.Dialog.__init__(self, None, None, gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) @@ -244,6 +249,7 @@ def __init__(self, message, callback, contacts): self.connect("response", self.on_response) label.show() self._name.show() + gtk.Dialog.set_title(self, title) self.show() def on_response(self, dialog, id): @@ -261,7 +267,7 @@ def set_title(self, title): gtk.Dialog.set_title(self, title) class aMSNGroupDeleteWindow(base.aMSNGroupDeleteWindow, gtk.Dialog): - def __init__(self, message, callback, groups): + def __init__(self, message, callback, groups, title = "aMSN Delete Group"): gtk.Dialog.__init__(self, None, None, gtk.DIALOG_NO_SEPARATOR, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT, gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT)) @@ -277,6 +283,7 @@ def __init__(self, message, callback, groups): self.connect("response", self.on_response) label.show() self._name.show() + gtk.Dialog.set_title(self, title) self.show() def on_response(self, dialog, id): diff --git a/amsn2/ui/front_ends/qt4/chat_window.py b/amsn2/ui/front_ends/qt4/chat_window.py index 79ccc388..a3d672c6 100644 --- a/amsn2/ui/front_ends/qt4/chat_window.py +++ b/amsn2/ui/front_ends/qt4/chat_window.py @@ -18,7 +18,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -import cgi import time import sys reload(sys) @@ -216,8 +215,7 @@ def on_user_typing(self, contact): def on_message_received(self, messageview, formatting=None): print "Ding!" - text = messageview.to_stringview().to_HTML_string() - text = cgi.escape(text) + text = messageview.to_stringview().parse_default_smileys().to_HTML_string() nick, msg = text.split('\n', 1) nick = nick.replace('\n', '
') msg = msg.replace('\n', '
') diff --git a/amsn2/ui/front_ends/qt4/choosers.py b/amsn2/ui/front_ends/qt4/choosers.py index e3d1c2a7..1bbfcd84 100644 --- a/amsn2/ui/front_ends/qt4/choosers.py +++ b/amsn2/ui/front_ends/qt4/choosers.py @@ -34,40 +34,49 @@ def __init__(self, filters, directory, callback, parent = None): -class aMSNDPChooserWindow(base.aMSNDPChooserWindow, QDialog): - def __init__(self, callback, backend_manager, parent = None): - QDialog.__init__(self, parent) - - self.resize(550, 450) - self.setWindowTitle("aMSN - Choose a Display Picture") - self.callback = callback - self.iconview = QListWidget() - self.iconview.setViewMode(1) - self.iconview.setResizeMode(1) - self.iconview.setMovement(0) - self.iconview.setIconSize(QSize(96,96)) - self.iconview.setWordWrap( True ) - self.iconview.setGridSize(QSize(106,121)) - QObject.connect(self.iconview, SIGNAL("itemDoubleClicked(QListWidgetItem)"), self._on_dp_dblclick) - self.buttonOk= QPushButton("Ok") - QObject.connect(self.buttonOk, SIGNAL("clicked()"), self._on_ok_clicked) - self.buttonCancel = QPushButton("Cancel") - QObject.connect(self.buttonCancel, SIGNAL("clicked()"), self.reject) - self.buttonOpen = QPushButton("Open File") - QObject.connect(self.buttonOpen, SIGNAL("clicked()"), self._open_file) - self.vboxlayout = QVBoxLayout() - self.hboxlayout = QHBoxLayout() - self.vboxlayout.addWidget(self.buttonOk) - self.vboxlayout.addWidget(self.buttonCancel) - self.vboxlayout.addWidget(self.buttonOpen) - self.vboxlayout.addStretch(1) - self.hboxlayout.addWidget(self.iconview) - self.hboxlayout.addLayout(self.vboxlayout) - self.setLayout(self.hboxlayout) +class aMSNDPChooserWindowSingleton(base.aMSNDPChooserWindow, QDialog): + def __init__(self): + self.firstTime = True + + def __call__(self, callback, backend_manager, title ="aMSN - Choose a Display Picture", parent = None): + if self.firstTime: + QDialog.__init__(self, parent) + self.iconview = QListWidget() + self.iconview.setViewMode(1) + self.iconview.setResizeMode(1) + self.iconview.setMovement(0) + self.iconview.setIconSize(QSize(96,96)) + self.iconview.setWordWrap( True ) + self.iconview.setGridSize(QSize(106,121)) + QObject.connect(self.iconview, SIGNAL("itemDoubleClicked(QListWidgetItem)"), self._on_dp_dblclick) + self.buttonOk= QPushButton("Ok") + QObject.connect(self.buttonOk, SIGNAL("clicked()"), self._on_ok_clicked) + self.buttonCancel = QPushButton("Cancel") + QObject.connect(self.buttonCancel, SIGNAL("clicked()"), self.reject) + QObject.connect(self, SIGNAL("rejected()"), self._on_reject) + self.buttonOpen = QPushButton("Open File") + QObject.connect(self.buttonOpen, SIGNAL("clicked()"), self._open_file) + self.vboxlayout = QVBoxLayout() + self.hboxlayout = QHBoxLayout() + self.vboxlayout.addWidget(self.buttonOk) + self.vboxlayout.addWidget(self.buttonCancel) + self.vboxlayout.addWidget(self.buttonOpen) + self.vboxlayout.addStretch(1) + self.hboxlayout.addWidget(self.iconview) + self.hboxlayout.addLayout(self.vboxlayout) + self.setLayout(self.hboxlayout) + default_dps = [] for dp in default_dps: self._update_dp_list(default_dps) - self.exec_() + self.resize(550, 450) + self.setWindowTitle(title) + self.callback = callback + self.show() + self.activateWindow() + self.firstTime = False + return self + def _open_file(self): filters = {'Image files':("*.png", "*.jpeg", "*.jpg", "*.gif", "*.bmp"), @@ -75,11 +84,22 @@ def _open_file(self): self.filechooser = aMSNFileChooserWindow(filters, None, self._update_dp_list,self) + def empty(self): + #self.iconview.clear() + pass #we should clear the view each time and re add all the images given by the core, but for now, no images are passed so i just leave the ones added and don't clear + + def _dp_chosen(self, path): - self.callback(str(path)) - self.done(0) - - + self.callback(str(path)) + self.accept() + self.empty() + self.done(-1) + + def _on_reject(self): + self.empty() + self.done(-1) + + def _on_ok_clicked(self): item = self.iconview.currentItem() if item == None: @@ -88,13 +108,21 @@ def _on_ok_clicked(self): path = item.data(Qt.UserRole) path = path.toString() self._dp_chosen(path) - + def _on_dp_dblclick(self, item): path = item.data(Qt.UserRole) path = path.toString() self._dp_chosen(path) - + + + def set_title(self, title): + self.setWindowTitle(title) + + + def show(self): + QDialog.show(self) + def _update_dp_list(self, dp_path): im = QPixmap(dp_path) #should pass the image to the core then get the rescaled pixmap from it @@ -103,4 +131,6 @@ def _update_dp_list(self, dp_path): name.remove(0, (name.lastIndexOf("/")+1)) item = QListWidgetItem(QIcon(im), name) item.setData(Qt.UserRole, dp_path) - self.iconview.addItem(item) \ No newline at end of file + self.iconview.addItem(item) + +aMSNDPChooserWindow = aMSNDPChooserWindowSingleton() \ No newline at end of file diff --git a/amsn2/ui/front_ends/qt4/contact_list.py b/amsn2/ui/front_ends/qt4/contact_list.py index 8d5e3307..641f2861 100644 --- a/amsn2/ui/front_ends/qt4/contact_list.py +++ b/amsn2/ui/front_ends/qt4/contact_list.py @@ -334,12 +334,16 @@ def contextMenuEvent(self, event): type = qvart.toString() view = qvarv.toPyObject() - #is the double-clicked item a contact? if type == "contact": menuview = view.on_right_click_popup_menu menu = QMenu("Contact Popup", self) common.create_menu_items_from_view(menu, menuview.items) menu.popup(event.globalPos()) + if type == "group": + menuview = view.on_right_click_popup_menu + menu = QMenu("Group Popup", self) + common.create_menu_items_from_view(menu, menuview.items) + menu.popup(event.globalPos()) def set_contact_context_menu(self, cb): #TODO: diff --git a/amsn2/ui/front_ends/qt4/utility.py b/amsn2/ui/front_ends/qt4/utility.py index 583bb964..79edc9e1 100644 --- a/amsn2/ui/front_ends/qt4/utility.py +++ b/amsn2/ui/front_ends/qt4/utility.py @@ -1,23 +1,57 @@ from amsn2.ui import base -from amsn2.core import views +from amsn2 import views from PyQt4.QtCore import * from PyQt4.QtGui import * class aMSNErrorWindow(base.aMSNErrorWindow, QMessageBox): - def __init__(self, error_text, parent = None): + def __init__(self, error_text, title = "aMSN Error", parent = None): QMessageBox.__init__(self, QMessageBox.Critical, "aMSN Error", error_text, QMessageBox.Ok, parent) - self.exec_() + self.setModal(False) + self.adress = self # Workaround to make the window not disapear as it is poped + QObject.connect(self, SIGNAL("finished(int)"), self.finish) + self.show() + + def set_title(self, title): + self.setWindowTitle(title) + + def show(self): + QDialog.show(self) + + def closeEvent(self, e): + self.finish() + e.accept() + + def finish(self, i = 0): + self.close() + self.deleteLater() class aMSNNotificationWindow(base.aMSNNotificationWindow, QMessageBox): - def __init__(self, notification_text, parent = None): + def __init__(self, notification_text, title = "aMSN Notification", parent = None): QMessageBox.__init__(self, QMessageBox.Information, "aMSN Notification", notification_text, QMessageBox.Ok, parent) - self.exec_() + self.setModal(False) + self.adress = self # Workaround to make the window not disapear as it is poped + QObject.connect(self, SIGNAL("finished(int)"), self.finish) + self.show() + + def set_title(self, title): + self.setWindowTitle(title) + + def show(self): + QDialog.show(self) + + def closeEvent(self, e): + self.finish() + e.accept() + + def finish(self, i = 0): + self.close() + self.deleteLater() class aMSNDialogWindow(base.aMSNDialogWindow, QMessageBox): - def __init__(self, message, actions, parent = None): + def __init__(self, message, actions, title = "aMSN Dialog", parent = None): QMessageBox.__init__(self, QMessageBox.Information, "aMSN Dialog", message, QMessageBox.NoButton, parent) for action in actions: @@ -25,135 +59,278 @@ def __init__(self, message, actions, parent = None): button = QPushButton(name) QObject.connect(button, SIGNAL("clicked()"), callback) self.addButton(button, QMessageBox.AcceptRole) - self.exec_() - -class aMSNContactInputWindow(base.aMSNContactInputWindow, QDialog): - def __init__(self, message, callback, groups, parent = None): - QDialog.__init__(self, parent) - self.setWindowTitle("aMSN Contact Input") - self._callback = callback + self.setModal(False) self.adress = self # Workaround to make the window not disapear as it is poped + QObject.connect(self, SIGNAL("finished(int)"), self.finish) + self.show() + + def set_title(self, title): + self.setWindowTitle(title) + + def show(self): + QDialog.show(self) - self.vboxlayout = QVBoxLayout() - label = QLabel(message[0]) - self.vboxlayout.addWidget(label) - self._name = QLineEdit() - self.vboxlayout.addWidget(self._name) - - # TODO: build list of existing groups - label2 = QLabel(message[1]) - self.vboxlayout.addWidget(label2) - self._message = QLineEdit() - self.vboxlayout.addWidget(self._message) - - self.buttonbox = QDialogButtonBox() - self.buttonOk = QPushButton("Ok", self) - QObject.connect(self.buttonOk, SIGNAL("clicked()"), self.onOk) - self.buttonbox.addButton(self.buttonOk,QDialogButtonBox.ActionRole) - self.buttonCancel = QPushButton("Cancel", self) - QObject.connect(self.buttonCancel, SIGNAL("clicked()"), self.onCancel) - self.buttonbox.addButton(self.buttonCancel,QDialogButtonBox.ActionRole) - self.vboxlayout.addWidget(self.buttonbox) - - self.setLayout(self.vboxlayout) + def closeEvent(self, e): + self.finish() + e.accept() + def finish(self, i = 0): + self.close() + self.deleteLater() + + +class aMSNContactInputWindowSingleton(base.aMSNContactInputWindow, QDialog): + def __init__(self): + self.firstTime = True + + def __call__(self, message, callback, groups, title = "aMSN Contact Input", parent = None): + if self.firstTime : + QDialog.__init__(self, parent) + + self.vboxlayout = QVBoxLayout() + self.hboxlayout1 = QHBoxLayout() + self.label = QLabel() + self.hboxlayout1.addWidget(self.label) + self._name = QLineEdit() + self.hboxlayout1.addWidget(self._name) + self.vboxlayout.addLayout(self.hboxlayout1) + + self.hboxlayout2 = QHBoxLayout() + self.label2 = QLabel() + self.hboxlayout2.addWidget(self.label2) + self._message = QLineEdit() + self.hboxlayout2.addWidget(self._message) + self.vboxlayout.addLayout(self.hboxlayout2) + + self.scrollarea = QScrollArea() + self.scrollvbox = QVBoxLayout() + self.scrollarea.setLayout(self.scrollvbox) + self.vboxlayout.addWidget(self.scrollarea) + + self.buttonbox = QDialogButtonBox() + + self.buttonOk = QPushButton("Ok", self) + QObject.connect(self.buttonOk, SIGNAL("clicked()"), self.accept) + QObject.connect(self, SIGNAL("accepted()"), self.onOk) + self.buttonbox.addButton(self.buttonOk,QDialogButtonBox.ActionRole) + + self.buttonCancel = QPushButton("Cancel", self) + QObject.connect(self.buttonCancel, SIGNAL("clicked()"), self.reject) + QObject.connect(self, SIGNAL("rejected()"), self.onCancel) + self.buttonbox.addButton(self.buttonCancel,QDialogButtonBox.ActionRole) + + self.vboxlayout.addWidget(self.buttonbox) + + self.setLayout(self.vboxlayout) + + self.dicgroups = {} + for group in groups: + checkbox = QCheckBox(group.name.to_HTML_string()) + self.scrollvbox.addWidget(checkbox) + self.dicgroups[checkbox] = group + self.spacer = QWidget() + self.scrollvbox.addWidget(self.spacer, 1) + + self.setWindowTitle(title) + self.label.setText(message[0]) + self.label2.setText(message[1]) + self.firstTime = False + self._callback = callback self.show() + self.activateWindow() + return self + + def set_title(self, title): + self.setWindowTitle(title) + + def show(self): + QDialog.show(self) + + def empty(self): + self._name.clear() + self._message.clear() + for checkbox in self.dicgroups: + checkbox.setParent = None + checkbox.deleteLater() + self.spacer.setParent = None + self.spacer.deleteLater() def onOk(self): name = str(self._name.text()) msg = str(self._message.text()) - self._callback(name, msg) - self.done(0) - self.deleteLater() + selectedgroups = [] + for checkbox in self.dicgroups: + if checkbox.isChecked(): + selectedgroups.append(self.dicgroups[checkbox].uid) + self._callback(name, msg, selectedgroups) + self.empty() + self.done(-1) def onCancel(self): - self.done(0) - self.deleteLater() - + self.empty() + self.done(-1) -class aMSNGroupInputWindow(base.aMSNGroupInputWindow, QDialog): - def __init__(self, message, callback, contacts, parent = None): - QDialog.__init__(self, parent) - self.setWindowTitle("aMSN Group Input") +aMSNContactInputWindow = aMSNContactInputWindowSingleton() + +class aMSNGroupInputWindowSingleton(base.aMSNGroupInputWindow, QDialog): + def __init__(self): + self.firstTime = True + + def __call__(self, message, callback, contacts, title = "aMSN Group Input", parent = None): + if self.firstTime : + QDialog.__init__(self, parent) + + self.vboxlayout = QVBoxLayout() + self.label = QLabel() + self.vboxlayout.addWidget(self.label) + self._name = QLineEdit() + self.vboxlayout.addWidget(self._name) + + self.scrollarea = QScrollArea() + self.scrollvbox = QVBoxLayout() + self.scrollarea.setLayout(self.scrollvbox) + self.vboxlayout.addWidget(self.scrollarea) + + self.buttonbox = QDialogButtonBox() + + self.buttonOk = QPushButton("Ok", self) + QObject.connect(self.buttonOk, SIGNAL("clicked()"), self.accept) + QObject.connect(self, SIGNAL("accepted()"), self.onOk) + self.buttonbox.addButton(self.buttonOk,QDialogButtonBox.ActionRole) + + self.buttonCancel = QPushButton("Cancel", self) + QObject.connect(self.buttonCancel, SIGNAL("clicked()"), self.reject) + QObject.connect(self, SIGNAL("rejected()"), self.onCancel) + self.buttonbox.addButton(self.buttonCancel,QDialogButtonBox.ActionRole) + + self.vboxlayout.addWidget(self.buttonbox) + + self.setLayout(self.vboxlayout) + + self.diccontacts = {} + for contact in contacts: + checkbox = QCheckBox(str(contact.name)) + self.scrollvbox.addWidget(checkbox) + self.diccontacts[checkbox] = contact + self.spacer = QWidget() + self.scrollvbox.addWidget(self.spacer, 1) + + self.setWindowTitle(title) + self.label.setText(message[0]) + self.firstTime = False self._callback = callback - self.adress = self # Workaround to make the window not disapear as it is poped + self.show() + self.activateWindow() + return self - self.vboxlayout = QVBoxLayout() - label = QLabel(message[0]) - self.vboxlayout.addWidget(label) - self._name = QLineEdit() - self.vboxlayout.addWidget(self._name) - - # TODO: build list of existing contacts - label2 = QLabel(message[1]) # Done like the GTK implementation but i really don't get what these second label and lineEdit are for ... - self.vboxlayout.addWidget(label2) - self._message = QLineEdit() - self.vboxlayout.addWidget(self._message) - - self.buttonbox = QDialogButtonBox() - self.buttonOk = QPushButton(self, "Ok") - QObject.connect(buttonOk, SIGNAL("clicked()"), self.onOk) - self.buttonbox.addButton(self.buttonOk) - self.buttonCancel = QPushButton(self, "Cancel") - QObject.connect(buttonCancel, SIGNAL("clicked()"), self.onCancel) - self.buttonbox.addButton(self.buttonCancel) - self.vboxlayout.addWidget(self.buttonbox) - - self.addLayout(vboxlayout) + def set_title(self, title): + self.setWindowTitle(title) - self.show() + def show(self): + QDialog.show(self) + + def empty(self): + self._name.clear() + for checkbox in self.diccontacts: + checkbox.setParent = None + checkbox.deleteLater() + self.spacer.setParent = None + self.spacer.deleteLater() def onOk(self): name = str(self._name.text()) - self._callback(name) - self.done(0) + selectedcontacts = [] + for checkbox in self.diccontacts: + if checkbox.isChecked(): + selectedcontacts.append(self.diccontacts[checkbox].account) + self._callback(name, selectedcontacts) + self.empty() + self.done(-1) self.deleteLater() def onCancel(self): - self.done(0) - self.deleteLater() + self.empty() + self.done(-1) -class aMSNContactDeleteWindow(base.aMSNContactDeleteWindow, QInputDialog): - def __init__(self, message, callback, contacts, parent = None): - QInputDialog.__init__(self, parent) - self._callback = callback - self.adress = self # Workaround to make the window not disapear as it is poped - self.setWindowTitle("aMSN Contact Input") - self.setInputMode(QInputDialog.TextInput) - self.setLabelText(message) - QObject.connect(self, SIGNAL("accepted()"), self.onOk) - QObject.connect(self, SIGNAL("rejected()"), self.onCancel) +aMSNGroupInputWindow = aMSNGroupInputWindowSingleton() + + +class aMSNContactDeleteWindowSingleton(base.aMSNContactDeleteWindow, QInputDialog): + def __init__(self): + self.firstTime = True + + def __call__(self, message, callback, contacts, title = "aMSN Delete Contact", parent = None): + if self.firstTime : + QInputDialog.__init__(self, parent) + self.setInputMode(QInputDialog.TextInput) + QObject.connect(self, SIGNAL("accepted()"), self.onOk) + QObject.connect(self, SIGNAL("rejected()"), self.onCancel) + self._callback = callback + self.setWindowTitle(title) + self.setLabelText(message[0]) + self.firstTime = False self.show() + self.activateWindow() + return self + + def set_title(self, title): + self.setWindowTitle(title) + + def show(self): + QDialog.show(self) + + def empty(self): + self.setTextValue("") def onOk(self): self._callback(str(self.textValue())) + self.empty() self.done(-1) - self.deleteLater() def onCancel(self): + self.empty() self.done(-1) - self.deleteLater() -class aMSNGroupDeleteWindow(base.aMSNGroupDeleteWindow, QInputDialog): - def __init__(self, message, callback, contacts, parent = None): - QInputDialog.__init__(self, parent) - self._callback = callback - self.adress = self # Workaround to make the window not disapear as it is poped - self.setWindowTitle("aMSN Group Input") - self.setInputMode(QInputDialog.TextInput) - self.setLabelText(message) - QObject.connect(self, SIGNAL("accepted()"), self.onOk) - QObject.connect(self, SIGNAL("rejected()"), self.onCancel) +aMSNContactDeleteWindow = aMSNContactDeleteWindowSingleton() + + +class aMSNGroupDeleteWindowSingleton(base.aMSNGroupDeleteWindow, QInputDialog): + def __init__(self): + self.firstTime = True + + def __call__(self, message, callback, contacts, title = "aMSN Delete Group", parent = None): + if self.firstTime : + QInputDialog.__init__(self, parent) + self.setInputMode(QInputDialog.TextInput) + QObject.connect(self, SIGNAL("accepted()"), self.onOk) + QObject.connect(self, SIGNAL("rejected()"), self.onCancel) + self._callback = callback + self.setWindowTitle(title) + self.setLabelText(message[0]) + self.firstTime = False self.show() + self.activateWindow() + return self + + def set_title(self, title): + self.setWindowTitle(title) + + def show(self): + QDialog.show(self) + + def empty(self): + self.setTextValue("") def onOk(self): self._callback(str(self.textValue())) + self.empty() self.done(-1) - self.deleteLater() def onCancel(self): - self.done(-1) - self.deleteLater() \ No newline at end of file + self.empty() + self.done(-1) + +aMSNGroupDeleteWindow = aMSNGroupDeleteWindowSingleton() \ No newline at end of file diff --git a/amsn2/views/stringview.py b/amsn2/views/stringview.py index a1744bce..b6e37e1c 100644 --- a/amsn2/views/stringview.py +++ b/amsn2/views/stringview.py @@ -18,6 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import cgi class StringView (object): TEXT_ELEMENT = "text" @@ -30,6 +31,7 @@ class StringView (object): BOLD_ELEMENT = "bold" UNDERLINE_ELEMENT = "underline" FONT_ELEMENT = "font" + SMILEY_ELEMENT = "smiley" # padding ? @@ -74,9 +76,14 @@ def __init__(self, italic): class UnderlineElement(StringElement): def __init__(self, underline): StringView.StringElement.__init__(self, StringView.UNDERLINE_ELEMENT, underline) + class SmileyElement(StringElement): + def __init__(self, (image, alt)): + StringView.StringElement.__init__(self, StringView.SMILEY_ELEMENT, (image, alt)) def __init__(self, default_background_color = None, default_color = None, default_font = None): self._elements = [] + from amsn2.core import aMSNCore + self._core = aMSNCore() self._default_background_color = default_background_color self._default_color = default_color @@ -92,6 +99,8 @@ def __init__(self, default_background_color = None, default_color = None, defaul def append(self, type, value): self._elements.append(StringView.StringElement(type, value)) + def append_smiley(self, image, alt): + self._elements.append(StringView.SmileyElement((image, alt))) def append_stringview(self, strv): #TODO: default (bg)color self._elements.extend(strv._elements) @@ -132,13 +141,39 @@ def reset_background_color(self): def reset_font(self): self.set_font(self._default_font) + def parse_default_smileys(self): + new_stringview = self + theme_manager = self._core._theme_manager + smiley_manager = self._core._smiley_manager + for shortcut in smiley_manager.default_smileys_shortcuts: + temp_stringview = StringView() + for element in new_stringview._elements: + if element.get_type() == StringView.TEXT_ELEMENT: + finished = False + text = element.get_value() + while (finished == False): + pos = text.find(shortcut) + if (pos == -1): + pos = text.upper().find(shortcut) + if (pos == -1): + finished = True + temp_stringview.append_text(text) + else: + temp_stringview.append_text(text[:pos]) + temp_stringview.append_smiley(theme_manager.get_smiley(smiley_manager.default_smileys_shortcuts[shortcut])[1], shortcut) #the [1] is because the theme manager returns a tuple + text = text[pos+len(shortcut):] + else: + temp_stringview.append(element.get_type(), element.get_value()) + new_stringview = temp_stringview + return new_stringview + def to_HTML_string(self): """ This method returns a formatted html string with all the data in the stringview """ out = "" for x in self._elements: if x.get_type() == StringView.TEXT_ELEMENT: - out += x.get_value() + out += cgi.escape(x.get_value()) elif x.get_type() == StringView.ITALIC_ELEMENT: if x.get_value() == True: out += "" @@ -151,6 +186,8 @@ def to_HTML_string(self): out += "" elif x.get_type() == StringView.IMAGE_ELEMENT: out += "" + elif x.get_type() == StringView.SMILEY_ELEMENT: + out += "" elif x.get_type() == StringView.UNDERLINE_ELEMENT: if x.get_value() == True: out += ""