Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3179f447ce | |||
| 9c0c6480e3 |
@@ -0,0 +1,2 @@
|
||||
build
|
||||
.DS_Store
|
||||
@@ -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
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -515,6 +515,9 @@ void InkCanvas::mouseReleaseEvent( QMouseEvent *event )
|
||||
|
||||
// clear the buffer.
|
||||
clearBuffer();
|
||||
|
||||
// update
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+669
-625
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -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.."
|
||||
|
||||
+787
-715
File diff suppressed because it is too large
Load Diff
+775
-696
File diff suppressed because it is too large
Load Diff
+1162
-1492
File diff suppressed because it is too large
Load Diff
+4
-2
@@ -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}
|
||||
)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -277,6 +277,8 @@ void ContactExtension::setAlternativeName( const QString& newAlternativeName )
|
||||
void ContactExtension::setContactAlternativePicturePath( const QString& _newVal )
|
||||
{
|
||||
alternativePictureFile_ = _newVal;
|
||||
|
||||
emit changedPicture();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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" );
|
||||
}
|
||||
|
||||
@@ -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&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
@@ -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
@@ -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
@@ -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
@@ -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", "<Enter your personal message here>" ) );
|
||||
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
@@ -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
@@ -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>
|
||||
|
||||
@@ -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
@@ -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"));
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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_;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
@@ -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 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user