Compare commits

...

2 Commits

Author SHA1 Message Date
Mario Fetka 3179f447ce Import release 2.0.3 2010-03-10 13:51:09 +00:00
Mario Fetka 9c0c6480e3 Import release 2.0.2 2009-12-04 22:51:32 +00:00
73 changed files with 36446 additions and 14927 deletions
+2
View File
@@ -0,0 +1,2 @@
build
.DS_Store
+14 -2
View File
@@ -28,7 +28,7 @@
Mauricio Rother <mauricio@digicomm.com.br>
Leonel Freire <leonelfreire@gmail.com>
Sergio Rafael Lemke <bedi.com@gmail.com>
Maurício Arozi Moraes
Morris Arozi Moraes
Catalan:
@@ -58,7 +58,7 @@
Jaap Woldringh <jjh.woldringh@planet.nl>
Elve <elve@savage-elve.net>
Sander Pientka <cumulus0007@gmail.com>
Heimen Stoffels <djmusic121@gmail.com>
Heimen Stoffels <vistausss@gmail.com>
Estonian:
@@ -118,6 +118,14 @@
Øyvind Sæther <oyvind@sather.tk>
Portuguese:
Bruno Almeida <bruno.r.almeida@gmail.com>
Russian:
Dmitriy Simbiriatin <slpiv@mail.ru>
Serbian:
Zoran Milovanović <provalisam@gmail.com>
@@ -229,6 +237,10 @@
- Emoticon preview in settings page
- Clickable contact properties dialog text
Marco Mentasti <marcomentasti@gmail.com>
- Internationalization fixes
- Drag'n'drop of images into display pictures
KMerlin <http://kmerlin.olsd.de/>
- Inspiration and assorted code
+64 -59
View File
@@ -13,59 +13,64 @@ CMAKE_MINIMUM_REQUIRED( VERSION 2.4.5 )
# Check for KDE 4
FIND_PACKAGE( KDE4 REQUIRED )
INCLUDE( KDE4Defaults )
# Make sure the rest still works
IF( NOT KDE4_FOUND )
# The macro's MACRO_LOG_FEATURE, MACRO_OPTIONAL_FIND_PACKAGE, MACRO_BOOL_TO_01
# are part of the KDE cmake modules, so these can't be used now.
MESSAGE( FATAL_ERROR "\n"
" The KDE Development Platform was not found.\n"
" \n"
" You will need this package and the matching development package.\n"
" Usually the package names for this library are:\n"
" on Debian: 'kdebase-runtime' and 'kdelibs4-dev'\n"
" on Ubuntu: 'kdebase-runtime' and 'kdelibs5-dev'\n"
" on openSUSE: 'kdebase4-runtime' and 'libkde4-devel'\n"
" \n"
" Please refer to the KMess board for more info,\n"
" and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
ENDIF( NOT KDE4_FOUND )
# Check for libxml2
FIND_PACKAGE( LibXml2 )
MACRO_LOG_FEATURE( LIBXML2_FOUND "LibXML2" "Libraries used to develop XML-aware applications" "http://www.xmlsoft.org/" TRUE ""
" Required for the chat styles system.
* You will need this package and the matching development package: for example, 'kmess' and 'kmess-dev' or 'kmess-devel'.
* Usually the package names for this library are:
on Ubuntu: 'libxml2' and 'libxml2-dev'
on openSUSE: 'libxml2' and 'libxml2-devel'
* Please refer to the KMess board for more info, and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
"Required for the chat styles system.
* You will need this package and the matching development package: for example, 'libxml2' and 'libxml2-dev' or 'libxml2-devel'.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libxml2' and 'libxml2-dev'
on openSUSE: 'libxml2' and 'libxml2-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
# Check for libxslt
FIND_PACKAGE( LibXslt )
MACRO_LOG_FEATURE( LIBXSLT_FOUND "LibXSLT" "A library to transform XML into other formats" "http://www.xmlsoft.org/XSLT" TRUE ""
" Required for the chat styles system.
* You will need this package and the matching development package: for example, 'kmess' and 'kmess-dev' or 'kmess-devel'.
* Usually the package names for this library are:
on Ubuntu: 'libxslt' and 'libxslt-dev'
on openSUSE: 'libxslt' and 'libxslt-devel'
* Please refer to the KMess board for more info, and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
"Required for the chat styles system.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libxslt' and 'libxslt-dev'
on openSUSE: 'libxslt' and 'libxslt-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
# Check for qca2
FIND_PACKAGE( QCA2 )
MACRO_LOG_FEATURE( QCA2_FOUND "QCA 2" "A cryptographic library written in Qt to access various encryption methods" "http://delta.affinix.com/qca/" TRUE ""
" Required for the Windows Live Messenger login process.
* You will need this package and the matching development package: for example, 'kmess' and 'kmess-dev' or 'kmess-devel'.
* Usually the package names for this library are:
on Ubuntu: 'libqca2', 'libqca2-dev' and 'libqca2-plugin-ossl'
on openSUSE: 'libqca2' and 'libqca2-devel'
on Fedora: 'qca2' and 'qca2-devel'
* Please refer to the KMess board for more info, and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
# Add cmake directory to the MODULE_PATH, so cmake can find GCrypt
SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} $ENV{CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake )
# As far as I know, it is impossible to find out if the required QCA plugin for OpenSSL is installed:
# so we need to ask QCA itself it it's got such a plugin. Pretty darned unportable stuff.
IF( QCA2_FOUND )
IF( UNIX )
EXECUTE_PROCESS( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cmake/check-qca2-ossl.sh OUTPUT_VARIABLE HAS_QCA2_OSSL_PLUGIN )
IF( HAS_QCA2_OSSL_PLUGIN EQUAL 1 )
SET( QCA2_OSSL_PLUGIN_FOUND TRUE )
ELSE( HAS_QCA2_OSSL_PLUGIN EQUAL 1 )
SET( QCA2_OSSL_PLUGIN_FOUND FALSE )
ENDIF( HAS_QCA2_OSSL_PLUGIN EQUAL 1 )
MACRO_LOG_FEATURE( QCA2_OSSL_PLUGIN_FOUND "QCA 2 - OpenSSL Plugin" "OpenSSL interaction library for QCA2" "http://delta.affinix.com/qca/" TRUE ""
" Required for the Windows Live Messenger login process.
* This package should have been installed along QCA2: if you have QCA2 installed
but still see this message, your distribution probably packages it separately.
Ubuntu does this, the package name is 'libqca2-plugin-ossl'.
* Please refer to the KMess forum for more info, and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
ELSE( UNIX )
# TODO: Find another *portable* way to detect the OSSL plugin.
MESSAGE( STATUS "NOTE: The qca2 OpenSSL can't be detected on this platform yet. Make sure you have it installed." )
ENDIF( UNIX )
ENDIF( QCA2_FOUND )
# Check for GCrypt
FIND_PACKAGE( GCrypt )
IF( NOT GCRYPT_FOUND )
MACRO_LOG_FEATURE( GCRYPT_FOUND "GCrypt" "A library to encrypt messages with various cyphers" "http://www.gnupg.org/" TRUE ""
"It is required for the Live Messenger login process.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libgcrypt' and 'libgcrypt-dev'
on openSUSE: 'libgcrypt' and 'libgcrypt-devel'
on Fedora: 'gcrypt' and 'gcrypt-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
ELSE()
MESSAGE( STATUS "Looking for GCrypt - found" )
ENDIF()
# Check for XScreenSaver extension
OPTION( WANT_XSCREENSAVER "Build with X11 screensaver auto-away support" ON )
@@ -74,11 +79,12 @@ IF( WANT_XSCREENSAVER )
MACRO_OPTIONAL_FIND_PACKAGE(X11)
IF( X11_FOUND )
MACRO_LOG_FEATURE( X11_Xscreensaver_FOUND "XScreenSaver" "X11 extension used to check idle state" "" FALSE ""
" Required for the auto-away feature.
* Usually the package names for this library are:
on Ubuntu: 'libxss-dev'
on openSUSE: 'xorg-x11-libs'
* Please refer to the KMess board for more info, and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
"Required for the auto-away feature.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libxss-dev'
on openSUSE: 'xorg-x11-libs'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
ELSE( X11_FOUND )
MESSAGE( STATUS "NOTE: The auto-away feature is not supported on this platform yet." )
ENDIF( X11_FOUND )
@@ -89,19 +95,18 @@ ENDIF( WANT_XSCREENSAVER )
# (for an optional feature, we don't want that to be fatal)
MACRO_OPTIONAL_FIND_PACKAGE( LibKonq QUIET )
MACRO_LOG_FEATURE( LIBKONQ_FOUND "LibKonq" "Integration with Konqueror context menu" "http://www.kde.org/" FALSE ""
" Optional context menu integration with Konqueror.
* You will need this package and the matching development package: for example, 'kmess' and 'kmess-dev' or 'kmess-devel'.
* Usually the package names for this library are:
on Ubuntu: 'libkonq5' and 'libkonq5-dev'
on openSUSE: 'libkonq5' and 'libkonq-devel'
* Please refer to the KMess board for more info, and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
"This is an optional feature.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libkonq5' and 'libkonq5-dev'
on openSUSE: 'libkonq5' and 'libkonq-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
# Check for libisf-qt
MACRO_OPTIONAL_FIND_PACKAGE( IsfQt QUIET )
MACRO_LOG_FEATURE( ISFQT_FOUND "LibISF-Qt" "Library to manage Microsoft's Mobile Ink" "http://www.kmess.org/" FALSE ""
" Support to send handwriting messages in a format compatible with Windows Live Messenger.
In absence of an installed isf-qt version, the bundled version will be compiled.")
"Support to send handwriting messages in a format compatible with Windows Live Messenger.
In absence of an installed isf-qt version, the bundled version will be compiled.")
MACRO_BOOL_TO_01( ISFQT_FOUND HAVE_LIBISFQT ) # For config-kmess.h.in
# Display the dependency collection results
@@ -134,7 +139,7 @@ INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${LIBXM
# Switch between the following two commands to force using a predefined version number
# EXECUTE_PROCESS( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cmake/get-svn-version.sh OUTPUT_VARIABLE KMESS_VERSION )
SET( KMESS_VERSION "2.0.1" )
SET( KMESS_VERSION "2.0.3" )
#### Define compiler flags ####
@@ -162,7 +167,7 @@ ENDIF( CMAKE_COMPILER_IS_GNUCXX )
# - relwithdebinfo (release with debug info)
# - minsizerel (minsize release)
# Uncomment the next line to always force building in full debug mode
# SET( CMAKE_BUILD_TYPE debugfull )
SET( CMAKE_BUILD_TYPE debugfull )
# Enable the KMess debug output when compiling a debug build
IF( CMAKE_BUILD_TYPE STREQUAL debugfull OR KMESS_DEBUG_OUTPUT EQUAL 1 )
+168 -3
View File
@@ -1,4 +1,169 @@
--- 2.0.3 released ---
2010-03-09 (Pano)
* Merged a Russian translation by Dmitriy Simbiriatin.
2010-03-05 (Pano)
* Merged an updated Japanese translation by Daniel E. Moctezuma.
* Merged an updated Slovak translation by Rastislav Krupanský.
2010-03-02 (Pano)
* Merged an updated Traditional Chinese translation by Yen-chou Chen.
2010-03-01 (Pano)
* Merged an updated Spanish translation by Mauricio Muñoz Lucero.
* Merged an updated Turkish translation by Uğur Çetin.
* Merged an updated Portuguese translation by Bruno Almeida.
* Merged an updated Estonian translation by Rivo Laks.
2010-02-28 (Pano)
* Merged an updated Greek translation by Dimitrios Glentadakis.
2010-02-27 (Pano)
* Merged an updated German translation.
* Merged an updated Catalan translation by Adrià Arrufat.
* Merged an updated Brazilian Portuguese translation by Morris Arozi Moraes.
* Merged an updated Dutch translation by Heimen Stoffels.
2010-02-26 (Pano)
* Merged an updated French translation by Grégory Bellier.
2010-02-25 (Pano)
* Merged an updated Hungarian translation by Pauli Henrik.
2010-02-22 (Pano)
* Added a Portuguese translation by Bruno Almeida.
2010-02-21 (Adam)
* Bug fix: ink editor was greyed out when changing tabs.
2010-02-20 (Ruben)
* Added DBus methods to get and set a personal message.
2010-02-20 (Adam)
* Backport: fix "contact added user" dialog appearing on next logon after deleting a contact.
2010-02-19 (Adam)
* Disable the reverse list colouring of the CL until we sort out the updating of membership lists.
2010-02-18 (Adam)
* Re-enable the password edit field in AccountSettingsDialog.
* Format times in text log files according to KLocale.
2010-02-16 (Adam)
* Fix a bug where the window size was not saved/reloaded properly on chat window close. See the comments
in chatwindow.cpp, line 1395 however.
2010-01-13 (Adam)
* Backport: properly update UI when choosing to connect with a different account whilst connection is in progress.
2010-01-29 (Ruben)
* Trunk backport: Added workaround where "last seen" and/or "last message" are in the year 2106.
2010-01-28 (Pano)
* Merged an updated Traditional Chinese translation by Yen-chou Chen.
* Merged an updated Dutch translation by Sjors Gielen.
2010-01-24 (Adam)
* New feature: if proxy connection fails, remove proxy details and try again.
2010-01-24 (Pano)
* Added a Russian translation by Dmitriy Simbiriatin.
2010-01-21 (Ruben)
* Improved layout flexibility of the contact properties dialog. (Trunk backport)
2010-01-20 (Pano)
* Merged an updated Brazilian Portuguese translation by Morris Arozi Moraes.
2010-01-19 (Adam)
* Bump copyright years.
* Bug fix: correctly parse MSN color information in chat messages.
* Bump version to 2.0.3dev.
2010-01-17 (Adam)
* Bug fix: friendly names weren't shown in Ink error messages.
* Bug fix: Ink validation failed if there were trailing \r\n characters; trim them out first.
* Bug fix: fixed long standing crash that occurred with InvitedContacts and restarted chats.
Reported by Ralesk.
2010-01-16 (Pano)
* Merged an updated Greek translation by Dimitrios Glentadakis.
2010-01-15 (Ruben)
* Merged improved patch by Mamadou Gueye, to show email count in systray tooltip.
2010-01-09 (Pano)
* Updated message catalogs (POT and PO files)
2010-01-08 (sifcenter)
* Use the SOAP reply into QDocDocument to indent and print it.
* Added a small tooltip for the image in contact properties dialog.
2010-01-08 (Valerio)
* Improved the sizes of the friendly name and personal message labels on the
Contact List.
* Added a workaround to a KDE bug, requiring the spell checker to be set twice
when switching between tabs.
2010-01-06 (Pano)
* Merged an updated French translation by Grégory Bellier.
2010-01-02 (Valerio)
* Merged patch by Mentos, fixing emoticon encoding issues in chat logs.
* Merged patch by Mentos, fixing a bug when setting a custom display picture
to a contact.
* Merged patch by Mentos, which enables dragging and dropping of images
into display picture frames.
* Fixed issue with empty personal messages on login showing an empty message
instead of the default message.
2009-12-31 (Valerio)
* Replaced the contact list friendlyname and PM labels with new labels
editable inline by clicking.
2009-12-29 (Valerio)
* Removed code to change the size of the displayed picture in chat.
* Merged patch by Mentos, fixing emoticon encoding issues.
* Merged patch by ipereira, adding translator details in the pot files.
2009-12-23 (Adam)
* After discussion with Sjors reverted QtWebKit commit. Will be moved into a branch
where it can be stabilised before being moved back into trunk or 2.0.x.
2009-12-23 (Sjors)
* Replaced QCA with GCrypt. This makes Mac and Windows builds much, much
easier and removes the support hell QCA used to be, because it required
OpenSSL plugins and that stuff.
2009-12-19 (Sjors)
* Removed KHTML in favor of QtWebKit. This will help us make Qt-only builds for Windows and Mac.
* Also removed KUrl in favor of QUrl, since they are almost the same anyway.
2009-12-15 (Valerio)
* Fixed a meaningless error dialog when logging in with accounts which have
added the Messenger official email address to the contact list.
2009-12-08 (Valerio)
* Fixed a crash which occurred when trying to login with the wrong password.
2009-12-05 (Adam)
* Fix a crash bug that can occur when we receive a CHG earlier than we should.
--- 2.0.2 released ---
2009-12-04 (Pano)
* Merged an updated Japanese translation by Daniel E. Moctezuma.
2009-12-03 (Sjors)
* Fixed a bug introduced just before 2.0.1 release, making it impossible to
log in twice in the same KMess run.
2009-12-02 (Pano)
* Merged an updated Brazilian Portuguese translation by Maurício Arozi Moraes.
* Merged an updated Traditional Chinese translation by Yen-chou Chen.
--- 2.0.1 released ---
2009-11-30 (Sjors)
@@ -69,7 +234,7 @@
2009-11-02 (Adam)
* Ensure the height of items in the contact list is sufficient to fully
display the contact name and PSM (strings got cut off when people used large
display the contact name and PSM (strings got cut off when people used large
KDE font sizes).
* Increase the notification unlock timeout to 10 seconds after the last ILN.
* Allow the download/upload buttons in the transfer window to expand to show their
@@ -106,14 +271,14 @@
* Store display name on roaming service but do not use it for display (in line with WLM).
* Remove duplicate "Show Statusbar" from the list of shortcuts.
* Fix updating of display picture with the roaming service.
* Change keystrokes for scrolling in chat message view - pgdn/pgup = scroll, alt+pgdn/pgup = fast scroll.
* Change keystrokes for scrolling in chat message view - pgdn/pgup = scroll, alt+pgdn/pgup = fast scroll.
Fixes a clash with the text editor which caused the view to scroll when shift+pg selecting text in the editor.
2009-10-22 (Adam)
* Fix build error introduced in r5567. My bad.
* Fix a crash bug that was introduced with a previous fix. Previous fix has been reverted pending better solution.
* Improve fix for KDE bug #209960.
* Stop writing bad "last seen date" and "last message date" values when saving contact list.
* Stop writing bad "last seen date" and "last message date" values when saving contact list.
2009-10-21 (Adam)
* Cache last display names of contacts; works around an issue where the AddressBook service
+1 -1
View File
@@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = KMess
PROJECT_NUMBER = 2.0.1
PROJECT_NUMBER = 2.0.3
OUTPUT_DIRECTORY = ./apidocs
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
+9 -1
View File
@@ -1,5 +1,13 @@
KMess Feature list
========================
- 2.0.3 -
Setting your friendly name and personal message by clicking on their labels in the contact list.
A display of the unread email count in the system tray tooltip.
Ability to change personal message using DBus.
- 2.0.2 -
Enabled drag-and-drop of images into display picture frames.
- 2.0.1 -
Synchronization of friendly names, personal messages and display pictures with Messenger.
Support to send screenshots by dragging and dropping them to a chat.
@@ -103,4 +111,4 @@ Chats can be configured to show timestamps when contacts send messages.
A "compact" chat format can be used to remove extraneous line breaks and reduce the size of the chat.
The chat window caption in the taskbar alternates between lower and upper case to inform the user of a received message when the window is not on top.
Internationalization support, with translations in: English, Dutch, German, Italian, Portuguese, Spanish, Turkish, Chinese, French, Catalan, Arabic, Korean, Norsk, Thai, Danish, and Estonian
There is now a method, though not absolute, to tell if a contact is blocking you. If a chat is started with a contact that appears offline, you will be informed if the contact is offline or online and blocking you.
There is now a method, though not absolute, to tell if a contact is blocking you. If a chat is started with a contact that appears offline, you will be informed if the contact is offline or online and blocking you.
+38 -1
View File
@@ -1,3 +1,40 @@
Changes between KMess 2.0.3 and 2.0.2:
--------------------------------------
- added ability to drag-and-drop images into display picture frames.
- added setting friendly name and personal message by clicking on their labels in the contact list.
- added Russian translation by Dmitriy Simbiriatin.
- added Portuguese translation by Bruno Almeida.
- added showing unread email count in the system tray tooltip.
- added setting personal message using DBus.
- fixed crash when logging in with the wrong password.
- fixed bug causing the "Contact Added User" dialog to appear after deleting contacts.
- fixed bug causing the chat window size to not be saved under KDE 4.4.
- improved performance when drawing complex ink messages.
- improved proxy support.
- updated French translation by Grégory Bellier.
- updated Catalan translation by Adrià Arrufat.
- updated German translation by Panagiotis Papadopoulos.
- updated Greek translation by Dimitrios Glentadakis.
- updated Brazilian Portuguese translation by Morris Arozi Moraes.
- updated Traditional Chinese translation by Yen-chou Chen.
- updated Dutch translation by Sjors Gielen.
- updated Dutch translation by Heimen Stoffels.
- updated Hungarian translation by Pauli Henrik.
- updated Spanish translation by Mauricio Muñoz Lucero.
- updated Turkish translation by Uğur Çetin.
- updated Estonian translation by Rivo Laks.
- updated Traditional Chinese translation by Yen-chou Chen.
- updated Japanese translation by Daniel E. Moctezuma.
- updated Slovak translation by Rastislav Krupanský.
Changes between KMess 2.0.2 and 2.0.1:
--------------------------------------
- fixed a bug that was introduced just before the release of KMess 2.0.1,
making it impossible to login twice in the same KMess session.
- updated Japanese translation by Daniel E. Moctezuma.
- updated Brazilian Portuguese translation by Maurício Arozi Moraes.
Changes between KMess 2.0.1 and 2.0:
--------------------------------------
- added a "Log in automatically" checkbox to the initial view (patch by Camille Begue).
@@ -40,7 +77,7 @@ Changes between KMess 2.0.1 and 2.0:
- updated Brazilian Portuguese translation by Maurício Arozi Moraes.
- updated Catalan translation by Adrià Arrufat.
- updated Dutch translation by Sjors Gielen.
- updated Estonian translation by Lauri Võsandi, Mihkel Tõnnov and Rivo Laks.
- updated Estonian translation by Lauri Võsandi, Mihkel Tõnnov and Rivo Laks.
- updated Finnish translation by Marko Mäkilä.
- updated French translation by Émeric Dupont.
- updated German translation by Panagiotis Papadopoulos.
+22
View File
@@ -0,0 +1,22 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+82
View File
@@ -0,0 +1,82 @@
# - Try to find GCrypt
# Once done this will define
#
# GCRYPT_FOUND - system has GCrypt
# GCRYPT_INCLUDE_DIRS - the GCrypt include directory
# GCRYPT_LIBRARIES - Link these to use GCrypt
# GCRYPT_DEFINITIONS - Compiler switches required for using GCrypt
#
# Copyright (c) 2009 Andreas Schneider <mail@cynapses.org>
#
# Redistribution and use is allowed according to the terms of the New
# BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
# Imported into KMess, monday october 19, 2009 by Sjors
# reference URL:
# http://dev.libssh.org/export/27d25752e93c19d3e6584915bd64b72e43f3afc0/ \
# cmake/Modules/FindGCrypt.cmake
#
if (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
# in cache already
set(GCRYPT_FOUND TRUE)
else (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
find_path(GCRYPT_INCLUDE_DIR
NAMES
gcrypt.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
)
mark_as_advanced(GCRYPT_INCLUDE_DIR)
find_library(GCRYPT_LIBRARY
NAMES
gcrypt
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
mark_as_advanced(GCRYPT_LIBRARY)
if (GCRYPT_LIBRARY)
set(GCRYPT_FOUND TRUE CACHE INTERNAL "Wether the gcrypt library has been found" FORCE)
endif (GCRYPT_LIBRARY)
set(GCRYPT_INCLUDE_DIRS
${GCRYPT_INCLUDE_DIR}
)
if (GCRYPT_FOUND)
set(GCRYPT_LIBRARIES
${GCRYPT_LIBRARIES}
${GCRYPT_LIBRARY}
)
endif (GCRYPT_FOUND)
if (GCRYPT_INCLUDE_DIRS AND GCRYPT_LIBRARIES)
set(GCRYPT_FOUND TRUE)
endif (GCRYPT_INCLUDE_DIRS AND GCRYPT_LIBRARIES)
if (GCRYPT_FOUND)
if (NOT GCrypt_FIND_QUIETLY)
message(STATUS "Found GCrypt: ${GCRYPT_LIBRARIES}")
endif (NOT GCrypt_FIND_QUIETLY)
else (GCRYPT_FOUND)
if (GCrypt_FIND_REQUIRED)
message(FATAL_ERROR "Could not find GCrypt")
endif (GCrypt_FIND_REQUIRED)
endif (GCRYPT_FOUND)
# show the GCRYPT_INCLUDE_DIRS and GCRYPT_LIBRARIES variables only in the advanced view
mark_as_advanced(GCRYPT_INCLUDE_DIRS GCRYPT_LIBRARIES)
endif (GCRYPT_LIBRARIES AND GCRYPT_INCLUDE_DIRS)
+5
View File
@@ -1,3 +1,8 @@
2010-02-21 (Adam)
* Optimise the painting of strokes. Cache logic added to IsfQtDrawing and only
strokes that have been added are painted. Also, no longer do a full bounding rect
recalculation when a stroke is added.
2009-10-03 (Adam)
* Remove unused HIMETRIC conversion methods.
+9
View File
@@ -32,6 +32,7 @@
#include <QMatrix>
#include <QPaintDevice>
#include <QUuid>
#include <QPixmap>
// Forward declarations
@@ -98,8 +99,14 @@ namespace Isf
QList<AttributeSet*> attributeSets_;
/// Bounding rectangle of the drawing
QRect boundingRect_;
/// Cached bounding rectangle
QRect cacheRect_;
/// The cached pixmap
QPixmap cachePixmap_;
/// Virtual drawing canvas dimensions
QRect canvas_;
/// A list of strokes that need to be repainted.
QList<Stroke*> changedStrokes_;
/// Link to the currently used metric data
Metrics *currentMetrics_;
/// Link to the currently used point info data
@@ -116,6 +123,8 @@ namespace Isf
StrokeInfo defaultStrokeInfo_;
/// Link to the default transformation
QMatrix defaultTransform_;
/// Is the drawing dirty? i.e, requires repainting?
bool dirty_;
/// Last parsing error (if there is one)
IsfError error_;
/// List of registered GUIDs
+3
View File
@@ -515,6 +515,9 @@ void InkCanvas::mouseReleaseEvent( QMouseEvent *event )
// clear the buffer.
clearBuffer();
// update
update();
}
+81 -26
View File
@@ -265,25 +265,21 @@ qint32 Drawing::addStroke( Stroke *newStroke )
// add FitToCurve (Windows will use Bezier smoothing to make the ink look nice)
newStroke->attributes->flags |= FitToCurve;
// set the bounding rectangle.
if ( polygon.boundingRect().size() == QSize(1, 1) )
{
// can't have a 1px by 1px bounding rect - the eraser will never hit it.
// make the bounding rectange completely cover the drawn stroke.
float penSize = newStroke->attributes->penSize.width();
QPoint point = newStroke->points.at( 0 ).position;
newStroke->boundingRect = QRect( point.x() - penSize / 2, point.y() - penSize / 2, penSize, penSize );
}
else
{
newStroke->boundingRect = polygon.boundingRect();
}
float halfPenSize = newStroke->attributes->penSize.width() / 2;
// set bounding rectangle, expanded it to accommodate pen size.
newStroke->boundingRect = polygon.boundingRect().adjusted( -( halfPenSize ), - ( halfPenSize ),
halfPenSize, halfPenSize );
isNull_ = false;
strokes_.append( newStroke );
// force a bounding rectangle update
boundingRect_ = QRect();
boundingRect_ = boundingRect_.united( newStroke->boundingRect );
// this stroke needs to be repainted.
changedStrokes_.append( newStroke );
dirty_ = true;
return ( strokes_.count() - 1 );
}
@@ -329,6 +325,7 @@ void Drawing::clear()
strokes_ .clear();
transforms_ .clear();
attributeSets_.clear();
changedStrokes_.clear();
// Invalidate the current item pointers
currentMetrics_ = 0;
@@ -339,6 +336,7 @@ void Drawing::clear()
// Nullify the other properties
boundingRect_ = QRect();
canvas_ = QRect();
cacheRect_ = QRect();
error_ = ISF_ERROR_NONE;
hasXData_ = true;
hasYData_ = true;
@@ -346,6 +344,8 @@ void Drawing::clear()
maxGuid_ = 0;
maxPenSize_ = QSizeF();
size_ = QSize();
dirty_ = false;
cachePixmap_ = QPixmap();
// set the default transform
defaultTransform_.scale( 1.f, 1.f );
@@ -402,9 +402,17 @@ bool Drawing::deleteStroke( quint32 index )
return false;
}
delete strokes_.takeAt( index );
boundingRect_ = QRect(); // force a recalculation.
Stroke *victim = strokes_.takeAt( index );
// make sure this goes from the changedStrokes_ list too.
changedStrokes_.removeAll( victim );
delete victim;
dirty_ = true;
boundingRect_ = QRect(); // force a recalculation.
return true;
}
@@ -504,7 +512,7 @@ const QList<AttributeSet*> Drawing::attributeSets()
QRect Drawing::boundingRect()
{
// if the boundingRect_ is invalid, update it.
// it becomes invalid after a stroke is added or deleted.
// it becomes invalid after a stroke is deleted.
if ( boundingRect_ == QRect() )
{
foreach( Stroke *stroke, strokes_ )
@@ -563,6 +571,11 @@ QPixmap Drawing::pixmap( const QColor backgroundColor )
return QPixmap();
}
if ( ! dirty_ && ! cachePixmap_.isNull() )
{
return cachePixmap_;
}
QSize size_ = size();
if( size_.width() > 2000 || size_.height() > 2000 )
@@ -573,25 +586,63 @@ QPixmap Drawing::pixmap( const QColor backgroundColor )
return QPixmap();
}
QPixmap pixmap( size_ );
pixmap.fill( backgroundColor );
QPainter painter( &pixmap );
// is the cache null, or are we repainting everything? if so, create a new pixmap.
if ( cachePixmap_.isNull() || changedStrokes_.isEmpty() )
{
cachePixmap_ = QPixmap( size_ );
cachePixmap_.fill( Qt::transparent );
cacheRect_ = boundingRect();
}
else
{
// otherwise, resize and repaint the cache.
QRect newRect = boundingRect();
// has the size of the drawing changed? if so, resize the cachePixmap_.
if ( cacheRect_.size() != newRect.size() )
{
// qDebug() << "Cache pixmap needs resizing to" << size_;
// qDebug() << "Cache rect:" << cacheRect_;
// qDebug() << "New rect:" << newRect;
QPixmap pixmap( size_ );
pixmap.fill( Qt::transparent );
QPainter painter( &pixmap );
int xOffset = ( newRect.x() - cacheRect_.x() ) * -1;
int yOffset = ( newRect.y() - cacheRect_.y() ) * -1;
// qDebug() << "x-offset:"<<xOffset<<", y-offset:"<<yOffset;
painter.drawPixmap( xOffset, yOffset, cachePixmap_ );
cachePixmap_ = pixmap;
cacheRect_ = newRect;
}
}
// if we're told specifically what strokes to paint, only paint those ones.
// otherwise, paint all of them.
QList<Stroke*> strokes = ( changedStrokes_.isEmpty() ? strokes_ : changedStrokes_ );
#ifdef ISFQT_DEBUG
qDebug() << "Rendering a drawing of size" << size_;
#endif
#ifdef ISFQT_DEBUG_VERBOSE
qDebug() << "The drawing contains" << strokes_.count() << "strokes.";
qDebug() << "The drawing contains" << strokes_.count() << "strokes; rendering" << strokes.count() << "strokes.";
#endif
// if there are no strokes there's no point going
// through the rest of this logic.
if ( strokes_.count() == 0 )
if ( strokes.count() == 0 )
{
return pixmap;
return cachePixmap_;
}
QPainter painter( &cachePixmap_ );
painter.setWindow( boundingRect() );
painter.setWorldMatrixEnabled( true );
painter.setRenderHints( QPainter::Antialiasing
@@ -611,7 +662,7 @@ QPixmap Drawing::pixmap( const QColor backgroundColor )
currentTransform_ = 0;
int index = 0;
foreach( const Stroke *stroke, strokes_ )
foreach( const Stroke *stroke, strokes )
{
if( currentMetrics_ != stroke->metrics )
{
@@ -712,11 +763,15 @@ QPixmap Drawing::pixmap( const QColor backgroundColor )
painter.end();
changedStrokes_.clear();
#ifdef ISFQT_DEBUG
qDebug() << "Rendering complete.";
#endif
return pixmap;
dirty_ = false;
return cachePixmap_;
}
+678 -625
View File
File diff suppressed because it is too large Load Diff
+695 -642
View File
File diff suppressed because it is too large Load Diff
+763 -705
View File
File diff suppressed because it is too large Load Diff
+714 -667
View File
File diff suppressed because it is too large Load Diff
+735 -664
View File
File diff suppressed because it is too large Load Diff
+1086 -825
View File
File diff suppressed because it is too large Load Diff
+2251 -1433
View File
File diff suppressed because it is too large Load Diff
+766 -753
View File
File diff suppressed because it is too large Load Diff
+725 -668
View File
File diff suppressed because it is too large Load Diff
+689 -629
View File
File diff suppressed because it is too large Load Diff
+824 -763
View File
File diff suppressed because it is too large Load Diff
+669 -625
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -27,7 +27,7 @@ echo 'i18nc("EMAIL OF TRANSLATORS","Your emails");' >> $RC_CPP
echo "extracting translations from *.ui files.."
cd $BASEDIR
find . -name '*.ui' -o -name '*.rc' -o -name '*.kcfg' | sort >> $RC_LIST
xargs --arg-file=$RC_LIST ${EXTRACTRC} > $RC_CPP
xargs --arg-file=$RC_LIST ${EXTRACTRC} >> $RC_CPP
# Parse .xsl files
echo "extracting translations from *.xsl files.."
+754 -813
View File
File diff suppressed because it is too large Load Diff
+6500
View File
File diff suppressed because it is too large Load Diff
+787 -715
View File
File diff suppressed because it is too large Load Diff
+5815
View File
File diff suppressed because it is too large Load Diff
+1234 -1761
View File
File diff suppressed because it is too large Load Diff
+7094
View File
File diff suppressed because it is too large Load Diff
+775 -696
View File
File diff suppressed because it is too large Load Diff
+1162 -1492
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -1,5 +1,5 @@
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${QCA2_INCLUDE_DIR} )
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${GCRYPT_INCLUDE_DIRS} )
########### next target ###############
@@ -88,6 +88,7 @@ SET(kmess_SOURCES
settings/miscellaneouspage.cpp
utils/crashhandler.cpp
utils/idletimer.cpp
utils/inlineeditlabel.cpp
utils/kmessconfig.cpp
utils/kmessdbus.cpp
utils/kmessdbusdatatypes.cpp
@@ -140,6 +141,7 @@ SET(kmess_UI_FILES
settings/chatstylepage.ui
settings/emoticonspage.ui
settings/miscellaneouspage.ui
utils/inlineeditlabel.ui
)
SET(kmess_LIBS
@@ -153,7 +155,7 @@ SET(kmess_LIBS
${KDE4_SOLID_LIBS}
${LIBXML2_LIBRARIES}
${LIBXSLT_LIBRARIES}
${QCA2_LIBRARIES}
${GCRYPT_LIBRARIES}
${QT_QTTEST_LIBRARY}
)
+4 -3
View File
@@ -1284,7 +1284,7 @@ void ChatMaster::slotDeliverMimeMessage(const MimeMessage &message, const QStrin
// Parse an gif ink message
void ChatMaster::slotGotInkMessage( const QString &inkData, const QString &contactHandle, InkFormat format )
void ChatMaster::slotGotInkMessage( const QString &ink, const QString &contactHandle, InkFormat format )
{
#ifdef KMESSDEBUG_SWITCHBOARD_GENERAL
switch( format )
@@ -1315,7 +1315,7 @@ void ChatMaster::slotGotInkMessage( const QString &inkData, const QString &conta
i18nc( "Error message shown in chat, %1 is the name of the contact",
"You received an handwritten message from %1, "
"but it could not be displayed. This version of "
"KMess was built without ISF support." ),
"KMess was built without ISF support.", friendlyName ),
contactHandle,
friendlyName ) );
return;
@@ -1324,6 +1324,7 @@ void ChatMaster::slotGotInkMessage( const QString &inkData, const QString &conta
// Validate the incoming data
QString inkData = ink.trimmed();
QRegExp inkChars( "([^A-Za-z0-9:+/=])" );
if( ! inkData.startsWith( "base64:" ) || inkChars.indexIn( inkData ) != -1 )
{
@@ -1336,7 +1337,7 @@ void ChatMaster::slotGotInkMessage( const QString &inkData, const QString &conta
i18nc( "Error message shown in chat, %1 is the name of the contact",
"You received an handwritten message from %1, "
"but it could not be displayed. The data could "
"not be read." ),
"not be read.", friendlyName ),
contactHandle,
friendlyName ) );
return;
+2 -2
View File
@@ -407,7 +407,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
}
else
{
chatHistory += "(" + chatMessage->getTime().toString( Qt::DefaultLocaleShortDate ) + ")"
chatHistory += "(" + KGlobal::locale()->formatTime( chatMessage->getTime() ) + ")"
" " + chatMessage->getContactHandle() + ":\n"
" " + chatMessage->getBody().trimmed() + "\n";
}
@@ -416,7 +416,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
// Add system messages etc
else
{
chatHistory += "(" + chatMessage->getTime().toString( Qt::DefaultLocaleShortDate ) + ")"
chatHistory += "(" + KGlobal::locale()->formatTime( chatMessage->getTime() ) + ")"
" " + chatMessage->getBody().trimmed() + "\n";
lastHandle = QString();
}
+14 -3
View File
@@ -469,7 +469,18 @@ bool ChatView::saveChatToFile( const QString &path, Account::ChatExportFormat fo
// Output the chat history to the file, with the right text encoding
QTextStream textStream( &file );
textStream.setCodec( QTextCodec::codecForLocale() );
// For plain text logs we use the locale codec
if (format == Account::EXPORT_TEXT)
{
textStream.setCodec( QTextCodec::codecForLocale() );
}
// For HTML and XML logs (that are created with charset attribute to UTF-8) we use UTF-8 encoding
else
{
textStream.setCodec( QTextCodec::codecForName("UTF-8") );
}
textStream << chatHistory;
file.close();
@@ -658,7 +669,7 @@ void ChatView::slotAddNewEmoticon()
// URL-Decode the encoded strings
picture = KUrl::fromPercentEncoding( picture.toAscii() );
shortcut = KUrl::fromPercentEncoding( shortcut.toAscii() );
shortcut = KUrl::fromPercentEncoding( shortcut.toUtf8() );
#ifdef KMESSDEBUG_CHATVIEW
kDebug() << "Showing Add Emoticon dialog - shortcut=" << shortcut << " picture=" << picture;
@@ -773,7 +784,7 @@ void ChatView::slotIgnoreEmoticon()
}
// URL-Decode the encoded strings
shortcut = KUrl::fromPercentEncoding( shortcut.toAscii() );
shortcut = KUrl::fromPercentEncoding( shortcut.toUtf8() );
// Add the emoticon to the contact's blacklist and update the chat
if( contact->manageEmoticonBlackList( true, shortcut ) )
+42 -5
View File
@@ -44,6 +44,7 @@
#include <QDockWidget>
#include <QShortcut>
#include <QTextDocumentFragment>
#include <QDesktopWidget>
#include <KAction>
#include <KActionMenu>
@@ -281,6 +282,11 @@ Chat *ChatWindow::addChatTab( Chat *newChat, bool foreground )
newChat->getContactsWidget()->setDockWidget( contactsDock_, dockWidgetArea( contactsDock_ ) );
newChat->setZoomFactor( zoomLevel_ );
// Enable the spell checker for the new tab.
// FIXME KDE4.x bug this needs to be unset then set
messageEdit_->setCheckSpellingEnabled( ! spellCheckAction_->isChecked() );
messageEdit_->setCheckSpellingEnabled( spellCheckAction_->isChecked() );
// If there's more than one tab now, enable the Close All option
bool hasMultipleTabs = ( chatTabs_->count() > 1 );
closeAllAction_->setEnabled( hasMultipleTabs );
@@ -733,7 +739,7 @@ bool ChatWindow::eventFilter( QObject *obj, QEvent *event )
return false;
}
if ( event->type() == QEvent::KeyPress )
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
@@ -743,7 +749,7 @@ bool ChatWindow::eventFilter( QObject *obj, QEvent *event )
return true;
}
}
// Only manage events for the editors from now on (the event filter code
// is complex enough as it is now...)
if( obj != messageEdit_
@@ -1383,8 +1389,24 @@ void ChatWindow::readProperties(const KConfigGroup &config )
// Resize the window to decent dimensions if there's no saved state.
resize( 550, 450 );
restoreState( group.readEntry( "ToolbarsAndDocksState", QByteArray() ) );
QByteArray state( group.readEntry( "ToolbarsAndDocksState", QByteArray() ) );
// adam (16Feb10): restoreWindowSize has to come before restoreState.
//
// when testing with KDE 4.4 I found, for some completely unknown reason,
// that calling restoreState *first* causes the configuration file in KConfigGroup above (which has *nothing* to do with restoreState)
// to reset its Width and Height settings to what seem to be default values.
//
// I have no idea why this happens - restoreState doesn't trigger a saveProperties call so it shouldn't happen at all!
// It's dark magic, I tell you.
//
// Swapping the calls around fixes the problem. But again, I'll be damned if I can figure out
// what's going on.
restoreWindowSize( group );
restoreState( state );
// Read if the spelling check feature is enabled
toggleSpellCheck( group.readEntry( "UseSpellCheck", false ) );
@@ -1432,6 +1454,11 @@ void ChatWindow::saveProperties( KConfigGroup &config )
group.writeEntry( "MessageSplitterSizes", splitter_->sizes() );
group.writeEntry( "CurrentZoom", zoomLevel_ );
// Save window size
saveWindowSize( group );
group.config()->sync();
}
@@ -2257,7 +2284,8 @@ void ChatWindow::slotSwitchEditor()
standardEmoticonsWidget_->hide();
customEmoticonsWidget_->hide();
winksWidget_->hide();
inkCanvas_->hide();
// Show the text control frame by default
inkCtlFrame_->setVisible( false );
textCtlFrame_->setVisible( true );
@@ -2287,6 +2315,8 @@ void ChatWindow::slotSwitchEditor()
#ifdef KMESSDEBUG_CHATWINDOW
kDebug() << "Switching to ink editor.";
#endif
inkCanvas_->show();
editorChooser_->setCurrentWidget( inkPage_ );
winksButton_->setChecked( false );
inkButton_->setChecked( true );
@@ -2484,6 +2514,11 @@ void ChatWindow::slotTabChanged( int currentIndex )
setWindowTitle();
updateModeButtons();
slotGotTypingMessage( chat );
// Re-enable the spell checker for this tab.
// FIXME KDE4.x bug this needs to be unset then set
messageEdit_->setCheckSpellingEnabled( ! spellCheckAction_->isChecked() );
messageEdit_->setCheckSpellingEnabled( spellCheckAction_->isChecked() );
}
@@ -2669,7 +2704,9 @@ void ChatWindow::toggleSpellCheck( bool useSpellCheck )
}
// Change the spell checking feature status
messageEdit_->setCheckSpellingEnabled( useSpellCheck );
// FIXME KDE4.x bug this needs to be unset then set
messageEdit_->setCheckSpellingEnabled( ! spellCheckAction_->isChecked() );
messageEdit_->setCheckSpellingEnabled( spellCheckAction_->isChecked() );
}
+62 -12
View File
@@ -18,6 +18,7 @@
#include "contactframe.h"
#include "../contact/contact.h"
#include "../contact/contactextension.h"
#include "../contact/msnstatus.h"
#include "../dialogs/contactpropertiesdialog.h"
#include "../model/contactlist.h"
@@ -119,6 +120,9 @@ void ContactFrame::activate( ContactBase *contact )
handle_ = contact_->getHandle();
detailedContact_ = CurrentAccount::instance()->getContactList()->getContactByHandle( handle_ );
// ensure we know when the contact is now invalid.
connect( contact_, SIGNAL( destroyed(QObject*) ), this, SLOT( contactDestroyed(QObject*) ) );
if( detailedContact_ != 0 )
{
// Connect the contact, to update the frame on presence info changes
@@ -132,8 +136,6 @@ void ContactFrame::activate( ContactBase *contact )
this, SLOT ( updatePicture() ) );
connect( detailedContact_, SIGNAL( changedPersonalMessage(Contact*) ),
this, SLOT ( updateStatusWidgets() ) );
connect( detailedContact_, SIGNAL( destroyed(QObject*) ),
this, SLOT ( contactDestroyed(QObject*) ) );
}
}
@@ -185,6 +187,10 @@ void ContactFrame::contactDestroyed( QObject *object )
// - somehow a code paths leads to this class (Chat::setSwitchboardConnection(0) is already patched).
// - crash.
// adam (17 Jan 2010) - the problem above occurs with InvitedContacts. we attach to the detailedContact_ destroyed() signal
// rather than the contact_ destroyed() signal. InvitedContact's have detailedContact_ == 0 so we never get notified
// of the InvitedContact deletion. fixed.
#ifdef KMESSDEBUG_CONTACTFRAME
if( contact_ && contact_ != object )
{
@@ -244,22 +250,72 @@ bool ContactFrame::eventFilter( QObject *obj, QEvent *event )
int eventType = event->type();
// Check if the obj is contactPixmapLabel
if( obj == contactPixmapLabel_ && detailedContact_
&& ( eventType == QEvent::Enter || eventType == QEvent::Leave ) )
if( obj == contactPixmapLabel_ && detailedContact_ )
{
QImage image( detailedContact_->getContactPicturePath() );
// Apply glow effect to image
if( eventType == QEvent::Enter )
{
QImage image( detailedContact_->getContactPicturePath() );
KIconEffect::toGamma( image, 0.8f );
contactPixmapLabel_->setPixmap( QPixmap::fromImage( image ) );
}
else if( eventType == QEvent::Leave && !typingTimer_.isActive() )
{
QImage image( detailedContact_->getContactPicturePath() );
// Only disable glow effect when the contact is not typing
contactPixmapLabel_->setPixmap( QPixmap::fromImage( image ) );
}
else if ( eventType == QEvent::DragEnter )
{
QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent*>( event );
const QMimeData *mimeData = dragEvent->mimeData();
// The mimeData object can contain one of the following objects: an image, HTML text, plain text, or a list of URLs.
// We need only the first URL object
if( mimeData->hasUrls() )
{
dragEvent->acceptProposedAction();
}
else
{
dragEvent->ignore();
}
}
else if ( eventType == QEvent::Drop )
{
QDropEvent* dropEvent = static_cast<QDropEvent*>( event );
const QMimeData *mimeData = dropEvent->mimeData();
// The mimeData object can contain one of the following objects: an image, HTML text, plain text, or a list of URLs.
// We need only the first URL object
if( ! mimeData->hasUrls() )
{
return true;
}
QUrl mimeUrl = mimeData->urls().first();
QString filePath;
QPixmap pictureData;
if( mimeUrl.isEmpty() )
{
kWarning() << "Dropped empty MIME URL";
return true;
}
filePath = mimeUrl.path();
if( ! pictureData.load( filePath ) )
{
kWarning() << "The file dropped is not an image or doesn't exist";
return true;
}
detailedContact_->getExtension()->setContactAlternativePicturePath( filePath );
dropEvent->acceptProposedAction();
}
}
if( eventType != QEvent::MouseButtonRelease )
@@ -731,12 +787,6 @@ void ContactFrame::updatePicture()
// Display the image
contactPixmapLabel_->setPixmap( contactPicture_ );
// only change min size for images smaller than 96x96
if ( contactImage.width() < 96 && contactImage.height() < 96 )
{
contactPixmapLabel_->setMinimumSize( contactImage.width(), contactImage.height() );
}
}
+3
View File
@@ -149,6 +149,9 @@
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Click here to display the menu for this contact</string>
</property>
+127 -2
View File
@@ -22,12 +22,16 @@
#include "../currentaccount.h"
#include "../kmessdebug.h"
#include "../network/msnswitchboardconnection.h"
#include "../utils/kmessshared.h"
#include "../utils/kmessconfig.h"
#include <QDockWidget>
#include <QMouseEvent>
#include <QDir>
#include <KIconEffect>
#include <KIO/NetAccess>
#include <KMessageBox>
// The constructor
ContactsWidget::ContactsWidget( QWidget *parent )
@@ -238,6 +242,127 @@ bool ContactsWidget::eventFilter( QObject *obj, QEvent *event )
return true;
}
break;
case QEvent::DragEnter:
{
QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent*>( event );
const QMimeData *mimeData = dragEvent->mimeData();
// The mimeData object can contain one of the following objects: an image, HTML text, plain text, or a list of URLs.
// We need only the first URL object
if( mimeData->hasUrls() )
{
dragEvent->acceptProposedAction();
}
else
{
dragEvent->ignore();
}
}
break;
case QEvent::Drop:
{
QDropEvent* dropEvent = static_cast<QDropEvent*>( event );
const QMimeData *mimeData = dropEvent->mimeData();
// The mimeData object can contain one of the following objects: an image, HTML text, plain text, or a list of URLs.
// We need only the first URL object
if( ! mimeData->hasUrls() )
{
return true;
}
KUrl mimeUrl = mimeData->urls().first();
bool isRemoteFile = false;
QString localFilePath;
QImage pictureData;
if( mimeUrl.isEmpty() )
{
kWarning() << "Dropped empty MIME URL";
return true;
}
if( mimeUrl.isLocalFile() )
{
localFilePath = mimeUrl.path();
}
else
{
// File is remote, download it to a local folder
// first because QPixmap doesn't have KIO magic.
// KIO::NetAccess::download fills the localFilePath field.
if( ! KIO::NetAccess::download(mimeUrl, localFilePath, this ) )
{
KMessageBox::sorry( this, i18n( "Downloading of display picture failed" ), i18n("KMess") );
return true;
}
isRemoteFile = true;
}
if( ! pictureData.load( localFilePath ) )
{
kWarning() << "The file dropped is not an image or doesn't exist";
return true;
}
if( isRemoteFile )
{
KIO::NetAccess::removeTempFile( localFilePath );
}
pictureData = pictureData.scaled( 96, 96, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation ); // Makes smallest edge 96 pixels, preserving aspect ratio
if( pictureData.width() != 96 || pictureData.height() != 96 )
{
// Copy the middle part of the picture.
pictureData = pictureData.copy( (pictureData.width() - 96) / 2, // X
(pictureData.height() - 96) / 2, // Y
96, 96 );
}
QString pictureDir = KMessConfig::instance()->getAccountDirectory( currentAccount->getHandle() ) + "/displaypics/";
QString tempPictureFile = pictureDir + "temporary-picture.png";
if( ! pictureData.save( tempPictureFile, "PNG" ) )
{
KMessageBox::sorry( this,
i18n( "An error occurred while trying to change the display picture.\n"
"Make sure that you have selected an existing image file." ),
i18n( "KMess" ) );
}
QString msnObjectHash( KMessShared::generateFileHash( tempPictureFile ).toBase64() );
const QString safeMsnObjectHash( msnObjectHash.replace( QRegExp("[^a-zA-Z0-9+=]"), "_" ) );
// Save the new display picture with its hash as name, to ensure correct caching
QString pictureName = msnObjectHash + ".png";
QDir pictureFolder = QDir( pictureDir );
// Do not overwrite identical pictures
if( ! pictureFolder.exists( pictureName ) )
{
if( ! pictureFolder.rename( tempPictureFile, pictureName ) )
{
kWarning() << "The display picture file could not be renamed from" << tempPictureFile << "to" << pictureName << ".";
return true;
}
}
if ( ! currentAccount->getShowPicture() )
{
currentAccount->setShowPicture( true );
currentAccount->saveProperties();
}
currentAccount->setPicturePath( pictureDir + pictureName );
currentAccount->setOriginalPicturePath( mimeUrl.path() );
dropEvent->acceptProposedAction();
}
break;
default:
break;
+3
View File
@@ -103,6 +103,9 @@
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Click here to open your account settings</string>
</property>
+2
View File
@@ -277,6 +277,8 @@ void ContactExtension::setAlternativeName( const QString& newAlternativeName )
void ContactExtension::setContactAlternativePicturePath( const QString& _newVal )
{
alternativePictureFile_ = _newVal;
emit changedPicture();
}
+6 -2
View File
@@ -398,7 +398,9 @@ void ContactPropertiesDialog::setupWidgets()
{
lastSeenString = i18n( "Connected" );
}
else if( extension->getLastSeen().toTime_t() == 0 || extension->getLastSeen().isNull() )
else if( extension->getLastSeen().toTime_t() == 0
|| extension->getLastSeen().toTime_t() == UINT_MAX
|| extension->getLastSeen().isNull() )
{
lastSeenString = i18n( "Not seen yet" );
}
@@ -407,7 +409,9 @@ void ContactPropertiesDialog::setupWidgets()
lastSeenString = extension->getLastSeen().toString();
}
if( extension->getLastMessageDate().toTime_t() == 0 || extension->getLastMessageDate().isNull() )
if( extension->getLastMessageDate().toTime_t() == 0
|| extension->getLastMessageDate().toTime_t() == UINT_MAX
|| extension->getLastMessageDate().isNull() )
{
lastMessageString = i18n( "No messages yet" );
}
+72 -45
View File
@@ -29,35 +29,42 @@
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="imageContact_">
<property name="minimumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="imageContact_">
<property name="minimumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="toolTip">
<string>Click or Drag&amp;Drop to change the image for this contact</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="restoreButton_">
@@ -75,6 +82,12 @@
<layout class="QGridLayout" name="gridLayout">
<item row="7" column="2">
<widget class="QLabel" name="clientLabel_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
@@ -88,6 +101,12 @@
</item>
<item row="6" column="2">
<widget class="QLabel" name="emailLabel_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
@@ -98,6 +117,12 @@
</item>
<item row="2" column="2">
<widget class="QLabel" name="trueNameLabel_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
@@ -114,6 +139,12 @@
</item>
<item row="4" column="2">
<widget class="QLabel" name="lastSeenLabel_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
@@ -124,6 +155,12 @@
</item>
<item row="5" column="2">
<widget class="QLabel" name="lastMessageLabel_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
@@ -134,6 +171,12 @@
</item>
<item row="3" column="2">
<widget class="QLabel" name="personalMessageLabel_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
@@ -173,22 +216,6 @@
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
+4 -14
View File
@@ -628,22 +628,12 @@ bool EmoticonTheme::saveTheme()
return false;
}
// Get encoding
QTextCodec *codec = QTextCodec::codecForLocale();
if( codec == 0 )
{
kWarning() << "Could not find codec '" << QTextCodec::codecForLocale() << "', special characters might not be saved correctly!";
}
// Start the XML output using the right text encoding
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextStream xmlOutput( &xmlFile );
if( codec != 0 )
{
xmlOutput.setCodec( codec );
}
xmlOutput.setCodec( codec );
// Start the XML tree by writing the root tag
xmlOutput << "<?xml version=\"1.0\"?>" << endl << "<messaging-emoticon-map>" << endl << endl;
xmlOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl << "<messaging-emoticon-map>" << endl << endl;
foreach( Emoticon *emoticon, emoticons_ )
{
+13 -8
View File
@@ -459,7 +459,10 @@ void KMess::changedSong( const QString &artist, const QString &album, const QStr
}
// Update KMessView
view_->changedSong( artist, album, track, playing );
if( view_ )
{
view_->changedSong( artist, album, track, playing );
}
}
}
@@ -851,13 +854,6 @@ void KMess::connectWithAccount(Account *account)
kDebug() << "Connecting account:" << account->getHandle();
#endif
// Update the initial view with account details and start the connection if everything is ok
if( ! initialView_->startConnecting( account->getHandle(), false /* emitConnectionSignal */ ) )
{
show();
return;
}
startConnection( account );
}
@@ -1824,6 +1820,13 @@ void KMess::startConnection( Account *account )
msnNotificationConnection_->closeConnection();
}
// Update the initial view with account details and start the connection if everything is ok
if( ! initialView_->startConnecting( account->getHandle(), false /* emitConnectionSignal */ ) )
{
show();
return;
}
// Update the main view's controls to match this account's details.
changedStatus( account );
@@ -1880,6 +1883,8 @@ void KMess::switchViewToContactList()
msnNotificationConnection_, SLOT ( allowContact(QString) ) );
connect( view_, SIGNAL( blockContact(QString) ), // Block the contact
msnNotificationConnection_, SLOT ( blockContact(QString) ) );
connect( view_, SIGNAL( changeFriendlyName(QString) ), // Change the friendly name
msnNotificationConnection_, SLOT ( changeFriendlyName(QString) ) );
connect( view_, SIGNAL( changePersonalMessage(QString) ), // Change the personal message.
msnNotificationConnection_, SLOT ( changePersonalMessage(QString) ) );
connect( view_, SIGNAL( copyContact(QString, QString) ),
+4 -4
View File
@@ -206,7 +206,7 @@ void KMessTest::testChatWindow()
}
// User-started chat
if( 0 )
if( 1 )
{
MsnSwitchboardConnection *sb1 = new MsnSwitchboardConnection();
kmess_->chatMaster_->switchboardConnections_.append( sb1 );
@@ -219,7 +219,7 @@ void KMessTest::testChatWindow()
}
// Contact-started group chat
if( 0 )
if( 1 )
{
MsnSwitchboardConnection *sb3 = new MsnSwitchboardConnection();
ChatInformation chatInfo3( kmess_->msnNotificationConnection_, "contact2@kmess.org", "127.0.0.1", 1234, "5678.8765", "-1", ChatInformation::CONNECTION_OFFLINE );
@@ -441,7 +441,7 @@ void KMessTest::testGroupsAndContacts()
AccountsManager::instance()->addAccount(account);
EmoticonManager::instance()->connected();
account->setLoginInformation("test@test.com", "Testing Account", "test" );
account->setLoginInformation("test@test.com", "[b]Testing Account[/b]", "test" );
account->setPersonalMessage( "omg! this [u]rocks![/u] :D " );
account->setGuestAccount( true );
account->setListPictureSize( 32 );
@@ -449,7 +449,7 @@ void KMessTest::testGroupsAndContacts()
account->setStatusOptions( true, 5, true );
account->setShowContactListBird( true );
account->setContactListOptions( true, false, true );
account->setContactListOptions( false, false, true );
account->setEmailSupported( true );
account->setContactListDisplayMode( Account::VIEW_MIXED ); // VIEW_MIXED VIEW_BYSTATUS VIEW_BYGROUP
account->setShowAllowedContacts( false );
+213 -77
View File
@@ -48,6 +48,7 @@
#include <KActionMenu>
#include <KApplication>
#include <KGlobal>
#include <KIO/NetAccess>
#include <KIconLoader>
#include <KIconEffect>
#include <KLocale>
@@ -85,20 +86,17 @@ KMessView::KMessView( QWidget *parent )
searchFrame_->hide();
// Capture focus events without subclassing the widget from the .UI file
personalMessageInput_->installEventFilter(this);
currentAccountDisplayPic_->installEventFilter(this);
contactListView_->installEventFilter(this);
contactListView_->viewport()->installEventFilter(this);
// Fake an event to configure the personal message input
QEvent ev(QEvent::FocusOut);
eventFilter(personalMessageInput_, &ev);
// Windows Live Messenger 8.5 and 2009 (latter only in the chat screen) don't
// display any part further than 129 characters.
// TODO: allow further than 129, but display a warning while typing.
personalMessageInput_->setMaxLength( 129 );
friendlyNameInput_->setFormattingMode( STRING_LIST_SETTING );
personalMessageInput_->setFormattingMode( STRING_LIST_SETTING );
// Set up the group update timer
updateTimer_.setSingleShot( true );
connect( &updateTimer_, SIGNAL( timeout() ),
@@ -125,7 +123,7 @@ KMessView::~KMessView()
delete viewModel_;
selectionModel_ = 0;
viewModel_ = 0;
#ifdef KMESSDEBUG_KMESSVIEW_GENERAL
kDebug() << "DESTROYED.";
#endif
@@ -273,11 +271,12 @@ bool KMessView::initialize( QAbstractItemModel *viewModel )
statusButton_, SLOT ( showMenu() ) );
// Enable the labels
onlineStatusLabel_->setEnabled(true);
emailLabel_->setEnabled(true);
QFont appFont( QApplication::font() );
onlineStatusLabel_->setStyleSheet( "QLabel { font-size: " + QString::number( appFont.pointSize() + 2 ) + "pt; }" );
int appFontSize = appFont.pointSize();
friendlyNameInput_->setStyleSheet( "QLabel { font-size: " + QString::number( appFontSize + 2 ) + "pt; }" );
personalMessageInput_->setStyleSheet( "QLabel { font-size: " + QString::number( appFontSize - 1 ) + "pt; }" );
// Hide the now listening until something is playing
changedSong( QString(), QString(), QString(), false );
@@ -291,6 +290,8 @@ bool KMessView::initialize( QAbstractItemModel *viewModel )
this, SLOT ( slotUpdateUserStatus() ) );
connect( currentAccount_, SIGNAL( changedFriendlyName() ), // Changed name
this, SLOT ( slotUpdateUserStatus() ) );
connect( currentAccount_, SIGNAL( changedPersonalMessage() ), // Changed personal message
this, SLOT ( slotUpdateUserStatus() ) );
connect( currentAccount_, SIGNAL( changedEmailDisplaySettings() ), // Changed email display settings
this, SLOT ( slotUpdateEmailDisplay() ) );
connect( currentAccount_, SIGNAL( changedDisplaySettings() ),
@@ -299,6 +300,8 @@ bool KMessView::initialize( QAbstractItemModel *viewModel )
this, SLOT ( slotUpdateGroups() ) );
connect( currentAccount_, SIGNAL( changedContactListOptions() ), // Changed contact list options
this, SLOT ( slotUpdateView() ) );
connect( currentAccount_, SIGNAL( changedContactListOptions() ), // Changed contact list options
this, SLOT ( slotUpdateUserStatus() ) );
// These update the display pic size depending on the email & now listening options
connect( currentAccount_, SIGNAL( changedNowListeningSettings() ),
this, SLOT ( slotUpdateDisplayPicture() ) );
@@ -326,6 +329,11 @@ bool KMessView::initialize( QAbstractItemModel *viewModel )
historyBox_->insertItem( 0, i18n( "[%1] Logged in with %2", QTime::currentTime ().toString( "HH:mm:ss" )
, currentAccount_->getHandle() ) );
// Enable changing inline the friendly name and PM
connect( friendlyNameInput_, SIGNAL( changed() ),
this, SLOT ( updateFriendlyName() ) );
connect( personalMessageInput_, SIGNAL( changed() ),
this, SLOT ( updatePersonalMessage() ) );
// Connect the search edit line with slot for searching
connect( searchEdit_, SIGNAL( textChanged(QString) ),
@@ -343,7 +351,9 @@ bool KMessView::initialize( QAbstractItemModel *viewModel )
slotUpdateNoEmails();
slotUpdateDisplayPicture();
slotUpdateGroups();
slotPersonalMessageLostFocus( true );
updateFriendlyName( true );
updatePersonalMessage( true );
return true;
}
@@ -431,8 +441,7 @@ void KMessView::toggleShowSearchFrame( bool show )
// The personal status message received an event.
bool KMessView::eventFilter(QObject *obj, QEvent *event)
{
if( obj != personalMessageInput_
&& obj != currentAccountDisplayPic_
if(obj != currentAccountDisplayPic_
&& obj != contactListView_
&& obj != contactListView_->viewport() )
{
@@ -460,6 +469,120 @@ bool KMessView::eventFilter(QObject *obj, QEvent *event)
{
emit showSettings();
}
else if( eventType == QEvent::DragEnter )
{
QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent*>( event );
const QMimeData *mimeData = dragEvent->mimeData();
// The mimeData object can contain one of the following objects: an image, HTML text, plain text, or a list of URLs.
// We need only the first URL object
if( mimeData->hasUrls() )
{
dragEvent->acceptProposedAction();
}
else
{
dragEvent->ignore();
}
}
else if( eventType == QEvent::Drop )
{
QDropEvent* dropEvent = static_cast<QDropEvent*>( event );
const QMimeData *mimeData = dropEvent->mimeData();
// The mimeData object can contain one of the following objects: an image, HTML text, plain text, or a list of URLs.
// We need only the first URL object
if( ! mimeData->hasUrls() )
{
return true;
}
else
{
KUrl mimeUrl = mimeData->urls().first();
bool isRemoteFile = false;
QString localFilePath;
QImage pictureData;
if( mimeUrl.isEmpty() )
{
kWarning() << "Dropped empty MIME URL";
return true;
}
if( mimeUrl.isLocalFile() )
{
localFilePath = mimeUrl.path();
}
else
{
// File is remote, download it to a local folder
// first because QPixmap doesn't have KIO magic.
// KIO::NetAccess::download fills the localFilePath field.
if( ! KIO::NetAccess::download(mimeUrl, localFilePath, this ) )
{
KMessageBox::sorry( this, i18n( "Downloading of display picture failed" ), i18n("KMess") );
return true;
}
isRemoteFile = true;
}
if( ! pictureData.load( localFilePath ) )
{
kWarning() << "The file dropped is not an image or doesn't exist";
return true;
}
if( isRemoteFile )
{
KIO::NetAccess::removeTempFile( localFilePath );
}
pictureData = pictureData.scaled( 96, 96, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation ); // Makes smallest edge 96 pixels, preserving aspect ratio
if( pictureData.width() != 96 || pictureData.height() != 96 )
{
// Copy the middle part of the picture.
pictureData = pictureData.copy( (pictureData.width() - 96) / 2, // X
(pictureData.height() - 96) / 2, // Y
96, 96 );
}
QString pictureDir = KMessConfig::instance()->getAccountDirectory( currentAccount_->getHandle() ) + "/displaypics/";
QString tempPictureFile = pictureDir + "temporary-picture.png";
if( ! pictureData.save( tempPictureFile, "PNG" ) )
{
KMessageBox::sorry( this,
i18n( "An error occurred while trying to change the display picture.\n"
"Make sure that you have selected an existing image file." ),
i18n( "KMess" ) );
}
QString msnObjectHash( KMessShared::generateFileHash( tempPictureFile ).toBase64() );
const QString safeMsnObjectHash( msnObjectHash.replace( QRegExp("[^a-zA-Z0-9+=]"), "_" ) );
// Save the new display picture with its hash as name, to ensure correct caching
QString pictureName = msnObjectHash + ".png";
QDir pictureFolder = QDir( pictureDir );
// Do not overwrite identical pictures
if( ! pictureFolder.exists( pictureName ) )
{
if( ! pictureFolder.rename( tempPictureFile, pictureName ) )
{
kWarning() << "The display picture file could not be renamed from" << tempPictureFile << "to" << pictureName << ".";
return true;
}
}
currentAccount_->setPicturePath( pictureDir + pictureName );
currentAccount_->setOriginalPicturePath( mimeUrl.path() );
dropEvent->acceptProposedAction();
}
}
}
else if( obj == contactListView_->viewport() )
{
@@ -488,44 +611,6 @@ bool KMessView::eventFilter(QObject *obj, QEvent *event)
}
}
}
else if( obj == personalMessageInput_ )
{
if( eventType == QEvent::Enter )
{
// Mouse enters widget's boundaries
// Just a bit different from the original client, already change the background line web-forms also do.
personalMessageInput_->setStyleSheet( "QLineEdit{ background-color: base; }" );
}
else if( eventType == QEvent::Leave )
{
// Mouse leaves the widget.
if( ! personalMessageInput_->hasFocus() )
{
personalMessageInput_->setStyleSheet( "QLineEdit{ background-color: transparent; }" );
}
}
else if( eventType == QEvent::FocusIn )
{
// Personal status mesage got the focus
personalMessageInput_->setStyleSheet( "QLineEdit{ background-color: base; }" );
// Clear if there is no status message, but a placeholder label
if( currentAccount_->getPersonalMessage().isEmpty() )
{
personalMessageInput_->clear();
}
else
{
// Select all text for editing
personalMessageInput_->selectAll();
}
}
else if( event->type() == QEvent::FocusOut )
{
// Lost the focus
personalMessageInput_->setStyleSheet( "QLineEdit{ background-color: transparent; }" );
}
}
return false; // don't stop processing.
}
@@ -1204,7 +1289,9 @@ void KMessView::showToolTip( const QPoint &point )
{
lastSeenString = i18n( "Connected" );
}
else if( lastSeen.toTime_t() == 0 || lastSeen.isNull() )
else if( lastSeen.toTime_t() == 0
|| lastSeen.toTime_t() == UINT_MAX
|| lastSeen.isNull() )
{
lastSeenString = i18n( "Not seen yet" );
}
@@ -1219,7 +1306,9 @@ void KMessView::showToolTip( const QPoint &point )
// Add last message date
const QDateTime& lastMessage( itemData[ "lastMessage" ].toDateTime() );
QString lastMessageString;
if( lastMessage.toTime_t() == 0 || lastMessage.isNull() )
if( lastMessage.toTime_t() == 0
|| lastMessage.toTime_t() == UINT_MAX
|| lastMessage.isNull() )
{
lastMessageString = i18n( "No messages yet" );
}
@@ -1663,30 +1752,81 @@ void KMessView::slotForwardUnblockContact()
// Called when the enter key is pressed on the personal message input
void KMessView::slotPersonalMessageEnterPressed()
/**
* @brief Update the friendly name from the inline editing label.
*
* Sends to the server the new friendly name selected by clicking
* the friendly name inline editing label.
*
* @param refreshOnly When true, the FN widget is only updated with the
* current account's name. When false, it is updated
* with the default message, and nothing is sent to
* the server.
*/
void KMessView::updateFriendlyName( bool refreshOnly )
{
personalMessageInput_->clearFocus();
const QString& defaultTooltip( i18nc( "Default friendly name tooltip", "Click here to change your friendly name" ) );
const QString& defaultName( currentAccount_->getFriendlyName( STRING_ORIGINAL ).trimmed() );
// When refreshing the message or when the focus losing isn't voluntary, don't update it on the server
if( refreshOnly || ! isActiveWindow() || ! topLevelWidget()->isActiveWindow() )
{
#ifdef KMESSDEBUG_KMESSVIEW_GENERAL
kDebug() << "Refreshing name only: initial update or non-intentional focus lose.";
#endif
// Refresh the message
friendlyNameInput_->setToolTip( defaultTooltip );
friendlyNameInput_->setText( defaultName );
return;
}
// Get message
QString newName( friendlyNameInput_->text().trimmed() );
#ifdef KMESSDEBUG_KMESSVIEW_GENERAL
kDebug() << "Updating friendly name to:" << newName;
#endif
// Set a default name (the email address) if the field is left empty
if( newName.isEmpty() )
{
newName = currentAccount_->getHandle();
}
// Only update the name if it's been changed
if( defaultName == newName )
{
return;
}
// Update the name and save the changes
currentAccount_->setFriendlyName( newName );
friendlyNameInput_->setToolTip( newName );
// Commit changes to disk, now
currentAccount_->saveProperties();
// Notify changes to the MSN server
emit changeFriendlyName( newName );
}
/**
* @brief Called when the personal message input looses focus
* @brief Update the personal message from the inline editing label.
*
* Sends to the server the new personal message selected by the user.
* Sends to the server the new personal message selected by clicking
* the personal message inline editing label.
*
* @param refreshOnly When true, the PM widget is only updated with the
* current account's message, or with the default
* message, and nothing is sent to the server.
* current account's message. When false, it is updated
* with the default message, and nothing is sent to
* the server.
*/
void KMessView::slotPersonalMessageLostFocus( bool refreshOnly )
void KMessView::updatePersonalMessage( bool refreshOnly )
{
const QString& defaultMessage( i18nc( "Default personal message shown in the contact list", "&lt;Enter your personal message here&gt;" ) );
const QString& defaultTooltip( i18nc( "Default personal message tooltip", "Enter here a message to show to your contacts: they will see it along with your friendly name" ) );
personalMessageInput_->clearFocus();
contactListView_->setFocus();
const QString& defaultMessage( i18nc( "Default personal message shown in the contact list", "[i]Click to set a personal message[/i]" ) );
const QString& defaultTooltip( i18nc( "Default personal message tooltip", "Click here to insert a message to show to your contacts: they will see it along with your friendly name" ) );
// When refreshing the message or when the focus losing isn't voluntary, don't update it on the server
if( refreshOnly || ! isActiveWindow() || ! topLevelWidget()->isActiveWindow() )
@@ -1696,11 +1836,11 @@ void KMessView::slotPersonalMessageLostFocus( bool refreshOnly )
#endif
// Refresh the message
const QString &message( currentAccount_->getPersonalMessage( STRING_ORIGINAL ) );
const QString &message( currentAccount_->getPersonalMessage( STRING_ORIGINAL ).trimmed() );
if( message.isEmpty() )
{
personalMessageInput_->setToolTip( defaultTooltip );
personalMessageInput_->setText( defaultMessage );
personalMessageInput_->setText( defaultMessage, true );
}
else
{
@@ -1708,15 +1848,11 @@ void KMessView::slotPersonalMessageLostFocus( bool refreshOnly )
personalMessageInput_->setText( message );
}
personalMessageInput_->setCursorPosition(0);
return;
}
personalMessageInput_->setCursorPosition(0);
// Get message
const QString& message( personalMessageInput_->text() );
const QString& message( personalMessageInput_->text().trimmed() );
#ifdef KMESSDEBUG_KMESSVIEW_GENERAL
kDebug() << "Updating personal message to:" << message;
@@ -1747,7 +1883,7 @@ void KMessView::slotPersonalMessageLostFocus( bool refreshOnly )
if( message.isEmpty() )
{
personalMessageInput_->setToolTip( defaultTooltip );
personalMessageInput_->setText( defaultMessage );
personalMessageInput_->setText( defaultMessage, true );
}
}
@@ -2088,15 +2224,15 @@ void KMessView::slotUpdateUserStatus()
{
const Status status( currentAccount_->getStatus() );
// Avoid newlines, which cause problems to the layout.
QString friendlyName( currentAccount_->getFriendlyName( STRING_LIST_SETTING_ESCAPED ).replace( '\n', ' ' ) );
#ifdef KMESSDEBUG_KMESSVIEW_GENERAL
kDebug() << "Updating user status to:" << MsnStatus::getName( status );
#endif
// Update the widgets
onlineStatusLabel_->setText( friendlyName );
updateFriendlyName( true );
updatePersonalMessage( true );
statusButton_->setText( MsnStatus::getName( status ) );
statusButton_->setIcon( MsnStatus::getIcon( status ) );
}
+6 -4
View File
@@ -139,10 +139,10 @@ class KMessView : public QWidget, private Ui::KMessView
void slotMoveGroupDown();
// Move up the selected group
void slotMoveGroupUp();
// Called when the enter key is pressed on the personal message input
void slotPersonalMessageEnterPressed();
// Called when the personal message input looses focus
void slotPersonalMessageLostFocus( bool refreshOnly = false );
// Update the friendly name from the inline editing label
void updateFriendlyName( bool refreshOnly = false );
// Update the personal message from the inline editing label
void updatePersonalMessage( bool refreshOnly = false );
// Generate the lists of actions for the "copy/move contact to group" menus
void rebuildContactActions();
// Delay a bit updating the groups status
@@ -230,6 +230,8 @@ class KMessView : public QWidget, private Ui::KMessView
void allowContact(QString handle);
// Request to block a contact
void blockContact(QString handle);
// Request to change the friendly name
void changeFriendlyName( QString friendlyName );
// Request to change the personal message.
void changePersonalMessage(QString personalMessage);
// Request a private chat with a contact
+14 -85
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>483</height>
<width>392</width>
<height>546</height>
</rect>
</property>
<property name="sizePolicy">
@@ -75,6 +75,9 @@
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@@ -114,7 +117,7 @@
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="GradientElideLabel" name="onlineStatusLabel_">
<widget class="InlineEditLabel" name="friendlyNameInput_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -127,27 +130,9 @@
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="indent">
<number>0</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@@ -183,38 +168,9 @@
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="KLineEdit" name="personalMessageInput_">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="maxLength">
<number>256</number>
</property>
<property name="frame">
<bool>false</bool>
</property>
<property name="urlDropsEnabled">
<bool>false</bool>
</property>
<property name="trapEnterKeyEvent" stdset="0">
<bool>true</bool>
</property>
<property name="lineWidth" stdset="0">
<number>1</number>
</property>
<property name="enableSqueezedText" stdset="0">
<bool>true</bool>
<widget class="InlineEditLabel" name="personalMessageInput_">
<property name="text">
<string/>
</property>
</widget>
</item>
@@ -566,6 +522,11 @@
<extends>QLabel</extends>
<header>utils/gradientelidelabel.h</header>
</customwidget>
<customwidget>
<class>InlineEditLabel</class>
<extends>QLabel</extends>
<header>utils/inlineeditlabel.h</header>
</customwidget>
</customwidgets>
<includes>
<include location="global">KLineEdit</include>
@@ -574,38 +535,6 @@
</includes>
<resources/>
<connections>
<connection>
<sender>personalMessageInput_</sender>
<signal>returnPressed()</signal>
<receiver>KMessView</receiver>
<slot>slotPersonalMessageEnterPressed()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>personalMessageInput_</sender>
<signal>lostFocus()</signal>
<receiver>KMessView</receiver>
<slot>slotPersonalMessageLostFocus()</slot>
<hints>
<hint type="sourcelabel">
<x>20</x>
<y>20</y>
</hint>
<hint type="destinationlabel">
<x>20</x>
<y>20</y>
</hint>
</hints>
</connection>
<connection>
<sender>emailLabel_</sender>
<signal>leftClickedUrl()</signal>
+2 -1
View File
@@ -268,7 +268,8 @@ void KMessViewDelegate::paint( QPainter *painter, const QStyleOptionViewItem &op
if( itemData[ "type" ].toInt() == ContactListModelItem::ItemContact
&& ! itemData[ "isReverse" ].toBool() ) // The contact does not have us in its list
{
painter->fillRect( option.rect, QColor( 255,0,0,20 ) );
// TODO: fontknocker (19 Feb 10): re-enable this when we get our list memberships sorted out.
//painter->fillRect( option.rect, QColor( 255,0,0,20 ) );
}
// Paint the images
+9 -8
View File
@@ -44,13 +44,13 @@ int main(int argc, char *argv[])
KMESS_VERSION, // app version from config-kmess.h
ki18n("A Live Messenger client for KDE"), // short description
KAboutData::License_GPL, // license
ki18n("(c) 2002-2009, Mike K. Bennett\n" // copyright
"(c) 2005-2009, Diederik van der Boor\n"
"(c) 2007-2009, Valerio Pilo\n"
"(c) 2008-2009, Antonio Nastasi\n"
"(c) 2008-2009, Ruben Vandamme\n"
"(c) 2009, Sjors Gielen\n"
"(c) 2009, Adam Goossens\n"),
ki18n("(c) 2002-2010, Mike K. Bennett\n" // copyright
"(c) 2005-2010, Diederik van der Boor\n"
"(c) 2007-2010, Valerio Pilo\n"
"(c) 2008-2010, Antonio Nastasi\n"
"(c) 2008-2010, Ruben Vandamme\n"
"(c) 2009-2010, Sjors Gielen\n"
"(c) 2009-2010, Adam Goossens\n"),
KLocalizedString(),
"http://www.kmess.org/", // home page
"bugs" "@" "kmess" "." "org" // address for bugs
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
aboutData.addCredit( ki18n("Mauricio Rother"), ki18n("Brazilian Portuguese translation"), "mauricio" "@" "digicomm" "." "com.br");
aboutData.addCredit( ki18n("Leonel Freire"), ki18n("More Brazilian Portuguese translation"), "leonelfreire" "@" "gmail" "." "com");
aboutData.addCredit( ki18n("Sergio Rafael Lemke"), ki18n("More Brazilian Portuguese translation"), "bedi" "." "com" "@" "gmail" "." "com");
aboutData.addCredit( ki18n("Maurício Arozi Moraes"), ki18n("More Brazilian Portuguese translation"));
aboutData.addCredit( ki18n("Morris Arozi Moraes"), ki18n("More Brazilian Portuguese translation"));
aboutData.addCredit( ki18n("Jaume Cornadó"), ki18n("Catalan translation"), "jaumec" "@" "lleida" "." "net");
aboutData.addCredit( ki18n("Adrià Arrufat"), ki18n("More Catalan translation"), "swiftscythe" "@" "gmail" "." "com");
@@ -179,6 +179,7 @@ int main(int argc, char *argv[])
aboutData.addCredit( ki18n("David López"), ki18n("Nudge button in chat"), "grannost" "@" "gmail" "." "com" );
aboutData.addCredit( ki18n("Pieterjan Camerlynck"), ki18n("Roaming Service support"), "pieterjan" "." "camerlynck" "@" "gmail" "." "com" );
aboutData.addCredit( ki18n("Anastasios Bourazanis"), ki18n("Emoticon preview in settings page,clickable contact properties dialog text"), "a.brzns" "@" "gmail" "." "com");
aboutData.addCredit( ki18n("Marco Mentasti"), ki18n("Internationalization fixes, drag'n'drop of images into display pictures"), "marcomentasti" "@" "gmail" "." "com" );
// Other apps
aboutData.addCredit( ki18n("KMerlin (kmerlin.olsd.de)"), ki18n("Inspiration and assorted code"));
+1 -1
View File
@@ -451,7 +451,7 @@ void MsnConnection::parseError( const QStringList &command, const QByteArray &pa
isWarning = true;
break;
case 229:
errorMessage = i18n("The group name is too long; it cannot be longer than 61 bytes");
errorMessage = i18n("The group name is too long; it cannot be longer than 61 characters");
isWarning = true;
break;
case 230:
+75 -53
View File
@@ -37,11 +37,15 @@
#include <QTextDocument> // for Qt::escape()
#include <QUrl>
#include <QtEndian>
#include <QDateTime>
#include <QNetworkProxy>
#include <KDialog>
#include <KLocale>
#include <KMessageBox>
#include <gcrypt.h>
#ifdef KMESSDEBUG_CONTACTLISTMODELTEST
#include "../../tests/modeltest/modeltest.h"
#endif
@@ -840,45 +844,26 @@ RoamingService* MsnNotificationConnection::createRoamingService()
* @param secret The secret data to encryption
* @param iv The initial vector for cbc mode
*/
QByteArray MsnNotificationConnection::createTripleDes ( const QByteArray key, const QByteArray secret,
const QCA::InitializationVector& iv )
QByteArray MsnNotificationConnection::createTripleDes ( const QByteArray &key, const QByteArray &secret, const QByteArray &iv )
{
// check for Triple Des with CBC support.
if ( ! QCA::isSupported( "tripledes-cbc" ) )
{
kWarning() << "Triple DES encryption not supported, please install the qca2 package and its openssl plugin!";
slotError( i18n( "Triple DES encryption is not supported. "
"This means you probably do not have installed the qca2 or qca2-plugin-ossl packages. "
"Please install them and retry." ),
MsnSocketBase::ERROR_AUTH_COMPUTATION );
return QByteArray();
}
// Create the key using the key parameter and secret data
QCA::SymmetricKey desKey( key );
QCA::SecureArray data( secret );
// Create the TripleDes object.
QCA::Cipher des3( QString ( "tripledes" ), QCA::Cipher::CBC, QCA::Cipher::NoPadding, QCA::Encode, desKey, iv );
// Chiper the data and check for the errors
QCA::SecureArray temp = des3.update ( data );
if ( ! des3.ok() )
{
kWarning() << "Triple DES computation failed on update step";
return "";
}
// Finish the compute and check for errors
des3.final();
if ( ! des3.ok() )
{
kWarning() << "Triple DES computation failed on final step";
return "";
}
// Return the encrypted data
return temp.toByteArray();
// Initialize a triple-DES CBC encryption
gcry_cipher_hd_t handle;
gcry_cipher_open( &handle, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0 );
// Set key and IV
gcry_cipher_setkey( handle, key.constData(), key.size() );
gcry_cipher_setiv( handle, iv.constData(), iv.size() );
// Encrypt the data. The out buffer has to have the same size as the in buffer.
char *encrypted = new char[ secret.size() ];
gcry_cipher_encrypt( handle, (void*) encrypted, secret.size(), secret.constData(), secret.size() );
// Clean up the cipher handle
gcry_cipher_close( handle );
QByteArray encryptedByteArray( encrypted, secret.size() );
delete [] encrypted;
return encryptedByteArray;
}
@@ -1105,6 +1090,7 @@ void MsnNotificationConnection::gotCvr( const QStringList& command )
// Set the connected status to false
connected_ = false;
initialStatusSent_ = false;
// Send the USR command
sendCommand( "USR", "SSO I " + currentAccount_->getHandle() );
@@ -1453,8 +1439,8 @@ void MsnNotificationConnection::gotUsr( const QStringList& command )
// closed before this point, we just try again with HTTP, which usually works.
isInitiatingConnection_ = false;
const QString& policy ( command[4] ); // Policy
nonceBase64_ = command[5]; // Base64 nonce
const QString& policy ( command[4] ); // Policy
nonceBase64_ = command[5].toAscii(); // Base64 nonce
// Change statusbar
emit statusMessage( i18n("Authenticating..."), false );
@@ -1797,19 +1783,37 @@ void MsnNotificationConnection::loginSucceeded()
deleteSoapClient( passportLoginService_ );
passportLoginService_ = 0;
// Initialize the QCA and create the IV key for triple des encryption
QCA::Initializer init;
QCA::InitializationVector iv(8);
// Initialize the GCrypt library if it wasn't done yet
if( !gcry_control( GCRYCTL_INITIALIZATION_FINISHED_P ) )
{
gcry_check_version( 0 );
// We don't need secure memory for this, I guess... Passwords and
// everything have already been sent.
gcry_control( GCRYCTL_DISABLE_SECMEM, 0 );
gcry_control( GCRYCTL_INITIALIZATION_FINISHED, 0 );
if( !gcry_control( GCRYCTL_INITIALIZATION_FINISHED_P ) )
{
qWarning() << "Failed to initialize GCrypt.";
return;
}
}
// Create the IV key for triple des encryption
const unsigned short ivLength = 8;
char *rawIv = new char[ ivLength ];
gcry_create_nonce( rawIv, ivLength );
QByteArray iv( rawIv, ivLength );
delete [] rawIv;
// Create the keys and hashes needed
QByteArray key1, key2, key3;
QByteArray hash, des3hash;
// Use the nonce received from last USR commands and the proof key for authentication
QByteArray nonce = nonceBase64_.toLatin1();
QByteArray nonce( nonceBase64_ );
// Compute the value to send with USR SSO command
QString magic1( "WS-SecureConversationSESSION KEY HASH" );
QString magic1( "WS-SecureConversationSESSION KEY HASH" );
QString magic2( "WS-SecureConversationSESSION KEY ENCRYPTION" );
key1 = QByteArray::fromBase64( currentAccount_->getToken( "MessengerClearProof" ).toLatin1() );
@@ -1833,12 +1837,12 @@ void MsnNotificationConnection::loginSucceeded()
blob.cryptMode = qToLittleEndian( 1 ); // CRYPT_MODE_CBC
blob.cipherType = qToLittleEndian( 0x6603 ); // Triple DES
blob.hashType = qToLittleEndian( 0x8004 ); // SHA-1
blob.ivLength = qToLittleEndian( 8 );
blob.ivLength = qToLittleEndian( iv.size() );
blob.hashLength = qToLittleEndian( 20 ); // Length of the HMAC hash
blob.cipherLength = qToLittleEndian( 72 );
// Copy the IV Bytes, the hash and chiper value in blob struct
memcpy( (char*) blob.ivBytes, iv.constData() , des3hash.size() );
memcpy( (char*) blob.ivBytes, iv.constData(), iv.size() );
memcpy( (char*) blob.hashBytes, hash.constData(), hash.size() );
memcpy( (char*) blob.cipherBytes, des3hash.constData(), des3hash.size() );
@@ -1856,15 +1860,16 @@ void MsnNotificationConnection::loginIncorrect()
kDebug() << "Passport login was incorrect.";
#endif
// NOTE: a similar thing also happens in soapRequestFailed(),
// but for fatal SOAP errors.
slotError( "Authentication failed. Wrong login credentials.", MsnSocketBase::ERROR_AUTH_LOGIN );
// Delete the login handler
// Delay deletion so it can complete the method.
deleteSoapClient( passportLoginService_ );
passportLoginService_ = 0;
// NOTE: a similar thing also happens in soapRequestFailed(),
// but for fatal SOAP errors.
slotError( "Authentication failed. Wrong login credentials.", MsnSocketBase::ERROR_AUTH_LOGIN );
}
@@ -2574,6 +2579,14 @@ void MsnNotificationConnection::removeContact(QString handle, bool block)
// Remove the contact from AB
AddressBookService *addressBook = createAddressBookService();;
addressBook->deleteContact( contactId );
// if not blocking, make sure we re-add to the Allow list.
// ABContactDelete removes them from the Allow list for some reason. This was what
// caused the "you've been added" dialog to popup for deleted contacts on the next login.
if ( ! block )
{
allowContact( handle );
}
}
@@ -3022,6 +3035,15 @@ void MsnNotificationConnection::slotError( QString error, MsnSocketBase::ErrorTy
}
}
// if there was a proxy error, try removing the proxy details and
// trying again.
if ( type == MsnSocketBase::ERROR_PROXY )
{
QNetworkProxy::setApplicationProxy( QNetworkProxy::NoProxy );
openConnection();
return;
}
// Clean up the mess left by the SOAP classes
if( qobject_cast<OfflineImService*>( sender() ) != 0 )
{
+3 -5
View File
@@ -26,8 +26,6 @@
#include <QDateTime>
#include <QList>
#include <QTimer>
#include <QtCrypto>
@@ -210,8 +208,8 @@ class MsnNotificationConnection : public MsnConnection
// Create the passport login handler
PassportLoginService *createPassportLoginService();
// Create triple des encryption
QByteArray createTripleDes ( const QByteArray key, const QByteArray secret,
const QCA::InitializationVector& iv );
QByteArray createTripleDes ( const QByteArray &key, const QByteArray &secret,
const QByteArray &iv );
// Received response to adl command
void gotAdl( const QStringList& command, const QString &payload = "" );
// Received confirmation of the user's status change
@@ -306,7 +304,7 @@ class MsnNotificationConnection : public MsnConnection
AddressBookService *addressBookService_;
bool connected_;
// Nonce received by the server on first SSO command
QString nonceBase64_;
QByteArray nonceBase64_;
// The list of contacts' role
QHash<QString,int> contactsRole_;
+1
View File
@@ -55,6 +55,7 @@ class MsnSocketBase : public QObject
/// These are generic socket and connection errors
ERROR_UNKNOWN = 0 /// An unspecified error has occurred
, ERROR_CONNECTING /// There was an error while establishing the connection
, ERROR_PROXY /// The configured proxy could not found/is invalid/etc.
, ERROR_CONNECTING_GATEWAY /// There was an error while establishing the HTTP connection
, ERROR_DROP /// The connection was dropped
, ERROR_DATA /// An error within the data was received
+8
View File
@@ -537,6 +537,14 @@ void MsnSocketTcp::slotSocketError( QAbstractSocket::SocketError errorCode )
type = ERROR_DATA;
break;
case QAbstractSocket::ProxyConnectionRefusedError:
case QAbstractSocket::ProxyConnectionClosedError:
case QAbstractSocket::ProxyConnectionTimeoutError:
case QAbstractSocket::ProxyNotFoundError:
case QAbstractSocket::ProxyProtocolError:
type = ERROR_PROXY;
break;
default:
type = ERROR_UNKNOWN;
break;
+2 -2
View File
@@ -547,7 +547,7 @@ const QString MsnSwitchboardConnection::convertMsnColorToHtmlColor( QString& col
// Fill the color out to six characters
else if( color.length() < 6 )
{
color.rightJustified( 6, '0' );
color = color.rightJustified( 6, '0' );
}
// Get the color components
@@ -1048,7 +1048,7 @@ void MsnSwitchboardConnection::parseChatMessage( const QString &contactHandle, c
QString family( message.getSubValue( "X-MMS-IM-Format", "FN" ) );
const QString& effects( message.getSubValue( "X-MMS-IM-Format", "EF" ) );
QString color( message.getSubValue( "X-MMS-IM-Format", "CO" ) );
family = QUrl::fromPercentEncoding( family.toUtf8() );
color = convertMsnColorToHtmlColor( color );
+6
View File
@@ -598,6 +598,7 @@ void AddressBookService::parseAddressBook( const QDomElement &body )
// easy the life of the users...for the moment..:P
if( handle.isEmpty() || handle == "messenger@microsoft.com" )
{
kWarning() << "Skipped 'messenger@microsoft.com' contact!";
continue;
}
@@ -723,6 +724,11 @@ void AddressBookService::parseMembershipLists( const QDomElement &body )
continue;
}
}
// HACK: See parseAddressBook() for details
else if( handle == "messenger@microsoft.com" )
{
continue;
}
// Insert the current contact in the hash with their respective role
// If the contact is already listed, the new value is OR'ed (set bit flag) with the old roleId
+9 -5
View File
@@ -449,20 +449,24 @@ void HttpSoapConnection::slotRequestFinished( QNetworkReply *reply )
// A response has arrived, stop the timeout detection timer
responseTimer_.stop();
QByteArray replyContents( reply->readAll() );
int statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt();
QString error( reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString() );
const QByteArray& replyContents( reply->readAll() );
const int statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt();
const QString& error( reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString() );
#ifdef KMESSDEBUG_HTTPSOAPCONNECTION_GENERAL
bool requestSuccess = false;
QUrl replyUrl( reply->url() );
const QUrl &replyUrl( reply->url() );
kDebug() << "Received response: code" << statusCode
<< reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute )
<< " from" << replyUrl;
#endif
#ifdef KMESSDEBUG_HTTPSOAPCONNECTION_HTTPDUMP
kDebug() << "Reply contents:";
kDebug() << replyContents;
// Create the document with the content of SOAP reply to indent it
QDomDocument document;
document.setContent( replyContents );
kDebug() << document.toString();
#endif
// Parse the body of the HTTP response (copying the other attributes from the request)
+2 -2
View File
@@ -305,8 +305,8 @@ void PassportLoginService::parseSoapFault( SoapMessage *message )
login();
// Resend the failed message
SoapMessage *message = getCurrentRequest( true /* copy */ );
sendSecureRequest( message, inProgressRequests_.value( getCurrentRequest() ) );
SoapMessage *messageCopy = getCurrentRequest( true /* copy */ );
sendSecureRequest( messageCopy, inProgressRequests_.value( getCurrentRequest() ) );
}
else
{
+16 -4
View File
@@ -52,6 +52,12 @@ SystemTrayWidget::SystemTrayWidget( QWidget *parent )
connect( currentAccount_, SIGNAL( changedFriendlyName() ),
this, SLOT ( statusChanged() ) );
// Connect email related signals
connect( currentAccount_, SIGNAL( changedNoEmails() ),
this, SLOT ( statusChanged() ) );
connect( currentAccount_, SIGNAL( changedEmailDisplaySettings() ),
this, SLOT ( statusChanged() ) );
// Force changing the icon
statusChanged();
}
@@ -245,15 +251,21 @@ void SystemTrayWidget::statusChanged()
{
#if !defined(Q_WS_WIN)
newTooltip += i18nc( "Tray icon tooltip, HTML version",
"<br><b>%1</b> (%2)",
"<br><b>%1</b> (%2)%3",
currentAccount_->getFriendlyName( STRING_CLEANED_ESCAPED ),
MsnStatus::getName( status ) );
MsnStatus::getName( status ),
currentAccount_->getShowEmail()?
i18nc("Tray icon email count, HTML version", "<br />%1 emails", currentAccount_->getNoEmails()):""
);
#else
// Qt on Windows does not support html in the system tray widget.
newTooltip += i18nc( "Tray icon tooltip, text version",
" - %1 (%2)",
" - %1 (%2)%3",
currentAccount_->getFriendlyName( STRING_CLEANED ),
MsnStatus::getName( status ) );
MsnStatus::getName( status ),
currentAccount_->getShowEmail()?
i18nc("Tray icon email count, text version", " - %1 emails", currentAccount_->getNoEmails()):""
);
#endif
}
+1 -1
View File
@@ -92,7 +92,7 @@
<item>
<widget class="KLineEdit" name="passwordEdit_">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+234
View File
@@ -0,0 +1,234 @@
/***************************************************************************
inlineeditlabel.cpp - description
-------------------
begin : Tue Dec 29 2009
copyright : (C) 2009 by Valerio Pilo
email : valerio@kmess.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "inlineeditlabel.h"
#include "utils/kmessshared.h"
#include "kmessdebug.h"
#include <QKeyEvent>
#include <QToolTip>
/**
* Constructor
*
* @param parent Parent widget
*/
InlineEditLabel::InlineEditLabel( QWidget *parent )
: QWidget( parent )
, Ui::InlineEditLabel()
, maxLength_( 0 )
, mode_( STRING_FORMATTED )
{
setupUi( this );
enableEditMode( false );
// We need to handle some events in a custom way
installEventFilter( this );
label_->installEventFilter( this );
lineEdit_->installEventFilter( this );
}
/**
* The destructor
*/
InlineEditLabel::~InlineEditLabel()
{
}
/**
* Switch the widget to the label or the lineedit.
*
* @param editMode If true, enable editing the label's text. If false, show the label.
*/
void InlineEditLabel::enableEditMode( bool editMode )
{
if( editMode )
{
// Check if we are already editing
if( label_->isHidden() )
{
return;
}
label_->hide();
lineEdit_->show();
lineEdit_->setFocus();
}
else
{
// Check if we are already showing the label
if( label_->isVisible() )
{
return;
}
label_->show();
lineEdit_->hide();
// Update the label from the line edit text
const QString &text( lineEdit_->text() );
// Do nothing when there are no changes to avoid unneeded updates
if( text == text_.getOriginal() )
{
return;
}
text_ = text;
label_->setText( text_.getString( mode_ ) );
emit changed();
}
}
/**
* The label or the lineedit received an event.
*
* @param obj Source object of the event
* @param event Event to handle
* @return bool Whether or not to continue processing the event.
*/
bool InlineEditLabel::eventFilter( QObject *obj, QEvent *event )
{
Q_UNUSED( obj );
QEvent::Type eventType = event->type();
if( eventType == QEvent::KeyRelease )
{
int key = static_cast<QKeyEvent*>( event )->key();
// Confirm editing on enter key press
if( key == Qt::Key_Return )
{
enableEditMode( false );
}
// Cancel editing on esc key press
else if( key == Qt::Key_Escape )
{
// Restore the original text to avoid signaling any change
lineEdit_->setText( text_.getOriginal() );
enableEditMode( false );
}
else if( maxLength_ > 0 )
{
// Check that the size in bytes of the string is within the set limit
const QString &text( lineEdit_->text() );
const QByteArray &stringData( text.toUtf8() );
if( stringData.length() > maxLength_ )
{
lineEdit_->setText( KMessShared::fixStringToByteSize( text, maxLength_ ) );
QToolTip::showText( lineEdit_->mapToGlobal( lineEdit_->rect().bottomLeft() ),
i18n( "The text cannot be longer than %1 characters.", maxLength_ ),
lineEdit_ );
return true;
}
}
return true;
}
if( eventType == QEvent::MouseButtonRelease && ! hasFocus() )
{
// We were clicked
enableEditMode( true );
}
else if( eventType == QEvent::FocusOut || eventType == QEvent::NonClientAreaMouseButtonPress )
{
// We lost focus
enableEditMode( false );
}
return false; // don't stop processing.
}
/**
* Change the text formatting mode for the label.
*
* @param mode The new formatting mode
* @see RichTextEditor and FormattedString
*/
void InlineEditLabel::setFormattingMode( FormattingMode mode )
{
mode_ = mode;
}
/**
* Limit the amount of text which can be input.
*
* @param length New maximum length in bytes for the field.
*/
void InlineEditLabel::setMaxLength( int length )
{
maxLength_ = length;
}
/**
* Set the text to show.
*
* @param text The text to set
* @param labelOnly If true, the text will only be set to the label,
* and the lineedit will be empty
*/
void InlineEditLabel::setText( const QString &text, bool labelOnly )
{
if( labelOnly )
{
text_ = QString();
label_->setText( FormattedString( text ).getString( mode_ ) );
lineEdit_->setText( QString() );
}
else
{
text_ = text;
label_->setText( text_.getString( mode_ ) );
lineEdit_->setText( text_.getOriginal() );
}
}
/**
* Retrieve the current text.
*
* @return QString
*/
const QString &InlineEditLabel::text()
{
return text_.getOriginal();
}
#include "inlineeditlabel.moc"
+80
View File
@@ -0,0 +1,80 @@
/***************************************************************************
inlineeditlabel.h - description
-------------------
begin : Tue Dec 29 2009
copyright : (C) 2009 by Valerio Pilo
email : valerio@kmess.org
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef INLINEEDITLABEL_H
#define INLINEEDITLABEL_H
#include "ui_inlineeditlabel.h"
#include "utils/richtextparser.h"
#include <QString>
#include <QWidget>
/**
* @brief An inline editing label.
*
* This is normally a label widget. By clicking on it, the label's contents can be changed,
* because the label turns into a line edit.
* The label supports rich text (and it is enabled by default), so emoticons,
* links etc can be used.
*
* @author Valerio Pilo
*/
class InlineEditLabel : public QWidget, private Ui::InlineEditLabel
{
Q_OBJECT
public:
// Constructor
InlineEditLabel( QWidget *parent = 0 );
// The destructor
virtual ~InlineEditLabel();
// The label or the lineedit received an event
bool eventFilter( QObject *obj, QEvent *event );
// Change the text formatting mode for the label
void setFormattingMode( FormattingMode mode );
// Limit the amount of text which can be input
void setMaxLength( int length );
// Set the text to show
void setText( const QString &text, bool labelOnly = false );
// Retrieve the current text
const QString & text();
private: // Private methods
// Switch the widget to the label or the lineedit
void enableEditMode( bool editMode );
private: // Private attributes
// Maximum length in bytes of the text in the input field
int maxLength_;
// Text formatting mode for the label
FormattingMode mode_;
// The current text
FormattedString text_;
signals:
// Label text was changed
void changed();
};
#endif
+78
View File
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InlineEditLabel</class>
<widget class="QWidget" name="InlineEditLabel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>337</width>
<height>45</height>
</rect>
</property>
<property name="windowTitle">
<string>InlineEditLabel</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="GradientElideLabel" name="label_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="indent">
<number>0</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_">
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GradientElideLabel</class>
<extends>QLabel</extends>
<header>utils/gradientelidelabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+36 -4
View File
@@ -23,6 +23,7 @@
#include "model/contactlist.h"
#include "kmessdbusadaptor.h"
#include "utils/richtextparser.h"
#include "network/msnnotificationconnection.h"
#include <QtDBus/QDBusMetaType>
@@ -120,6 +121,39 @@ int KMessDBus::getStatus()
// Set the personal message
void KMessDBus::setPersonalMessage( QString message )
{
#ifdef KMESSDEBUG_KMESSDBUS
kDebug() << "setPersonalMessage( QString message ) called";
#endif
if( kmess_->isConnected() )
{
kmess_->msnNotificationConnection_->changePersonalMessage( message );
kmess_->currentAccount_->setPersonalMessage( message );
}
}
// Get the personal message
QString KMessDBus::getPersonalMessage()
{
#ifdef KMESSDEBUG_KMESSDBUS
kDebug() << "getPersonalMessage() called";
#endif
//return kmess_->currentAccount_->getStatus();
if( kmess_->isConnected() )
{
return kmess_->currentAccount_->getPersonalMessage();
}
return QString();
}
// Get friendly name
QString KMessDBus::getFriendlyName( int formattingMode )
{
@@ -135,10 +169,8 @@ QString KMessDBus::getFriendlyName( int formattingMode )
return kmess_->currentAccount_->getFriendlyName();
}
else
{
return kmess_->currentAccount_->getFriendlyName( FormattingMode( formattingMode ) );
}
return kmess_->currentAccount_->getFriendlyName( FormattingMode( formattingMode ) );
}
+2
View File
@@ -46,6 +46,8 @@ class KMessDBus: public QObject
bool isConnected();
void setStatus( int status );
int getStatus();
void setPersonalMessage( QString message );
QString getPersonalMessage();
QString getFriendlyName( int formattingMode = -1 );
DBusContactList getList();
void requestChat( QString handle );
+6
View File
@@ -14,6 +14,12 @@
<method name="getStatus">
<arg name="status" type="i" direction="out"/>
</method>
<method name="setPersonalMessage">
<arg name="message" type="s" direction="in"/>
</method>
<method name="getPersonalMessage">
<arg name="message" type="s" direction="out"/>
</method>
<method name="getFriendlyName" >
<arg direction="in" type="i" name="formattingMode" />
<arg direction="out" type="s" name="friendlyName" />
+62 -3
View File
@@ -35,6 +35,8 @@
#include <QFile>
#include <QUuid>
#include <QPainter>
#include <QList>
#include <QString>
#ifdef KMESSDEBUG_SHAREDMETHODS
#define KMESSDEBUG_SHARED_OPENEXTERNAL
@@ -179,7 +181,7 @@ QByteArray KMessShared::deriveKey ( const QByteArray &keyToDerive, const QByteAr
/**
/**
* @brief Draws an icon with an overlay from two pixmaps.
*
* This method takes the two pixmaps and draws them over each other, returning a new pixmap with 'overlay'
@@ -216,7 +218,7 @@ QPixmap KMessShared::drawIconOverlay( const QPixmap icon, const QPixmap overlay,
const int x = width - overlayWidth;
const int y = height - overlayHeight;
// thanks, Amarok, for the code and the idea :)
QPixmap result( width, height );
result.fill( Qt::transparent );
@@ -561,7 +563,7 @@ void KMessShared::openEmailClient( const QString &mailto, const QString &folder,
*
* If startingNumber is 1, there is actually no suffix; but this is never a problem if you
* correctly handle this method returning false, reading the existing file using the suffix,
* and writing a new file using startingNumber.
* and writing a new file using startingNumber.
*
* For example, calling selectNextFile( "/", "name", suffix, "ext", startingNumber ):
* - if startingNumber is zero and "/name.ext" doesn't exist, returns false,
@@ -671,3 +673,60 @@ bool KMessShared::selectNextFile( const QString &directory, const QString &baseN
// Truncate an UTF-8 multibyte string to a fixed byte size
QString KMessShared::fixStringToByteSize( const QString &string, quint32 size )
{
// Check if truncating is not needed
if( string.isEmpty() || size == 0 )
{
return string;
}
// Seek through the string one multibyte char at a time, and count their actual size in bytes
quint32 validPos = 0;
for( quint32 pos = 0; (qint32)pos < string.length(); ++pos )
{
QChar character( string.at( pos ) );
quint32 skip = 0;
quint32 more;
// Character ranges from http://en.wikipedia.org/wiki/UTF-8
if( character <= 0x007f )
{
more = 1;
}
else if( character <= 0x07FF )
{
more = 2;
}
else if( character <= 0xd7ff )
{
more = 3;
}
else if( character <= 0xDFFF )
{
// Surrogate area, consume next char as well
more = 4;
skip = 1;
}
else
{
more = 3;
}
// The next character would make the string too long: cut it here
if( validPos + more > size )
{
return QString::fromUtf8( string.toUtf8().left( validPos ) );
}
validPos += more;
pos += skip;
}
return string;
}
+3
View File
@@ -18,6 +18,7 @@
#ifndef KMESSSHARED_H
#define KMESSSHARED_H
#include <QByteArray>
#include <QObject>
#include <QPixmap>
@@ -66,6 +67,8 @@ class KMessShared
static bool selectNextFile( const QString &directory, const QString &baseName, QString &suffix, const QString &extension, int &startingNumber );
// Draws an icon with an overlay from two pixmaps (width and height -1, the defaults, mean take the width and height from the icon itself)
static QPixmap drawIconOverlay( const QPixmap icon, const QPixmap overlay, int width = -1, int height = -1, float sizeFactor = 0.5, float iconSizeFactor = 1.0 );
// Truncate an UTF-8 multibyte string to a fixed byte size
static QString fixStringToByteSize( const QString &string, quint32 size );
private:
// Create the html file to request the given service