Compare commits

..

2 Commits

Author SHA1 Message Date
Mario Fetka 919dbe2a0f Import release 2.0beta2 2009-05-13 18:20:42 +00:00
Mario Fetka 8c44bbd89b Import release 1.5.2 2009-03-23 23:35:55 +00:00
248 changed files with 96242 additions and 84715 deletions
+14 -9
View File
@@ -8,6 +8,8 @@
Valerio Pilo <amroth@coldshock.net>
Antonio Nastasi <sifcenter@gmail.com>
Ruben Vandamme <vandammeru@gmail.com>
Sjors Gielen <dazjorz@dazjorz.com>
Adam Goossens <fontknocker@gmail.com>
-- Translations --
@@ -19,16 +21,19 @@
Mohamed Aser <mohasr@link.net>
Youssef Chahibi <chahibi@gmail.com>
Ma'moun Diraneyya <mamoun.diraneyya@gmail.com>
Brazilian Portuguese:
Mauricio Rother <mauricio@digicomm.com.br>
Leonel Freire <leonelfreire@gmail.com>
Sergio Rafael Lemke <bedi.com@gmail.com>
Maurício Arozi Moraes
Catalan:
Jaume Cornadó <jaumec@lleida.net>
Adrià Arrufat <swiftscythe@gmail.com>
Chinese (Simplified):
@@ -53,6 +58,7 @@
Jaap Woldringh <jjh.woldringh@planet.nl>
Elve <elve@savage-elve.net>
Sander Pientka <cumulus0007@gmail.com>
Heimen Stoffels <djmusic121@gmail.com>
Estonian:
@@ -63,6 +69,7 @@
Markus Vuori <markus@vuoret.net>
Joonas Niilola <juippis@roskakori.org>
Jussi Timperi <jussi.timperi@gmail.com>
Antony Hussi <antony.hussi@tranciend.com>
French:
@@ -70,6 +77,7 @@
Vincent Fretin <fretinvincent@hotmail.com>
Andrea Blankenstijn <darkan9el@gmail.com>
Barthe Guillaume <gu_barthe@yahoo.fr>
Scias <shining.scias@gmail.com>
German:
@@ -91,6 +99,7 @@
David Vignoni <dvgn@libero.it>
Valerio Pilo <amroth@coldshock.net>
Vincenzo Reale <smart2128@baslug.org>
Andrea Decorte <adecorte@gmail.com>
Korean:
@@ -121,6 +130,7 @@
Christian Kaiser <k39@users.sourceforge.net>
Juan Pablo González Tognarelli <jotapesan@gmail.com>
Alexis Daniel Medina Medina <alexismedina@gmail.com>
Manuel Ramírez <elpreto@kde.org.ar>
Swedish:
@@ -189,14 +199,6 @@
Matteo Nardi <91.matteo@gmail.com>
- KWallet support
Adam Goossens <fontknocker@gmail.com>
- Notifications blocking option
- Winks disabling option
- Last message date feature
Sjors Gielen <dazjorz@dazjorz.com>
- IRC-like commands in the chat window
Andrea Decorte <adecorte@gmail.com>
- Group selection in 'contact added user' dialog
@@ -218,4 +220,7 @@
- Close-to-tray icon screenshot code
Amarok
- Custom crash handler implementation
- Custom crash handler implementation
Quassel
- KNotify not giving focus bug fix and KWin focus stealing prevention workaround
+93 -19
View File
@@ -19,7 +19,9 @@ 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', and on openSUSE: 'libxml2' and 'libxml2-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://www.kmess.org/board/viewtopic.php?t=3100" )
# Check for libxslt
@@ -27,7 +29,9 @@ 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', and on openSUSE: 'libxslt' and 'libxslt-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://www.kmess.org/board/viewtopic.php?t=3100" )
# Check for qca2
@@ -35,7 +39,10 @@ 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' and 'libqca2-dev', and on openSUSE: 'libqca2' and 'libqca2-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://www.kmess.org/board/viewtopic.php?t=3100" )
# As far as I know, it is impossible to find out if the required QCA plugin for OpenSSL is installed:
@@ -44,15 +51,15 @@ 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 )
SET( QCA2_OSSL_PLUGIN_FOUND TRUE )
ELSE( HAS_QCA2_OSSL_PLUGIN EQUAL 1 )
SET( QCA2_OSSL_PLUGIN_FOUND FALSE )
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'.
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://www.kmess.org/board/viewtopic.php?t=3100" )
ELSE( UNIX )
# TODO: Find another *portable* way to detect the OSSL plugin.
@@ -61,16 +68,21 @@ IF( QCA2_FOUND )
ENDIF( QCA2_FOUND )
# Check for XScreenSaver extension
MACRO_BOOL_TO_01( X11_Xscreensaver_FOUND HAVE_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' and on openSUSE, 'xorg-x11-libs'.
OPTION( WANT_XSCREENSAVER "Build with X11 screensaver auto-away support" ON )
IF( WANT_XSCREENSAVER )
MACRO_BOOL_TO_01( X11_Xscreensaver_FOUND HAVE_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://www.kmess.org/board/viewtopic.php?t=3100" )
ELSE( X11_FOUND )
MESSAGE( STATUS "NOTE: The auto-away feature is not supported on this platform yet." )
ENDIF( X11_FOUND )
ELSE( X11_FOUND )
MESSAGE( STATUS "NOTE: The auto-away feature is not supported on this platform yet." )
ENDIF( X11_FOUND )
ENDIF( WANT_XSCREENSAVER )
# Check for libkonq
# QUIET is to fix compiling on systems like Debian Lenny, which don't have FindLibKonq.cmake
@@ -79,7 +91,21 @@ 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', and on openSUSE: 'libkonq5' and 'libkonq-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://www.kmess.org/board/viewtopic.php?t=3100" )
# Check for libgif
INCLUDE( "cmake/giflib_hack.cmake" )
MACRO_OPTIONAL_FIND_PACKAGE( GIF )
MACRO_BOOL_TO_01( GIF_FOUND HAVE_LIBGIF )
MACRO_LOG_FEATURE( GIF_FOUND "GIF" "Handwriting messages support" "http://sourceforge.net/projects/giflib/" FALSE ""
" Optional support to send handwriting messages compatible with Windows Live Messenger.
* You will need to install both the library and development packages of the GIF Library, giflib.
* Usually the package names for this library are:
on Ubuntu: 'libgif4' and 'libgif-dev'
on openSUSE: 'giflib' and 'giflib-devel'
* Please refer to the KMess board for more info, and specially to this guide: http://www.kmess.org/board/viewtopic.php?t=3100" )
@@ -101,8 +127,8 @@ INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${LIBXM
#### Define the app version number ####
# 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.0beta1" )
#EXECUTE_PROCESS( COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cmake/get-svn-version.sh OUTPUT_VARIABLE KMESS_VERSION )
SET( KMESS_VERSION "2.0beta2" )
#### Define compiler flags ####
@@ -112,7 +138,12 @@ SET( KMESS_VERSION "2.0beta1" )
IF( CMAKE_COMPILER_IS_GNUCXX )
# skipped: -ansi -pendantic -Wfatal-errors -Wold-style-cast -Wconversion
SET( CMAKE_CXX_FLAGS_DEBUG "-O0 -g -Wall" )
SET( CMAKE_CXX_FLAGS_DEBUGFULL "-O0 -g3 -fno-inline -Wall -Woverloaded-virtual -Wsign-compare -Wundef -fvisibility=default" )
SET( CMAKE_CXX_FLAGS_DEBUGFULL "-O0 -g3 -fno-inline -Wall -Woverloaded-virtual -Wsign-compare -Wundef" )
# the -fvisibility option makes symbols also visible to the KDE backtrace dumper, but
# the MinGW gcc doesn't seem to understand it well, so only add it if we're not on win32
IF( NOT WIN32 )
SET( CMAKE_CXX_FLAGS_DEBUGFULL "${CMAKE_CXX_FLAGS_DEBUGFULL} -fvisibility=default" )
ENDIF( NOT WIN32 )
ENDIF( CMAKE_COMPILER_IS_GNUCXX )
@@ -145,6 +176,13 @@ ELSE( KMESS_ENABLE_BINRELOC EQUAL 1 )
SET( KMESS_ENABLE_BINRELOC "0" )
ENDIF( KMESS_ENABLE_BINRELOC EQUAL 1 )
# Disable LikeBack if not needed
IF( KMESS_DISABLE_LIKEBACK EQUAL 1 )
SET( KMESS_DISABLE_LIKEBACK "1" )
ELSE( KMESS_DISABLE_LIKEBACK EQUAL 1 )
SET( KMESS_DISABLE_LIKEBACK "0" )
ENDIF( KMESS_DISABLE_LIKEBACK EQUAL 1 )
# Enable the experimental webcam connection if needed
IF( NOT DEFINED KMESS_ENABLE_WEBCAM )
@@ -157,6 +195,42 @@ IF( NOT CMAKE_INSTALL_PREFIX )
SET( CMAKE_INSTALL_PREFIX "/usr" )
ENDIF( NOT CMAKE_INSTALL_PREFIX )
IF( CMAKE_USE_CPACK EQUAL 1 )
MESSAGE( STATUS "Enabling the CPack package target..." )
# source: http://www.vtk.org/Wiki/CMake:Packaging_With_CPack
INCLUDE( InstallRequiredSystemLibraries )
# the installer will be named ${PACKAGENAME}-{VERSIONMAJOR}.{VERSIONMINOR}.{VERSIONPATCH}-win32.exe.
# the installer will say "Welcome to the ${INSTALL_DIRECTORY} Setup Wizard and install to ${INSTALL_DIRECTORY} too, and
# put the program in start menu under the ${INSTALL_DIRECTORY} name.
# it will ask if ${PACKAGENAME} should be put in PATH.
SET( CPACK_PACKAGE_NAME "KMess" )
SET( CPACK_PACKAGE_DESCRIPTION_SUMMARY "KMess (package description)" )
SET( CPACK_PACKAGE_VENDOR "The KMess team" )
SET( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README" )
SET( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING" )
SET( CPACK_PACKAGE_VERSION_MAJOR "1" )
SET( CPACK_PACKAGE_VERSION_MINOR "0" )
SET( CPACK_PACKAGE_VERSION_PATCH "0" )
SET( CPACK_PACKAGE_INSTALL_DIRECTORY "KMess" )
IF( WIN32 AND NOT UNIX )
# There is a bug in NSI that does not handle full unix paths properly. Make
# sure there is at least one set of four (4) backslashes.
SET( CPACK_GENERATOR "NSIS" )
SET( CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/data/icons\\\\hi32-app-kmess.png" )
SET( CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\kmess.exe" )
SET( CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} KMess (display name)" )
SET( CPACK_NSIS_HELP_LINK "http:\\\\\\\\kmess.org" )
SET( CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\kmess.org" )
SET( CPACK_NSIS_CONTACT "project@kmess.org" )
SET( CPACK_NSIS_MODIFY_PATH ON )
ELSE( WIN32 AND NOT UNIX )
SET( CPACK_STRIP_FILES "bin/kmess" )
SET( CPACK_SOURCE_STRIP_FILES "" )
ENDIF( WIN32 AND NOT UNIX )
SET( CPACK_PACKAGE_EXECUTABLES "kmess" "KMess" )
INCLUDE( CPack )
ENDIF( CMAKE_USE_CPACK EQUAL 1 )
#### Other settings ####
+562
View File
@@ -1,4 +1,566 @@
--- 2.0beta2 released ---
2009-05-10 (dazjorz)
* Re-added check for getSessionInfo() (or participants > 1) in contactJoined.
2009-05-10 (Pano)
* Merged an updated Italian translation by Andrea Decorte.
* Merged an updated Finnish translation by Antony Hussi.
* Merged an updated Catalan translation by Adrià Arrufat.
2009-05-10 (Ruben)
* Fixed bug in Konqueror plugin. Thanks to Pano.
* Added Dutch translation for Konqueror Plugin.
2009-05-09 (Ruben)
* Fixed bug causing the "Away Message" Dialog to appear twice. Bug reported by Pano.
2009-05-09 (Pano)
* Merged an updated German translation.
2009-05-08 (Pano)
* Merged an updated Brazilian Portuguese translation by Maurício Arozi Moraes.
2009-05-08 (dazjorz)
* The "contact joined" is now always shown, even if it's the first message
etc.
* Removed all <html> tags around the strings again... (Sorry translators!)
* Added a piece of code for CPack in CMakeLists, so we can build an installer
for Windows and possibly OS X.
* Let the build process only link in libgif if it was found.
* Skip installing the message handler on Windows, because it makes debug
output disappear there.
2009-05-07 (Pano)
* Merged an updated Brazilian Portuguese translation by Maurício Arozi Moraes.
2009-05-07 (dazjorz)
* Fixed searching for a contact with a contact with MSN+ tags in his name in
the InvitedDialog, it now searches through the cleaned string instead of
through the formatted string.
* Fixed the Individuals group also displaying the number of online contacts.
* Merged a slightly altered patch by Ralesk, which now *correctly* splits the
string also for languages like Arabic.
* Made the languages list in LikeBack bold, because it tends to be ignored.
* Made the first given language in LikeBack actually the first listed language.
2009-05-06 (dazjorz)
* Split string in kmessview, needed for an Arabic translation which
apparantly needs to make the difference between a count of 1 or != 1 for the
'online' part too.
2009-05-05 (Pano)
* Merged an updated Dutch translation by Heimen Stoffels.
2009-05-04 (Pano)
* Merged an updated Dutch translation by Sander Pientka.
* Merged an updated German translation.
2009-05-03 (Pano)
* Updated the KMess handbook a little
2009-05-03 (Diederik)
* Fixed automatic reconnecting when network manager is initialized at KDE login.
2009-05-03 (dazjorz)
* Merged a patch by me and Valerio, which disables the inks and winks button
if the contact doesn't support the respective feature (also keeping in mind
the WLM inks bug).
* Fixed crash when quitting KMess after doing the testMsnPlusInteractive()
test.
2009-05-02 (Pano)
* Merged an updated Dutch translation by Sander Pientka.
2009-05-01 (dazjorz)
* Removed the last > and } from a link if there is no < or { in it.
* Fixed behaviour of the pre-wordwrapper if the string that is currently
being wrapped ends inside a HTML entity.
2009-04-28 (Pano)
* Merged an updated Brazilian Portuguese translation by Maurício Arozi Moraes.
* Merged an updated Catalan translation by Adrià Arrufat.
* Merged an updated Greek translation by Dimitrios Glentadakis.
2009-04-28 (dazjorz)
* Fixed #460 with the help of Ed Schouten: encoding issues in the chat
history dialog. They were caused by a QByteArray being converted to a
QString.
* Modified the notice when no logs could be found for a contact, and added
another notice when no logs could be found and chat logging is disabled.
2009-04-28 (Adam)
* Require the user to enter a friendly name for an account before saving or updating
* Display a console warning in MsnNotificationConnection if we try to set an empty friendly name: ignores
setting empty friendly names now. Stops the NS booting us with a 209 error.
2009-04-27 (Pano)
* Added tooltips to strings in the account settings that lacked them
2009-04-27 (Valerio)
* Fixed sorting of Away and Idle contacts in the contact list: now idle ones are always shown above
away ones.
* Added warning message in chat when an handwritten message can't be sent or received.
* Enabled by default the "Hide notifications when busy" option.
2009-04-27 (dazjorz)
* Implemented workaround for KWin bug: clicking buttons in knotify popups
wouldn't give a window focus, and kwin focus stealing prevention was blocking
focus asking; now kmess workarounds the prevention and gives itself focus.
* Implemented maximum length for the Personal Message input, based on
research on the max length WLM 8.5 and 2009 (chat window only) will display.
* Fixed documentation in account.h, account.cpp, addcontactdialog.cpp,
kmessdbusadaptor.h, filetransferp2p.cpp, application.h,
httpsoapconnection.cpp, offlineimservice.cpp, msnnotificationconnection.cpp,
msnobject.h, kmessshared.cpp and likeback.h.
2009-04-26 (Valerio)
* Fixed chat session restarting.
* Fixed LikeBack's introductory dialog box.
2009-04-25 (sifcenter)
* Fixed sending of oim when the user has a long nickname. The server accepts friendly name up to 48 chars.
2009-04-24 (Pano)
* Merged an updated Traditional Chinese translation by the Tryneeds-Chinese Translation Platform.
2009-04-22 (Valerio)
* Fixed sending long offline messages.
* Fixed ampersands displayed incorrectly in chat tab labels.
2009-04-22 (Pano)
* Merged translations to the kmesssendplugin.desktop file.
* Merged an updated Dutch translation by Heimen Stoffels.
* Synced the translators section of the manual with the AUTHORS file.
2009-04-21 (Diederik)
* Small fix of r4660 (disabling buttons). winks also require multi-packet, and wlm bug tests for 1-on-1 chat.
2009-04-21 (Valerio)
* Disable the Winks and/or Handwriting buttons if any contacts in a chat don't support it (or we can't
send those).
* Show the contact list tooltips even if the window doesn't have focus.
* Improved cleaning up of SOAP connections after a disconnection.
* Improved the timers to detect login process timeouts.
* Fixed zooming in chat. It won't properly "zoom" now, but simply scale the font.
2009-04-21 (Adam)
* LikeBack welcome message no longer displays if the LikeBack bar is disabled: the message doesn't make
sense without the bar so best not to show the message in this case.
* Fixed some compile time warnings.
2009-04-21 (Pano)
* Merged an updated French translation by Scias.
* Merged an updated German translation.
* Merged an updated Italian translation by Andrea Decorte.
2009-04-20 (Adam)
* Removed an unused variable in chat.h left over from a reverted commit
* Select the correct menu entry for contact picture display size on startup.
2009-04-19 (dazjorz)
* Added notice in likebackdialog why we want users to specify their e-mail
address.
* Made e-mail address enabled by default.
* Made LikeBack send new comments in utf-8.
* Added a warning when you try to send an ink to a WLM 8.5 client with ISF
support; this doesn't work now.
2009-04-19 (Valerio)
* Fixed the Contact List widget rendering again.
* Improved the SOAP server redirection system.
* Added workaround for Qt development versions > 4.5.0, to allow connecting again.
* Improved a bit the looks of the Contact List and Account Settings.
* Removed many languages from the LikeBack dialog.
* Made LikeBack's feedback dialog to be non-modal.
* Added default label in the Contact Added User dialog when the contact's friendly name is unknown.
* Added new wink receiving messages, shown when receiving winks which don't carry a name.
* Made non-interactive data transfers really quiet: no more errors will be shown in chat for random
picture transfers.
2009-04-18 (sifcenter)
* Polished a bit the code of chat class.
* Fixed an issue in the chatmaster code: The switchboard could be still "active" for the kmess and for the NS server,
but the remote contact could be disconnected by network problem. When the contact came back online again and continue to chat
with the user the new switchboard is not attached to the chat. The issue for the moment is managed by createChat.
Please be attention to this issue because we lost messages ( we can view the messages received only
on debug messages but not in chat ). Refer to the code to understand well what happens.
2009-04-18 (dazjorz)
* Fixed libxml parsing errors: now removing invalid characters which may not
appear in XML strings in ChatMessageStyle.
2009-04-17 (dazjorz)
* Made KMess only save passwords when a change is detected. Fixes this bug on
the forums: http://www.kmess.org/board/viewtopic.php?p=10373
* Fixed a very rare crash in DirectConnectionPool.
2009-04-17 (Valerio)
* Fixed MimeMessage bug, which caused text messages containing a string used in P2P and multipart
messages to be interpreted as binary messages.
2009-04-16 (dazjorz)
* Added gif encoding support, fixes bug #409.
* Fixed some ink cropping bugs and made inks look more smooth.
* Added libgif as a dependency to KMess.
* Added support for receiving application/x-ms-ink messages. (though kmess
will assume it's gif)
* Fixed sending ink messages to Live Messenger 8.5: Now sending headers in
the "right order". (yeah, as if there's something like order in these... f*** you MS)
* Added '+' symbol as an allowed character in e-mail addresses in the
RichTextParser.
2009-04-16 (Adam)
* In an offline messaging session nudges/winks will now cause a switchboard refresh if the contact in the session
has come online.
2009-04-15 (sifcenter)
* Switched to reference variables in some code of contact* classes.
2009-04-14 (sifcenter)
* Use UnAckedMessage* instead of UnAckedMessage in QHash of SB, that stores all unacked messages, to avoid
using of MimeMessage copy costructor when unAckedMessages_.remove() is called.
2009-04-14 (Valerio)
* Fixed the scrollbar background in the contact list window.
* Fixed incorrect detection of ticket expiration time.
* Disabled "connection problem" message, it was too unreliable with some clients, most notably WLM.
2009-04-13 (Valerio)
* Fixed a tiny HTML encoding issue in the chat XML.
* Another huge set of improvements to the Chat History Dialog:
- The generation of chat logs from the XML files is now threaded.
- Generation can be interrupted to look to the chats with another contact.
- The UI doesn't block and makes it visually clear that it's loading stuff.
- It reacts better to invalid chat logs ("No chats" is shown).
- Message date and times are correctly shown according to the account settings.
- Removed the "Do not filter" checkbox as it was pretty much useless.
2009-04-13 (sifcenter)
* Fixed an issue on add emoticon dialog: the emoticon preview wasn't update correctly.
* Fixed the press of enter key on CL: the chat wasn't opened.
* Don't submit the request the changing of the name of one group if the new name is the same of the old one.
2009-04-13 (Pano)
* Merged an updated Catalan translation by Adrià Arrufat.
2009-04-13 (Adam)
* Fixed startup state of Show History Box checkbox. Now matches account settings.
* Group chats now always open in their own chat tab.
* Removed a useless method from the ContactsWidget class.
2009-04-12 (Ruben)
* Fixed crash when setting contact in ChatHistoryDialog.
* Added "Show Chat History" when rightclicking on a contact.
* Show a messagebox when trying to view the chat history of a contact without a history.
2009-04-12 (Valerio)
* Changed the Transfers Window to a window from a dialog: it now appears quietly minimized.
* Changed the Transfer Entries appearance (removed their frames, made them to look more Oxygen).
2009-04-12 (dazjorz)
* Fixed 'configure' to set debugging to be enabled when the build is
debugfull (CMake automatically does this anyway and also overrides the
--enable-debug-output option)
* Added data hash methods and variables to Emoticon, EmoticonTheme,
EmoticonManager.
* Fixed checking if we already have an emoticon: now using the data hash
instead of the shortcut.
* Fixed some warnings and failing asserts in DirectConnectionBase and P2PApplication.
* Removed unneeded hack from EmoticonTheme: html entities in emoticon
shortcuts (i.e. &amp;) ) will not collide with ;) because it's in the regexp
as &#59;).
2009-04-11 (Ruben)
* Disable reconnection timer when the user reconnects using the ChatWindow reconnect button.
2009-04-11 (Pano)
* Merged an updated Catalan translation by Adrià Arrufat.
2009-04-11 (sifcenter)
* Fixed the behavior of picture frame on initial view when the user doesn't want one picture.
* Fixed the behavior of kmess when the user remove his picture: now the right msnobject is sent.
* Fixed a regression introduced at r4564.
2009-04-11 (Valerio)
* Refined a bit the new LikeBack Feedback Bar.
* Changed the Add Emoticon Dialog height.
* Fixed resizing of the chat style preview in the Account Settings.
* Fixed spacing between emoticons in the Emoticons Panel.
* Fixed saving the detected MSN client name.
* Prevented KMess from creating new chats just to report P2P error messages.
* Fixed showing the sent wink's name when it is not known.
* Fixed connecting to a new account without saving the password.
* Reorganized the View menu entries in the Contact List window.
2009-04-10 (sifcenter)
* Added a workaroud to avoid the blinking of window on task bar also after the windows became active.
* Small improvements to code of dialogs classes.
* Added a small check to user pictures dialog to avoid corrupt view of list.
2009-04-10 (Valerio)
* Improved LikeBack:
- Now it will also be enabled in release builds, but then the feedback bar
will be disabled by default.
- Moved the "Show Feedback Icons" checkbox from the feedback dialog to the
Help menu, along with the "Send a Comment" action.
- Made it to keep the "Show Feedback Icons" setting even when the
application version changes.
* Rewritten the LikeBack Feedback Bar, it works a lot more smoothly with all
window managers.
* Fixed chat window messages for winks sending and receiving.
* When sending a wink, added showing its name and the actual wink (if enabled).
2009-04-10 (Pano)
* Merged an updated Italian translation by Andrea Decorte.
* Fixed/changed a bunch of strings
2009-04-10 (dazjorz)
* Fixed the pending emoticon regexp sometimes matching zero-width space: It's
now (correctly) rebuilt every time the pendingEmoticons_ list is changed.
* If the zero-length match bug hits (it shouldn't from now on), more
information is outputted, and the code tries to save the situation instead of
going into an endless loop.
2009-04-09 (sifcenter)
* Fixed the issue about the storing of passwords. Ticket #450.
* Improved the code on the settings classes.
* Restored the blinking of windows in task bar.
2009-04-08 (dazjorz)
* Fixed KWallet failing to save passwords on crashes etc: the wallet is now
only opened when it's needed and closed after it has done its job.
2009-04-08 (Adam)
* Added a submenu to the contact frame that can open different areas of the
contact properties dialog.
2009-04-08 (Pano)
* Merged an updated Brazilian Portuguese translation by Sergio Rafael Lemke.
2009-04-08 (dazjorz)
* Fixed warning in contactlist model
2009-04-07 (dazjorz)
* Added group list checking: makes sure there are no duplicates and gaps in
the contact list.
* Fixed code from getGroupBySortPosition, it does not need to handle gaps
anymore now the contact list is corrected.
2009-04-06 (dazjorz)
* Added a lot of hacks to fix contact list sorting issues:
* Fixed getGroupBySortPosition function to actually return the right group in
an unordered groups list
* Fixed slotGroupMoved (with some hacks...) to swap correctly with the
correct group.
* For this, added a getOldSortPosition to Group, to find out what group was
swapped with in the second run of slotGroupMoved.
2009-04-04 (dazjorz)
* Fixed memory leaks in EmoticonTheme, ChatView, KMessInterface and
MsnStatus.
* Fixed bug in NetworkWindow where a slot may be called just after cleaning
up the object, causing incorrect, non-allocated memory to be read.
* Possibly fixed endian issues in
MsnNotificationConnection::loginSucceeded(). I say "possibly", since there's
currently no way to test for me.
2009-04-04 (Adam)
* Fixed the order in which contacts are removed from a chat when a SB session closes.
* Contacts widget now behaves correctly when contacts leave a chat.
2009-04-04 (sifcenter)
* Improved the code for the emoticon theme, emoticon manager and emoticon class.
* Fixed issue when the player finds only empty strings: now kmess doesn't show the multimedia pm in this case.
2009-04-04 (Pano)
* Merged an updated Greek translation by Dimitrios Glentadakis.
2009-04-03 (dazjorz)
* Fixed "invalid read error" from Valgrind in MsnNotificationConnection
* Fixed memory leak in ChatMessageView
* Fixed memory leak in AddEmoticonDialog
* Fixed and optimized friendly name handling in MsnObject
* Fixed two invalid free's in XAutoLock
* Fixed invalid free in xsltransformation.cpp
2009-04-03 (Adam)
* Fixed changing a contacts groups via the contact properties when the properties were opened
via the chat window.
* Contacts widget now shows the correct contacts when the SB session is lost during a group chat.
* Chat window tabs and window title now show the correct participants when the SB session is lost
during a group chat.
* Chat window UI now enables properly when re-invited into a group chat after a disconnect.
* When the NS connection fails all group chats revert to 1-1 chats with the last remaining contact (like WLM).
* Fixed pending invitations: they now invite the correct contact.
2009-04-03 (Valerio)
* Rewritten the Chat History dialog. It works now, and it is a lot faster also.
* Added a workaround for the connection issues of today.
2009-04-02 (Valerio)
* Fixed time of arrival of Offline Messages, it was sometimes offset by many hours.
* Fixed showing delivery errors when sending offline messages.
* Fixed authentication tokens expiration time on login, they were sometimes expired at,
time of arrival, or about to expire.
* Fixed renewal of authorization codes after their expiration after 8 hours of connection.
* Fixed group chat reactivation after a reconnection. If you get reinvited to the same
chat, the tab will be reenabled.
2009-04-02 (dazjorz)
* Fixed richtextparser bug: When a valid pending regexp was given that
matched empty strings, the program would freeze. This is a hotfix, the
pending regexps should actually be fixed.
2009-04-01 (Adam)
* If the user adds themself to their contact list do not show that contact in the
invite contact dialog (can't invite yourself to a chat).
2009-03-31 (dazjorz)
* Re-enabled -fvisibility=default if we're not on Windows (fixes KDE
backtraces)
2009-03-31 (Adam)
* Disallow editing the current account's handle (prevents a crash)
* Fixed the buddy shortcut for the sound chooser in contact properties.
* Fixed a display issue with the group list in the contact properties dialog when that
dialog was opened through a chat.
* Added a little more debugging information to the Now Playing class, including the
player name from MPRIS.
2009-03-31 (Valerio)
* Fixed chats started by contacts sometimes stealing chat window focus as if they were
user requested.
* Changed the color of presence messages.
* Fixed bug which allowed duplicates of the same presence message.
* Fixed drag and drop bug, it was possible to drop a contact to the Individuals group.
* Disallow dragging and dropping for contacts and groups which can't be moved.
* Fixed bug where the status of contacts in chat was not updated in tab names after
reconnecting.
* Merged patch by Andrea Decorte to fix contact names in the invite dialog.
* Fixed the Dim chat style.
* Improved session messages: don't show them if they would be the first message, and
always show them if the Show Session Messages option is enabled.
2009-03-30 (dazjorz)
* Fixed compiling on Windows with MinGW.
2009-03-30 (Pano)
* Replaced some specific words in the KMess manual with aquivalent KDE entities.
* Merged an updated Brazilian Portuguese translation by Maurício Arozi Moraes.
* Merged an updated German translation.
2009-03-30 (Ruben)
* Contact notification sound chooser in ContactPropertiesDialog is now a KUrlRequester.
* Filetype of contact notification sound is now matched against Phonon backend capabilities.
2009-03-30 (sifcenter)
* Improved the code of Contact Frame.
2009-03-30 (Valerio)
* Removed the debugging network socket, and added Local Mode #ifs instead, to allow using the
new KMess Test Server.
2009-03-29 (Pano)
* Merged an updated Traditional Chinese translation by the Tryneeds-Chinese Translation Platform.
* Synchronised the "Translators" section of the user manual with the AUTHORS file.
2009-03-29 (sifcenter)
* Merged a patch from Andrea Decorte to "show copy music entry only when needed" in chat window context menu.
* Added the ability to disable all notification from one contact.
2009-03-29 (Diederik)
* Improved the user manual, made small corrections and refrazes.
2009-03-29 (Valerio)
* Fixed chat window search, broken a week ago (winks fixing).
2009-03-28 (dazjorz)
* Fixed socket read errors never appearing.
2009-03-28 (Valerio)
* Completely rewritten and updated the user manual for the 2.0 release.
* Fixed dragging and dropping contacts on special groups.
2009-03-28 (sifcenter)
* Fixed the issue about the contact context menu in chat window. We must find out a method to leave transparent the
container but that leave also the "frame sunken" on picture.
* Fixed the frame for the unknow contacts when the user is in multi-chat. Ticket #420.
* Removed the transparent from stylesheet in contact widgets because it's the responsable of some problems at
Contact properties dialog, context menu, tooltip and all QWidgets childs.
* Fixed the size of images in contact list tooltip and in chat windows' contacts panale. Ticket #430.
* Merged the patch of fontknocker for the model list and improved a bit the code.
2009-03-27 (Valerio)
* Removed an unneeded signal emission.
* Added interpretation for another OIM response fault.
* Finished drag&drop support - now works within the contact list and from it
to chat.
* Removed the "Search for contact" website links, I can't find these pages
anymore.
* Added a check to avoid showing the "close all tabs" confirmation dialog, if
the user wanted to close all tabs.
* Merged slightly changed patch by Andrea Decorte, adding the two missing actions
to the Contact Frame contextmenu: Copy Music and Properties.
2009-03-26 (Pano)
* Merged an updated Spanish translation by Manuel Ramírez.
* Merged an updated Brazilian Portuguese translation by Maurício Arozi Moraes.
2009-03-26 (dazjorz)
* Made offline contact chat windows reusable for when a contact comes online.
* Fixed wrong signal arguments in msnswitchboardconnection.
* Reverted removal of friendlyName.isEmpty() check, because the friendlyName
is an optional argument and setFriendlyName() outputs a warning if
friendlyName is empty.
* Merged patch by alexjp, fixing loading idle timer settings upon KMess
start.
* Fixed Kopete detection and fixed a typo in contactbase.h.
* Fixed incorrect signal connection in msnswitchboardconnection (signal from
offlineimservice).
* Fixed P2P transfer bug (#437) with Vale's help.
2009-03-25 (dazjorz)
* Fixed failing assert caused by SOAP message handler.
* Merged patch by Andrea Decorte, which resets the quick retype index when
switching tabs (and keeps it local in the chat window).
* Made ctrl+down also work when there was no saved message - it's more
intuitive and less bug-prone that way.
2009-03-25 (Adam)
* Fixed gradient problem with Oxygen again.
2009-03-25 (Pano)
* Merged an updated French translation by Barthe Guillaume.
* Merged an updated Traditional Chinese translation by Yen-chou Chen.
* Merged an updated German translation.
2009-03-25 (Valerio)
* Fixed playing Winks.
2009-03-24 (Adam)
* Fixed typing notifications not appearing in WLM 2009.
2009-03-24 (dazjorz)
* Fixed soft hyphen showing up as a zero-width character in copy-pastes.
* Added abort() call to the crash handler, so KMess will coredump and a
possible second crash handler will help us with bughunting.
* Merged slightly altered patch by Andrea Decorte, fixing scrolling up and
down in message history in tabbed chats.
2009-03-24 (Valerio)
* Fixed Winks button not being disabled when the network connection is lost.
* Fixed bug where chat messages sent to a contact who just went offline were being sent
again as normal messages if the contact in chat came back online.
2009-03-23 (Adam)
* Work around possible Qt bug which resets not just font colour but font face as well when
message edit box is cleared.
* Truly empty groups (with no contacts) are hidden now if "Show Empty Groups" is disabled.
* Fixed bug where offline contacts were not included in the search
* Fixed gradient problem for the list of contacts in a chat window. Now displays properly
under KDE4 with Oxygen theme.
--- 2.0beta1 released ---
2009-03-23 (dazjorz)
+1 -1
View File
@@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = KMess
PROJECT_NUMBER = 2.0-beta1
PROJECT_NUMBER = 2.0-beta2
OUTPUT_DIRECTORY = ./apidocs
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
+37 -218
View File
@@ -1,242 +1,61 @@
Installation Tip:
=================
Installation Hints:
===================
NOTE: This package is used to build KMess from source code.
If you're looking for a simple way to install KMess,
take a look at http://www.kmess.org/download/.
take a look at http://www.kmess.org/download/.
NOTE: These instructions are meant for UNIX-like systems. If they don't
work for you, please tell us at http://www.kmess.org/board/.
For building on Windows, see this Wiki page:
http://trac.kmess.org/wiki/Compiling%20KMess%20for%20Windows
To install KMess from this source package you need to create a separate
build directory first. It must be created outside the source folder.
build directory first. It must be created outside the source folder. After
that, you must configure your build using cmake.
mkdir kmess2-build
Then configure your build using cmake,
and point to the source folder:
cd kmess2-build
cmake ../kmess2
If the cmake scripts did not display any errors, you can run:
To ease the building process, KMess comes with a 'configure' script that
creates the directory and runs CMake for you. To build this package, simply
run:
cd kmess
./configure
make
and then, as root, type
To install on most systems, you can run:
make install
sudo make install
If your system doesn't come with sudo, you can use:
su -c 'make install'
That's it!
Of course, building without the configure script is also possible:
mkdir build
cd build
cmake ..
make
sudo make install
Useful parameters:
==================
Useful cmake parameters:
========================
The configure script automatically makes the right build for you. For a release (non-alpha or beta)
package, the configure script builds KMess in release mode; for an alpha or beta package, KMess will
run in debug mode. When something goes wrong, debug mode will help us find the cause, and fix it. :-)
Try the following switches the change the build.
If you want to modify your build, you can try the following options to the configure script:
-D CMAKE_INSTALL_PREFIX=/usr
--prefix=/usr
Install in the /usr directory instead.
-D CMAKE_BUILD_TYPE=[none,debug,debugfull,release,relwithdebuginfo,minsizerel]
--build-type=(one of debug,debugfull,release,relwithdebuginfo,minsizerel)
Set the preferred build type, which sets recommended compiler flags automatically.
Tell CMake to build this specific build type.
Also consider running "ccmake" for an curses-interface to cmake.
That only works after the build directory is configured with cmake before.
* * * * * * The parts below do not apply to KMess 2 yet! * * * * * *
Important:
==========
The configure script tries to detect your KDE3 directory automatically.
If configure fails to detect KDE, you should tell KMess which directory
to use. Basically, we're talking about the parent directory
of /share/apps/k~bunch of kapps~
Not doing this will result in emoticons being displayed
as text, and icons being displayed incorrectly as well.
If configure tells you you're missing something that you think you
have installed on your system, you probably need to install the
"devel" version of that thing. i.e. If it tells you you're missing
libfam, install the libfam-devel rpm.
More information can be found in the README file.
The following paragraphs below provide generic installation instructions:
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes a while. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Type `make install' to install the programs and any data files and
documentation.
4. You can remove the program binaries and object files from the
source code directory by typing `make clean'.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.
ccmake only works after the build directory has been configured with cmake before.
+42 -3
View File
@@ -1,7 +1,45 @@
Changes between KMess SVN and 2.0-beta1:
Changes between KMess 2.0-beta2 and 2.0-beta1:
--------------------------------------
- None yet.
- completed drag&drop support.
- fixed quick retype.
- fixed winks playing and naming support.
- fixed disconnections after many hours of use.
- fixed losing KDE Wallet passwords.
- fixed typing notifications not appearing in WLM 2009.
- fixed long words breaking was breaking copy-pastes.
- fixed weird characters which were breaking the chat styles.
- fixed resending messages already sent as offline messages.
- fixed searching for offline contacts.
- fixed time of arrival of offline messages.
- fixed new chat windows or tabs opened by contacts sometimes stole focus.
- fixed contact list group sorting.
- fixed many memory leaks.
- fixed overflowing contact list background picture and color.
- improved the Chat History dialog and its integration with KMess.
- improved drag and drop support in contact list.
- improved the color of the less important contact status messages in chat.
- improved client detection support.
- improved handwriting message sending.
- improved the file transfers window's behavior.
- improved chat session management.
- improved the LikeBack buttons bar.
- updated English handbook.
- updated Arabic translation by Ma'moun Diraneyya.
- updated Brazilian Portuguese translation by Sergio Rafael Lemke.
- updated Brazilian Portuguese translation by Maurício Arozi Moraes.
- updated Catalan translation by Adrià Arrufat.
- updated Dutch translation by Heimen Stoffels.
- updated Dutch translation by Sander Pientka.
- updated Finnish translation by Antony Hussi.
- updated French translation by Barthe Guillaume.
- updated French translation by Scias.
- updated German translation by Panagiotis Papadopoulos.
- updated Greek translation by Dimitrios Glentadakis.
- updated Italian translation by Andrea Decorte.
- updated Spanish translation by Manuel Ramírez.
- updated Traditional Chinese translation by Yen-chou Chen.
- updated Traditional Chinese translation by the Tryneeds-Chinese Translation Platform.
Changes between KMess 2.0-beta1 and 2.0-alpha2:
--------------------------------------
@@ -93,7 +131,8 @@ Changes between KMess 2.0-beta1 and 2.0-alpha2:
- removed custom notification settings in favour of KNotify settings in the global settings panel.
- updated English handbook by Heimen Stoffels.
- updated Brazilian Portuguese translation by Leonel Freire.
- updated Dutch translation by Elvse and Sander Pientka.
- updated Brazilian Portuguese translation by Sergio Rafael Lemke.
- updated Dutch translation by Elve and Sander Pientka.
- updated French translation by Barthe Guillaume.
- updated German translation by Panagiotis Papadopoulos.
- updated Greek translation by Panagiotis Papadopoulos, Dimitrios Glentadakis.
+8 -239
View File
@@ -14,240 +14,11 @@ The licensing terms are the GNU General Public License.
Installation Tip:
Installing KMess:
=================
NOTE: This package is used to build KMess from source code.
If you're looking for a simple way to install KMess,
take a look at http://www.kmess.org/download/.
First configure your build using the configure script:
./configure
If everything went well, you can run:
make
and then, as root, type
make install
That's it!
Compiling with cmake:
=====================
* * this is for experienced users only * *
KMess 2 is KDE 4 software, which uses 'cmake' to build the software.
To make it a bit more familiar for you, we have created a 'configure'
script which does all the cmake magic behind the scenes.
It's also possible to use 'cmake' directly.
The build commands become a little bit different.
First, you need to create a separate build directory:
mkdir build
Then configure your build using cmake,
and point to the source folder:
cd build
cmake ../
You can provide extra parameters with the '-D' option, see below.
If the cmake scripts did not display any errors, you can run:
make
and then, as root, type
make install
Useful cmake parameters:
========================
Try the following switches to change the build.
-D CMAKE_INSTALL_PREFIX=/usr
Install in the /usr directory instead (default is /usr/local).
-D CMAKE_BUILD_TYPE=[none,debug,debugfull,release,relwithdebuginfo,minsizerel]
Set the preferred build type, which sets recommended compiler flags automatically.
-D KMESS_DEBUG_OUTPUT=[1,0]
Activates/deactivates KMess debugging output to console, even on release builds.
This flag is automatically enabled when the build type is "debugfull".
-D KMESS_ENABLE_BINRELOC=[1,0]
Enable support for binary relocatable binaries. This allows the binary
to find it's resource files whatever directory it is installed in.
-G "MinGW Makefiles"
This option is required to build KMess on Windows (still experimental).
See http://trac.kmess.org/wiki/Compiling%20KMess%20for%20Windows for details.
If you find this too difficult, consider using our "./configure" script
instead. This is a wrapper these 'cmake' arguments to make it easier,
and more familiar, to compile software.
Also consider running "ccmake" for an curses-interface to cmake.
That only works after the build directory is configured with cmake before.
* * * * * * The parts below do not apply to KMess 2 yet! * * * * * *
Important:
==========
The configure script tries to detect your KDE3 directory automatically.
If configure fails to detect KDE, you should tell KMess which directory
to use. Basically, we're talking about the parent directory
of /share/apps/k~bunch of kapps~
Not doing this will result in emoticons being displayed
as text, and icons being displayed incorrectly as well.
Troubleshooting
===============
The following packages are required to install KMess:
- make
- gcc
- gcc-c++ (if available)
- qt
- kdelibs
If your distribution uses separate "devel" or "dev" packages,
make sure you have these packages installed also:
- qt-devel (or qt3-devel)
- kdelibs-devel (or kdelibs3-devel)
- x-devel (or xfree-devel/xorg-x11-devel)
- libstdc++-devel
Likely the dependencies of these "devel" packages will
be installed automatically. Some worth mentioning are:
- fontconfig-devel
- freetype2-devel
- libfam-devel (or fam-devel)
- libjpeg-devel
- libpng-devel
- zlib-devel
- libart_lgpl-devel
If configure tells you you're missing something that you think you
have installed on your system, you probably need to install the
"devel" package of that thing.
i.e. If it tells you you're missing libfam, install the libfam-devel rpm.
If you get this error:
''configure: error: no acceptable C compiler found in $PATH''
you need to install the packages "gcc" and "make".
If you get this error:
''Your Installation isn't able to compile simple C++ programs.''
you need to install "libstdc++-devel" and some distributions
also require a "gcc-c++" package for C++ support.
If you get this error:
''error: Can't find X includes. Please check your installation [...]''
you need to install the x developer packages. Depending on your distribution,
this can be something like "x-devel", "xfree-devel", "xorg-devel".
If you get this eror:
''checking for libz... configure: error: not found.''
you need to install the "zlib-devel" package.
If you get this error:
''configure: WARNING: libjpeg not found. disable JPEG support.''
you need to install the "libjpeg-devel" package.
If you get this error:
''checking for Qt... configure: error:
Qt (>= Qt 3.1 (20021021)) (headers and libraries) not found.
Please check your installation!''
you need to install the "qt-devel" (or "qt3-devel") package.
If you get this error:
''checking for KDE... configure: error:
in the prefix, you've chosen, are no KDE headers installed. This will fail.
So, check this please and use another prefix!''
you need to make sure "kdelibs-devel" (or "kdelibs3-devel") is installed!
Installing from SVN:
====================
If there is any need to install the SVN version, read on.
The KMess SVN repository contains the latest changes made to KMess.
Each new feature or bugfix will be stored into SVN by developers.
The code in SVN will eventually become the new KMess release.
NOTE: The SVN version is the equivalent
of an "alpha" or "beta" release; there also is
a little possibility that it won't even compile!
To install KMess from SVN you need to have the packages "autoconf"
and "automake" installed.
To download the SVN version, run these commands:
svn checkout http://kmess.svn.sourceforge.net/svnroot/kmess/trunk/kmess/
If the download succeeds, run this command:
make -f Makefile.dist
This will generate the ./configure script and Makefile templates.
Then you can proceed with the normal installation.
Each time the SVN version is updated, you can run
svn update
make -f Makefile.dist
./configure
make
make install
and you'll have the latest KMess version installed.
For more information about accessing the KMess SVN repository,
visit the KMess site at http://kmess.org/svn/ .
Please see the INSTALL file for help with compiling and installing
KMess from source.
@@ -264,16 +35,14 @@ This is what you need to do:
- Open the language "po" file, and start translating!
Also watch for translations marked as "fuzzy",
they often need updating.
- The the following commands in the "po" folder:
make
make install
(if this doesn't work, run configure first)
- Update the translations.
- Test the new translation.
(to test other languages, run 'KDE_LANG=<code> kmess')
- Contact the KMess developers.
- Contact the KMess developers to send your changes!
A more detailed tutorial can be found online
at http://www.kmess.org/translating/
at http://trac.kmess.org/wiki/Translating%20KMess
Building RPM Packages
@@ -288,7 +57,7 @@ To build a RPM package for your distribution, run:
Building Slackware Packages
===========================
To build a TGZ package for Slackware, also run:
To build a TGZ package for Slackware, run:
rpmbuild -tb kmess-2.0.tar.gz
+5 -203
View File
@@ -1,207 +1,9 @@
Please note that this file has been replaced by an online project management tool,
and all information here can be completely outdated.
Our new project management site can be found at: http://trac.kmess.org/
For bugs, future ideas, et cetera, please check our developer site
powered by trac at http://trac.kmess.org/.
If you're looking for junior jobs, you may also contact us
at the KMess help forums: http://kmess.org/board/
If you're looking for junior jobs, you may also contact us at the
KMess help forums: http://kmess.org/board/
Thanks
- The KMess team
To do:
======
Unfinished new features:
___ Invite contacts for a new chat session when the current chat is used for file transfers.
___ Invite contacts for a new chat session when the current chat has multiple participants (display dialog to choose the contact).
___ Lookup all "TODO" items in the code.
Unfinished protocol features:
___ Integrate UPnP support with file transfer invitation code.
___ Make sure KMess can send two files at once with the classic file transfer method (test this).
___ Support a SLP Decline/error message for a sent P2P/SLP transfer invitation, and continue to transfer over the switchboard.
___ Support a second invitation for file transfers, detect when remote client only returns it's internal IP or does not listen.
___ Detect network settings, make the other client server for file transfer (sending a second transfer-invite).
___ Update the classic FileTransfer application to use the new async-cnnect, DirectConnectionPool and showTransfer*() API.
Critical bugs:
___ Restore the documentation
___ Restore the translations
Junior jobs:
___ Improve wink playing, include preview, offer "play" button (also see other showWink() issues). Also fixes issues when chat is started with a wink.
___ Implement phone settings (PRP and BPR fields).
___ Implement privacy settings (GTC and BLP fields, messages like "can't chat with invited contact" because not in the AL).
... And if you're up for a challenge, you could try one of the "Low priority protocol features" below too.
... Or try to implement a new MSN feature (see "Future ideas" section).
Annoying bugs:
___ Fix repeated picture transfer invitations when contact declines or aborts the invitation (preferably disable only for a few minutes).
___ Automatically clean up the displaypics folder, and msnpicture-alias-##.png images that are older then 1 month.
___ Add detection for NAK responses to file transfer invitations
___ Improve performance of restyling the chat window: combine xml to one string.
Low-priority features:
___ Improve wink processing messages of `cabextract` output in ChatWindow::showWink().
___ When chat window closes, inform user the file transfers will also abort.
___ See what happens when there is a picture transfer in a multi-chat, and one of the chats becomes busy.
___ When opening chat windows, shift their position to make them cascade.
Low-priority code changes:
___ Add Application::get..TransferAbortMessage().
___ Only allow plugins/non-local files temporary when displaying winks?
___ Implement Application::attachToChat(..) feature to improve aborting?
___ Create a WinkArchive class for the code in ChatWindow::showWink().
___ Include contact meta-data in receivedMessage() call of ChatWindow::showWink().
Low-priority protocol features:
___ Support adding contacts to multiple groups.
___ Detect multiple external IP addresses to advertise in file transfer invite message.
___ Support sending the data-preparation ACK later with Windows Live Messenger picture transfers.
___ Support direct connection setups when requesting contact pictures.
___ Support aborting the data-preparation, also detect when contact does this.
___ Support the datacast emulation over MSNP2P for MSNC1-compatible clients (for winks).
___ Test whether applications need to be aborted when the switchboard reconnects.
___ Check P2P incomingMessages_ / outgoingMessages_ cache for timeouts.
___ Leave a P2PApplication half-open to receive a final error message.
___ Use "URL PERSON/PROFILE" settings.
Wishes by users for 1.5:
___ XMMS2 now listening: http://www.kmess.org/board/viewtopic.php?t=1569 (use relaytool from autopackage.org for that).
Implemented for 1.5:
_Y_ Implement text/x-clientcaps message and MsnObject name to advertise KMess to other third-party messengers.
_Y_ Add a checkbox to the settingspanel to disable the shaking window effect.
_Y_ Support emoticons folder with KDE 3.3
_Y_ Support "now playing" by other contacts, use dcop for our status.
_Y_ Handle closed direct connection, KMess keeps using the direct connection.
_Y_ Implement i18n() for chat styles, e.g. use libxml to replace all text nodes, create an XSLT to extract all text nodes.
_Y_ Fix the memory-leak of sentMessages_ for chat messages, these are only cleared at a NAK currently.
_Y_ Send previews of images in msn file transfers.
_Y_ Fix detection of context field splitter in FileTransferP2P::contactStarted1..(), also needed to show image previews.
_Y_ Contact sidebar width is not saved/restord anymore.
_Y_ Contact sidebar width is changed when the chat window resizes.
_Y_ Check if our eventsrc file is found in the KDE-dirs, otherwise warn KMess can't notify or flash the taskbar or play sounds (see: http://www.kmess.org/board/viewtopic.php?t=1619)
_N_ (caused by Beryl bug) "Focus stealing prevention", open the new chat windows in the background by default.
_Y_ Add save log button to network window.
_Y_ Improve removing contacts, offer dialog to block the contact as well (currently always kept in allowed list).
_Y_ Display a message box if the chat logs can't be saved because the folder no longer exists.
_Y_ Automatically save settings when pressing OK, not when closing KMess.
_Y_ Fix settings for balloon notifications, see http://www.kmess.org/board/viewtopic.php?t=559
_Y_ Now listening icon is SUSE specific
_Y_ Fix MsnConnection::addPercents(), replace with KURL::encode_string(), but test for compatibility.
_Y_ Replace warning message "you can't change your friendly name" with something less unobtrusive.
_Y_ Emoticons are no longer displayed in the chat settings tab.
_Y_ Improve settingsdialog height, for 800x600 displays.
_Y_ Hide the register link when editing an account.
_Y_ Remove the dependency on QWidget for data-classes.
_Y_ Add a balloon if the contact start the chat with an filetransfer/nudge/wink.
_Y_ Implement KDE passive popups so the balloon code can be removed later.
_Y_ Balloon size fix (2 contacts on balloon), might become obsolute when passive popups are used instead.
_Y_ Get rid of the balloons
_Y_ Drag and drop of files in the chat window.
_Y_ Fix newline shortkey Ctrl+Enter / Shift+Enter in GNOME. In fact it didn't work at all, not only in GNOME. :P
_Y_ Delete contact settings when contact no longer exists in the contact list.
_Y_ Implement cleaning up of the kmessrc file, remove old Contact entries that are no longer used.
_Y_ Make moving of contacts smoother, see MsnNotificationConnection::getAdc().
_Y_ Fix error messages with 'actions -> new contact' on a 'non-existing contact', 'existing contact' and 'contact without @'.
_N_ Move network/extra/httpsoapconnection to the network root folder.
_Y_ Move chat/invitedcontact.h to the contact folder.
_Y_ Implement text/x-keepalive message so be sure when a contact really left a chat.
_Y_ Update binreloc support to version 2.0.
_Y_ Crash with downloading offline-im messages: http://www.kmess.org/board/viewtopic.php?t=1490
_Y_ Login blocks all gui-events: make all connection attempts async
_Y_ Allow users to scale fonts in the chat window (zoom icons).
_Y_ Fix problems with clicking on contacts rapidly, see http://www.kmess.org/board/viewtopic.php?t=533
_Y_ Decouple the MsnSwitchboardConnection from the ChatWindow class, for picture transfers in the background.
_Y_ Highlight the text of the contact list item when it's active.
_Y_ Fix contact list background picture scrolling
_Y_ Implement setEnabled() checks for the contact group context menu in KMessView::slotContextMenu().
_Y_ Optionally download contact pictures when the picture changed but they're not in a chat yet.
_Y_ Test whether a display picture is fully received, and remove the image from the cache otherwise.
_Y_ Limit the maximum number of MSN Object simultaneous downloads, to avoid server flooding. See ChatMaster::slotContactChangedMsnObject().
_Y_ Fix e-mail support for non-Hotmail accounts, don't attempt to use Hotmail. Use chosen app or default KDE mail app instead).
_Y_ Update the accounts listed in the initial list When one of the registered accounts is deleted.
_Y_ Improve the contact list contact menu
_N_ Check if the mutex lock in MsnConnection is really needed anymore.
_Y_ Restore the context menu in the chat window.
_Y_ Disallow logging in without having entered a password.
_Y_ When the switchboard is disconnected (gray contact pictures), the command to invite new contacts will get ignored when a new switchboard gets ready.
_Y_ In the emoticon settings panel, don't assume "smile.png" will always be available (parse theme, preferably with an EmoticonTheme class).
_Y_ Include a tooltip in the contact sidebar.
_Y_ Include a contact menu in the contact sidebar (see https://www.lab.fi.uva.es/~albgonz/kmesss.jpg)
_Y_ When the contact disables it's picture, should we leave the current one active, or revert the the "unknown" picture?
_Y__ Group chats: remove contact frame when a user leaves the chat.
_Y_ Support removing a contact from just one group.
_Y_ Group chats: fix status bar when multiple users are typing a message.
_Y_ Implement UPnP support
_Y_ Add winks support
_Y_ Add emoticon transfer support
_N_ "Who has me in his/hers contact list?" dialog (allowed/removed groups already reveal this)
_N_ Include the network-window as "--with-network-window" if the network-window-code displays traffic nicer.
Implemented for 2.0:
_Y_ Account menu's: only show submenu when there are multiple accounts.
_Y_ Add the ability to select another browser for opened links, instead of the kde's default browser.
_Y_ Change mouse cursor when hovering over the "personal status message" widget, make non-active background color less dark.
_Y_ Compact sidebar list as described in http://www.kmess.org/board/viewtopic.php?t=460
(make it optional, let the user choose between "no", "compact", "full")
_Y_ Contact list items flicker, specially when there are a lot of contacts.
_Y_ Disable cut/copy for the password line (InitialViewInterface, not using KPasswordEdit because it disables too much).
_Y_ Group chats: use more compact contact frame.
_Y_ Group off-line contacts in one single group.
_Y_ Improve the parsing of *bold* /italics/ and _underline_, so http:/website/ does not become italic and avoid mangling
<a href="http://website/"> to <a href="http:/<i>/website/</i>">.
(looks more clean, though it's a bit kmerlin like though, and the current pictures list is not that bad for multi-chat) - Being worked on
_Y_ Maybe: improve chat window layout like http://kde-apps.org/content/show.php?content=24461
_Y_ Move utility classes to a separate folder.
_Y_ Order of the title in the main window, account before or after. Should distinguish from the chat windows though.
_Y_ Put TcpConnectionBase under MsnConnection.
_Y_ Remove all #includes for <kdebug.h> and replace it with "kmessdebug.h" (watch for inclusions from subdirs)
_Y_ See what happens when there is a picture transfer in a multi-chat, and one of the chats becomes buzy.
_Y_ Tabbed chats.
_Y_ Use if(KMESS_NULL(..)) checks instead of current if(.. != 0) { .. }
_Y_ Use kdWarning() instead of kdDebug() << "WARNING", for warning messages.
_Y_ Add HTTP connection method.
_Y_ Add Ink support?
_Y_ Upgrade to MSNP14, but not until the protocol is fully understood! (it has some radical changes).
_Y_ Update contact properties edit dialog, icon button for contact icon.
_Y_ Browse/view the contact picture cache (include meta data, like contact handle and date/time)
_Y_ GetHotNewStuff (as of KDE 3.4, either support it through a KPart, or wait for KDE 4 conversion)
_Y_ KWallet integration
Future ideas:
=============
MSN Protocol support:
___ Improve old file transfer code, multiple connections like MSN5 does.
___ Implement a settings category ("File transfers") where the user can at least choose:
- "[x] Allow KMess to control my internet router programmatically [learn more]"
- "Use the following port to receive UPnP broadcast responses: [default 1900]"
___ Implement STUN support, also for Connection-Type field, see http://en.wikipedia.org/wiki/STUN and http://en.wikipedia.org/wiki/UDP_hole_punching.
___ Add voice (SIP) support
___ Add Voice clips support, see http://www.hypothetic.org/docs/msn/phorum/read.php?f=1&i=11505&t=11437
___ Add webcam (RTP) support, see http://www.hypothetic.org/docs/msn/phorum/read.php?f=1&i=9837&t=9837
___ Fix msn remote desktop invitation support (context field with user/pass)
___ Implement MSN Spaces integration
___ Implement MSN Games support (ActicitiesCollection : public QPtrList<Activity>)
___ Implement shared folders.
Invitation support:
___ Check whether gnomemeeting, krdc exists before starting/acceping a session
___ Support Konference for netmeeting invitations as well.
___ Detect whether gnomemeeting or konference exists before starting a netmeeting session.
Interface features:
___ Show an icon overlay for contact connected with webmessenger.msn.com / MSN Mobile
___ Add contact icon (purple?) for unknown contacts added by others in a multi-chat session.
KDE Integration:
___ KDE-IM bridge (http://developer.kde.org/documentation/library/cvs-api/interfaces/html/classKIMIface.html)
- The KMess team
+1 -1
View File
@@ -4,7 +4,7 @@
RootName: @kmess.sourceforge.net/kmess:$SOFTWAREVERSION
DisplayName: KMess
ShortName: kmess
SoftwareVersion: 2.0beta1
SoftwareVersion: 2.0beta2
Maintainer: The KMess Developers
Packager: Diederik van der Boor
Summary: MSN Messenger client for KDE
+6
View File
@@ -20,8 +20,14 @@
/* Define if you have the XScreenSaver extension */
#cmakedefine HAVE_XSCREENSAVER ${HAVE_XSCREENSAVER}
/* Define if LikeBack is not needed */
#define KMESS_DISABLE_LIKEBACK ${KMESS_DISABLE_LIKEBACK}
/* Define if you have KPhone installed (for SIP voice chat) (currently unused) */
/* #define HAS_KPHONE 1 */
/* Define whether to enable MSN webcam support (HIGHLY EXPERIMENTAL) */
#define ENABLE_WEBCAM ${KMESS_ENABLE_WEBCAM}
/* Define whether to enable Ink support (using GIFLib) */
#define KMESS_ENABLE_INK ${HAVE_LIBGIF}
+1 -1
View File
@@ -32,4 +32,4 @@ if [ "$svnver" = "exported" ]; then
fi
# display subversion version and date
echo -n "$appver-svn (`svnversion` >= $date)"
/bin/echo -n "$appver-svn (`svnversion` >= $date)"
+24
View File
@@ -0,0 +1,24 @@
# This file is included here because the standard FindGIF.cmake file
# requires the CHECK_STRUCT_MEMBER macro. It wasn't on my PC, at least, so
# I include a copy of the macro here for giflib to use.
MACRO (CHECK_STRUCT_MEMBER _STRUCT _MEMBER _HEADER _RESULT)
SET(_INCLUDE_FILES)
FOREACH (it ${_HEADER})
SET(_INCLUDE_FILES "${_INCLUDE_FILES}#include <${it}>\n")
ENDFOREACH (it)
SET(_CHECK_STRUCT_MEMBER_SOURCE_CODE "
${_INCLUDE_FILES}
int main()
{
${_STRUCT}* tmp;
tmp->${_MEMBER};
return 0;
}
")
CHECK_CXX_SOURCE_COMPILES("${_CHECK_STRUCT_MEMBER_SOURCE_CODE}" ${_RESULT})
ENDMACRO (CHECK_STRUCT_MEMBER)
Vendored
+2 -1
View File
@@ -119,7 +119,8 @@ function run_cmake
# Check build type
case "$BUILD_TYPE" in
release|relwithdebinfo|minsizerel|debug|debugfull) ;;
debugfull) DEBUG=1 ;;
release|relwithdebinfo|minsizerel|debug) ;;
*)
echo "$0: invalid build type: $BUILD_TYPE" >&2
exit 1
@@ -87,6 +87,16 @@
</div>
</xsl:when>
<!-- presence message (e.g. contact gone offline) -->
<xsl:when test="@type='presence'">
<div dir="{body/@dir}">
<font color="gray">
<xsl:value-of disable-output-escaping="yes" select="body"/>
</font>
</div>
</xsl:when>
<!-- notification message (e.g. file received) -->
<xsl:when test="@type='notification'">
<div dir="{body/@dir}">
+10
View File
@@ -86,6 +86,16 @@
</xsl:when>
<!-- presence message (e.g. contact gone offline) -->
<xsl:when test="@type='presence'">
<div style="margin-bottom: 16px" dir="{body/@dir}">
<font color="gray">
<xsl:value-of disable-output-escaping="yes" select="body"/>
</font>
</div>
</xsl:when>
<!-- notification message (e.g. file received) -->
<xsl:when test="@type='notification'">
<div style="margin-bottom: 16px" dir="{body/@dir}">
@@ -141,6 +141,7 @@ dd
*/
div.application,
div.notification,
div.presence,
div.system
{
margin: 10px 0 10px; /* top and bottom margin */
@@ -151,6 +152,11 @@ div.application
color: blue;
}
div.presence
{
color: gray;
}
div.notification
{
color: purple;
@@ -119,12 +119,12 @@
</xsl:when>
<!--
other messages, like:
other messages, like:
- application message (e.g. invite for file transfer)
- notification message (e.g. file received)
- system message (error messages, e.g. invitations KMess does not support)
-->
<xsl:when test="@type='application' or @type='notification' or @type='system'">
<xsl:when test="@type='application' or @type='presence' or @type='notification' or @type='system'">
<div class="{body/@dir}">
<div class="{@type}" dir="{body/@dir}">
+6
View File
@@ -129,6 +129,7 @@ dt span.time
*/
div.application,
div.notification,
div.presence,
div.system
{
margin: 10px 0 10px; /* top and bottom margin */
@@ -139,6 +140,11 @@ div.application
color: #6172b2;
}
div.presence
{
color: #c4c4c4;
}
div.notification
{
color: #c034c9;
+2 -2
View File
@@ -118,12 +118,12 @@
</xsl:when>
<!--
other messages, like:
other messages, like:
- application message (e.g. invite for file transfer)
- notification message (e.g. file received)
- system message (error messages, e.g. invitations KMess does not support)
-->
<xsl:when test="@type='application' or @type='notification' or @type='system'">
<xsl:when test="@type='application' or @type='presence' or @type='notification' or @type='system'">
<div class="{body/@dir}">
<div class="{@type}" dir="{body/@dir}">
+6
View File
@@ -144,6 +144,7 @@ dl
div.application,
div.notification,
div.presence,
div.system
{
margin-left: 7em;
@@ -210,6 +211,11 @@ div.application
color: blue;
}
div.presence
{
color: gray;
}
div.notification
{
color: purple;
+2 -2
View File
@@ -118,12 +118,12 @@
</xsl:when>
<!--
other messages, like:
other messages, like:
- application message (e.g. invite for file transfer)
- notification message (e.g. file received)
- system message (error messages, e.g. invitations KMess does not support)
-->
<xsl:when test="@type='application' or @type='notification' or @type='system'">
<xsl:when test="@type='application' or @type='presence' or @type='notification' or @type='system'">
<div class="{body/@dir}">
<div class="{@type}">
@@ -119,6 +119,7 @@ dl, dt, dd
div.application,
div.notification,
div.presence,
div.system
{
margin-left: 11px;
@@ -228,6 +229,11 @@ div.application
color: #0b0;
}
div.presence
{
color: #bbb;
}
div.notification
{
color: #bb0;
+2 -2
View File
@@ -137,12 +137,12 @@
</xsl:when>
<!--
other messages, like:
other messages, like:
- application message (e.g. invite for file transfer)
- notification message (e.g. file received)
- system message (error messages, e.g. invitations KMess does not support)
-->
<xsl:when test="@type='application' or @type='notification' or @type='system'">
<xsl:when test="@type='application' or @type='presence' or @type='notification' or @type='system'">
<div class="{body/@dir}">
<div class="{@type}" dir="{body/@dir}">
+6
View File
@@ -118,6 +118,7 @@ dl, dt, dd
div.application,
div.notification,
div.presence,
div.system
{
margin-left: 11px;
@@ -227,6 +228,11 @@ div.application
color: blue;
}
div.presence
{
color: gray;
}
div.notification
{
color: purple;
+2 -2
View File
@@ -136,12 +136,12 @@
</xsl:when>
<!--
other messages, like:
other messages, like:
- application message (e.g. invite for file transfer)
- notification message (e.g. file received)
- system message (error messages, e.g. invitations KMess does not support)
-->
<xsl:when test="@type='application' or @type='notification' or @type='system'">
<xsl:when test="@type='application' or @type='presence' or @type='notification' or @type='system'">
<div class="{body/@dir}">
<div class="{@type}" dir="{body/@dir}">
+6
View File
@@ -253,6 +253,7 @@ dd
*/
div.application,
div.notification,
div.presence,
div.system
{
margin: 10px 0 10px; /* top and bottom margin */
@@ -263,6 +264,11 @@ div.application
color: blue;
}
div.presence
{
color: gray;
}
div.notification
{
color: purple;
+3 -3
View File
@@ -104,7 +104,7 @@
<span class="name">
<xsl:value-of disable-output-escaping="yes" select="from/contact/displayName/@text"/>
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
</span>
</span>
</span>
</dt>
@@ -121,12 +121,12 @@
</xsl:when>
<!--
other messages, like:
other messages, like:
- application message (e.g. invite for file transfer)
- notification message (e.g. file received)
- system message (error messages, e.g. invitations KMess does not support)
-->
<xsl:when test="@type='application' or @type='notification' or @type='system'">
<xsl:when test="@type='application' or @type='presence' or @type='notification' or @type='system'">
<div class="{body/@dir}">
<div class="{@type}" dir="{body/@dir}">
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

+4 -4
View File
@@ -7,10 +7,10 @@ Type=Application
DocPath=kmess/index.html
Terminal=0
Categories=Qt;KDE;Network;InstantMessaging;
Comment=MSN Messenger Clone for KDE 4
Comment[de]=MSN-Messenger-Klon für KDE 4
Comment=Live Messenger Client for KDE
Comment[de]=Live-Messenger-Klon für KDE 4
Comment[nl]=MSN Messenger Kloon voor KDE 4
GenericName=MSN Client
GenericName=Live Messenger Client
GenericName[af]=Irc Kliënt
GenericName[ar]=عميل MSN
GenericName[be]=Кліент MSN
@@ -20,7 +20,7 @@ GenericName[ca]=Client MSN
GenericName[cs]=MSN klient
GenericName[cy]=Dibynnydd MSN
GenericName[da]=MSN-klient
GenericName[de]=MSN-Programm
GenericName[de]=Live-Messenger-Programm
GenericName[el]=Πελάτης MSN
GenericName[eo]=MSN-kliento
GenericName[es]=Cliente de MSN

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

+1524 -868
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

+5 -5
View File
@@ -1,11 +1,11 @@
Begin4
Title: KMess
Version: 2.0beta1
Entered-date: 2005-05-05
Version: 2.0beta2
Entered-date: 2009-05-10
Description: A MSN Messenger / Windows Live Messenger client for KDE
Keywords: KDE X11 desktop MSN Messenger
Keywords: KDE, X11, desktop, WLM, MSN, Live, Messenger
Author: KMess Developers Team <project@kmess.org>
Primary-site: http://www.kmess.org/
Platforms: Linux and other Unices
Copying-policy: GNU Public License
Platforms: Linux (and most unices) and Windows; requires KDE (at least 4.0)
Copying-policy: GNU General Public License 2.0
End
+2 -2
View File
@@ -13,8 +13,8 @@
# PACKAGE SETTINGS
#
%define kmess_version 2.0beta1
%define kmess_tar_version 2.0beta1
%define kmess_version 2.0beta2
%define kmess_tar_version 2.0beta2
%define rpm_release 1
%define with_debug 0
%define doc_files AUTHORS COPYING FEATURES INSTALL NEWS README TODO
+606
View File
@@ -0,0 +1,606 @@
{
<insert a suppression name here>
Memcheck:Param
write(buf)
fun:__write_nocancel
obj:/usr/lib/libICE.so.6.3.0
fun:_IceWrite
fun:IceFlush
fun:_ZL14sm_setPropertyPKcS0_iP11SmPropValue
fun:_ZL14sm_setPropertyRK7QStringS1_
fun:_ZL22sm_performSaveYourselfP22QSessionManagerPrivate
fun:_ZL23sm_saveYourselfCallbackP8_SmcConnPviiii
fun:_SmcProcessMessage
fun:IceProcessMessages
fun:_ZN17QSmSocketReceiver11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
}
{
<insert a suppression name here>
Memcheck:Cond
fun:BN_mod_inverse
fun:BN_MONT_CTX_set
fun:BN_MONT_CTX_set_locked
obj:/lib/libcrypto.so.0.9.8
fun:RSA_verify
fun:EVP_VerifyFinal
fun:ASN1_item_verify
obj:/lib/libcrypto.so.0.9.8
fun:X509_verify_cert
fun:ssl_verify_cert_chain
fun:ssl3_get_server_certificate
fun:ssl3_connect
}
{
<insert a suppression name here>
Memcheck:Cond
fun:BN_div
fun:BN_nnmod
fun:BN_mod_inverse
fun:BN_MONT_CTX_set
fun:BN_MONT_CTX_set_locked
obj:/lib/libcrypto.so.0.9.8
fun:RSA_verify
fun:EVP_VerifyFinal
fun:ASN1_item_verify
obj:/lib/libcrypto.so.0.9.8
fun:X509_verify_cert
fun:ssl_verify_cert_chain
}
{
<insert a suppression name here>
Memcheck:Cond
fun:BN_div
fun:BN_nnmod
fun:BN_mod_inverse
fun:BN_MONT_CTX_set
fun:BN_MONT_CTX_set_locked
obj:/lib/libcrypto.so.0.9.8
fun:RSA_verify
fun:EVP_VerifyFinal
fun:ASN1_item_verify
obj:/lib/libcrypto.so.0.9.8
fun:X509_verify_cert
fun:ssl_verify_cert_chain
}
{
<insert a suppression name here>
Memcheck:Cond
fun:BN_mod_inverse
fun:BN_MONT_CTX_set
fun:BN_MONT_CTX_set_locked
obj:/lib/libcrypto.so.0.9.8
fun:ssl3_send_client_key_exchange
fun:ssl3_connect
fun:_ZN24QSslSocketBackendPrivate14testConnectionEv
fun:_ZN24QSslSocketBackendPrivate8transmitEv
fun:_ZN10QSslSocket11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
fun:_ZN22QAbstractSocketPrivate19canReadNotificationEv
fun:_ZN13QReadNotifier5eventEP6QEvent
}
{
<insert a suppression name here>
Memcheck:Cond
fun:BN_div
fun:BN_MONT_CTX_set
fun:BN_MONT_CTX_set_locked
obj:/lib/libcrypto.so.0.9.8
fun:ssl3_send_client_key_exchange
fun:ssl3_connect
fun:_ZN24QSslSocketBackendPrivate14testConnectionEv
fun:_ZN24QSslSocketBackendPrivate8transmitEv
fun:_ZN10QSslSocket11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
fun:_ZN22QAbstractSocketPrivate19canReadNotificationEv
fun:_ZN13QReadNotifier5eventEP6QEvent
}
{
<insert a suppression name here>
Memcheck:Cond
fun:deflate
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
fun:png_write_row
fun:png_write_image
fun:_ZN15QPNGImageWriter10writeImageERK6QImageiRK7QStringii
fun:_ZN11QPngHandler5writeERK6QImage
fun:_ZN12QImageWriter5writeERK6QImage
fun:_ZlsR11QDataStreamRK6QImage
fun:_ZlsR11QDataStreamRK7QPixmap
fun:_ZN20KNotificationManager6notifyEP13KNotificationRK7QPixmapRK11QStringListRK5QListI5QPairI7QStringSA_EERKSA_
}
{
<insert a suppression name here>
Memcheck:Value8
fun:crc32
obj:/usr/lib/libpng12.so.0.27.0
fun:png_write_chunk_data
fun:png_write_chunk
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
fun:png_write_row
fun:png_write_image
fun:_ZN15QPNGImageWriter10writeImageERK6QImageiRK7QStringii
fun:_ZN11QPngHandler5writeERK6QImage
}
{
<insert a suppression name here>
Memcheck:Value8
fun:crc32
obj:/usr/lib/libpng12.so.0.27.0
fun:png_write_chunk_data
fun:png_write_chunk
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
obj:/usr/lib/libpng12.so.0.27.0
fun:png_write_row
fun:png_write_image
fun:_ZN15QPNGImageWriter10writeImageERK6QImageiRK7QStringii
fun:_ZN11QPngHandler5writeERK6QImage
}
{
<insert a suppression name here>
Memcheck:Param
writev(vector[...])
fun:writev
obj:/lib/libdbus-1.so.3.4.0
obj:/lib/libdbus-1.so.3.4.0
obj:/lib/libdbus-1.so.3.4.0
obj:/lib/libdbus-1.so.3.4.0
obj:/lib/libdbus-1.so.3.4.0
obj:/lib/libdbus-1.so.3.4.0
obj:/lib/libdbus-1.so.3.4.0
fun:dbus_connection_send_with_reply
fun:_ZN22QDBusConnectionPrivate18sendWithReplyAsyncERK12QDBusMessagei
fun:_ZN22QDBusConnectionPrivate18sendWithReplyAsyncERK12QDBusMessageP7QObjectPKcS6_i
fun:_ZNK15QDBusConnection16callWithCallbackERK12QDBusMessageP7QObjectPKcS6_i
}
{
<insert a suppression name here>
Memcheck:Param
write(buf)
obj:/lib/libc-2.9.so
obj:/usr/lib/libICE.so.6.3.0
fun:_IceWrite
fun:IceFlush
fun:SmcCloseConnection
fun:_ZN15QSessionManagerD0Ev
fun:_ZN12QApplicationD2Ev
fun:_ZN16KMessApplicationD1Ev
fun:main
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:_ZN7QString7reallocEi
fun:_ZN7QString6resizeEi
fun:_ZN7QString8fromUtf8EPKci
fun:_ZL26fromPercentEncodingMutableP10QByteArray
fun:_ZNK11QUrlPrivate5parseENS_12ParseOptionsE
fun:_ZNK4QUrl7isValidEv
fun:_ZN4KUrl14_setEncodedUrlERK10QByteArray
fun:_ZN4KUrlC1ERK7QString
fun:_ZN5khtml6Loader20servePendingRequestsEv
fun:_ZN5khtml19CachedCSSStyleSheetC1EPNS_9DocLoaderERKN3DOM9DOMStringEN3KIO12CacheControlEPKc
fun:_ZN5khtml5Cache13requestObjectINS_19CachedCSSStyleSheetELNS_12CachedObject4TypeE1EEEPT_PNS_9DocLoaderERK4KUrlPKc
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
obj:/usr/lib/libxml2.so.2.6.32
fun:xmlSAX2StartElementNs
obj:/usr/lib/libxml2.so.2.6.32
fun:xmlParseElement
fun:xmlParseContent
fun:xmlParseElement
fun:xmlParseDocument
fun:xmlSAXParseMemoryWithData
fun:_ZN17XslTransformation13setStylesheetERK7QString
fun:_ZN16ChatMessageStyle8setStyleERK7QString
fun:_ZN15ChatMessageView15updateChatStyleEv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:_Znwm
fun:_ZN19QDockAreaLayoutInfo12restoreStateER11QDataStreamR5QListIP11QDockWidgetEb
fun:_ZN15QDockAreaLayout12restoreStateER11QDataStreamRK5QListIP11QDockWidgetEb
fun:_ZN22QMainWindowLayoutState11checkFormatER11QDataStreamb
fun:_ZN22QMainWindowLayoutState12restoreStateER11QDataStreamRKS_
fun:_ZN17QMainWindowLayout12restoreStateER11QDataStream
fun:_ZN11QMainWindow12restoreStateERK10QByteArrayi
fun:_ZN11KMainWindow23applyMainWindowSettingsERK12KConfigGroupb
fun:_ZN13KXmlGuiWindow23applyMainWindowSettingsERK12KConfigGroupb
fun:_ZN10ChatWindow10initializeEv
fun:_ZN10ChatMaster16createChatWindowEP4Chat
fun:_ZN10ChatMaster10createChatEP24MsnSwitchboardConnectionb
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:_ZN8QMapData11node_createEPPNS_4NodeEi
fun:_ZN4QMapI10QByteArray11QStringListE11node_createEP8QMapDataPPNS3_4NodeERKS0_RKS1_
fun:_ZNK13KStandardDirs12resourceDirsEPKc
fun:_ZN10KIconThemeC1ERK7QStringS2_
fun:_ZN18KIconLoaderPrivate14initIconThemesEv
fun:_ZN11KIconLoader9addAppDirERK7QString
fun:_ZN16KMessApplication15initializePathsEv
fun:_ZN16KMessApplicationC1Ev
fun:main
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
obj:/usr/lib/libxslt.so.1.1.24
fun:xsltParseStylesheetProcess
fun:xsltParseStylesheetImportedDoc
fun:xsltParseStylesheetDoc
fun:_ZN17XslTransformation13setStylesheetERK7QString
fun:_ZN16ChatMessageStyle8setStyleERK7QString
fun:_ZN15ChatMessageView15updateChatStyleEv
fun:_ZN8ChatView10initializeEv
fun:_ZN4Chat10initializeEP24MsnSwitchboardConnection
fun:_ZN10ChatMaster10createChatEP24MsnSwitchboardConnectionb
fun:_ZN10ChatMaster11qt_metacallEN11QMetaObject4CallEiPPv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
obj:/usr/lib/libfontconfig.so.1.3.0
obj:/usr/lib/libfontconfig.so.1.3.0
obj:/usr/lib/libfontconfig.so.1.3.0
obj:/usr/lib/libfontconfig.so.1.3.0
obj:/usr/lib/libexpat.so.1.5.2
obj:/usr/lib/libexpat.so.1.5.2
obj:/usr/lib/libexpat.so.1.5.2
obj:/usr/lib/libexpat.so.1.5.2
fun:XML_ParseBuffer
fun:FcConfigParseAndLoad
fun:FcConfigParseAndLoad
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:nss_parse_service_list
fun:__nss_database_lookup
obj:*
obj:*
fun:getpwuid_r@@GLIBC_2.2.5
fun:_ZL22sm_performSaveYourselfP22QSessionManagerPrivate
fun:_ZL23sm_saveYourselfCallbackP8_SmcConnPviiii
fun:_SmcProcessMessage
fun:IceProcessMessages
fun:_ZN17QSmSocketReceiver11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:_XimOpenIM
fun:_XimRegisterIMInstantiateCallback
fun:XRegisterIMInstantiateCallback
fun:_ZN16QXIMInputContextC1Ev
fun:_ZN20QInputContextFactory6createERK7QStringP7QObject
fun:_ZNK12QApplication12inputContextEv
fun:_ZN19QApplicationPrivate14setFocusWidgetEP7QWidgetN2Qt11FocusReasonE
fun:_ZN7QWidget8setFocusEN2Qt11FocusReasonE
fun:_ZN12QApplication15setActiveWindowEP7QWidget
fun:_ZN12QApplication15x11ProcessEventEP7_XEvent
fun:_ZL22x11EventSourceDispatchP8_GSourcePFiPvES1_
}
{
<insert a suppression name here>
Memcheck:Leak
fun:_Znwm
fun:_ZN5khtml11RenderStyleC1Eb
fun:_ZN5khtml11RenderStyleC1Ev
fun:_ZN5khtml16CSSStyleSelector21setupDefaultRootStyleEPN3DOM12DocumentImplE
fun:_ZN5khtml16CSSStyleSelectorC1EPN3DOM12DocumentImplE7QStringPNS1_18StyleSheetListImplERK4KUrlb
fun:_ZN3DOM12DocumentImpl6attachEv
fun:_ZN9KHTMLPart5beginERK4KUrlii
fun:_ZN15ChatMessageView7setHtmlERK7QString
fun:_ZN15ChatMessageView9clearViewEb
fun:_ZN15ChatMessageViewC1EP7QWidget
fun:_ZN8ChatViewC2EP7QWidget
fun:_ZN4ChatC1EP7QWidget
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:CRYPTO_malloc
fun:c2i_ASN1_BIT_STRING
fun:asn1_ex_c2i
obj:/lib/libcrypto.so.0.9.8
fun:ASN1_item_ex_d2i
obj:/lib/libcrypto.so.0.9.8
obj:/lib/libcrypto.so.0.9.8
fun:ASN1_item_ex_d2i
obj:/lib/libcrypto.so.0.9.8
obj:/lib/libcrypto.so.0.9.8
fun:ASN1_item_ex_d2i
}
{
<insert a suppression name here>
Memcheck:Leak
fun:realloc
obj:/usr/lib/libfontconfig.so.1.3.0
obj:/usr/lib/libfontconfig.so.1.3.0
fun:FcDefaultSubstitute
fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei
fun:_ZNK12QFontPrivate15engineForScriptEi
fun:_ZNK12QFontMetrics6heightEv
fun:_ZN10QStatusBar8reformatEv
fun:_ZN10QStatusBar18setSizeGripEnabledEb
fun:_ZN10QStatusBarC2EP7QWidget
fun:_ZN10KStatusBarC1EP7QWidget
fun:_ZN11KMainWindow9statusBarEv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:_ZN8QMapData11node_createEPPNS_4NodeEi
fun:_ZN4QMapI9KEntryKey6KEntryE6insertERKS0_RKS1_
fun:_ZN9KEntryMap8setEntryERK10QByteArrayS2_S2_6QFlagsINS_11EntryOptionEE
fun:_ZN17KConfigIniBackend11parseConfigERK10QByteArrayR9KEntryMap6QFlagsIN14KConfigBackend11ParseOptionEEb
fun:_ZN17KConfigIniBackend11parseConfigERK10QByteArrayR9KEntryMap6QFlagsIN14KConfigBackend11ParseOptionEE
fun:_ZN14KConfigPrivate16parseConfigFilesEv
fun:_ZN7KConfig20reparseConfigurationEv
fun:_ZN7KConfigC1ERK7QString6QFlagsINS_8OpenFlagEEPKc
fun:_ZN11KMessConfig15getGlobalConfigERK7QString
fun:_ZN13NetworkWindowD0Ev
fun:_ZN13NetworkWindow7destroyEv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:CRYPTO_malloc
fun:SSL_new
fun:_ZN24QSslSocketBackendPrivate14initSslContextEv
fun:_ZN24QSslSocketBackendPrivate21startClientEncryptionEv
fun:_ZN17QSslSocketPrivate16_q_connectedSlotEv
fun:_ZN10QSslSocket11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
fun:_ZN22QAbstractSocketPrivate25fetchConnectionParametersEv
fun:_ZN22QAbstractSocketPrivate17_q_testConnectionEv
fun:_ZN14QWriteNotifier5eventEP6QEvent
fun:_ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent
}
{
<insert a suppression name here>
Memcheck:Cond
fun:BN_div
fun:BN_MONT_CTX_set
fun:BN_MONT_CTX_set_locked
obj:/lib/libcrypto.so.0.9.8
fun:RSA_verify
fun:EVP_VerifyFinal
fun:ASN1_item_verify
obj:/lib/libcrypto.so.0.9.8
fun:X509_verify_cert
fun:ssl_verify_cert_chain
fun:ssl3_get_server_certificate
fun:ssl3_connect
}
{
<insert a suppression name here>
Memcheck:Leak
fun:_Znwm
fun:_ZNK14QX11PixmapData11paintEngineEv
fun:_ZN8QPainter5beginEP12QPaintDevice
fun:_ZN11KIconEngine6pixmapERK5QSizeN5QIcon4ModeENS3_5StateE
fun:_ZNK5QIcon6pixmapERK5QSizeNS_4ModeENS_5StateE
fun:_ZN14QWidgetPrivate17setWindowIcon_sysEb
fun:_ZN7QWidget6createEmbb
fun:_ZN7QWidget10setVisibleEb
fun:_ZN7QWidget4showEv
fun:_ZN11LikeBackBar8autoMoveEv
fun:_ZN11LikeBackBar11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:CRYPTO_malloc
fun:ssl3_setup_buffers
fun:ssl3_connect
fun:_ZN24QSslSocketBackendPrivate14testConnectionEv
fun:_ZN24QSslSocketBackendPrivate21startClientEncryptionEv
fun:_ZN17QSslSocketPrivate16_q_connectedSlotEv
fun:_ZN10QSslSocket11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
fun:_ZN22QAbstractSocketPrivate25fetchConnectionParametersEv
fun:_ZN22QAbstractSocketPrivate17_q_testConnectionEv
fun:_ZN14QWriteNotifier5eventEP6QEvent
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:CRYPTO_malloc
fun:ASN1_OBJECT_new
fun:c2i_ASN1_OBJECT
fun:asn1_ex_c2i
obj:/lib/libcrypto.so.0.9.8
fun:ASN1_item_ex_d2i
obj:/lib/libcrypto.so.0.9.8
obj:/lib/libcrypto.so.0.9.8
fun:ASN1_item_ex_d2i
obj:/lib/libcrypto.so.0.9.8
obj:/lib/libcrypto.so.0.9.8
}
{
<insert a suppression name here>
Memcheck:Cond
fun:_ZL13PolygonRegionPK6QPointii
fun:_ZN7QRegionC1ERK8QPolygonN2Qt8FillRuleE
fun:_ZN15QX11PaintEngine11updateStateERK17QPaintEngineState
fun:_ZN15QPainterPrivate15updateStateImplEP13QPainterState
fun:_ZN15QPainterPrivate11updateStateEP13QPainterState
fun:_ZN8QPainter13setClipRegionERK7QRegionN2Qt13ClipOperationE
fun:_ZNK14QWidgetPrivate15paintBackgroundEP8QPainterRK7QRegionRK6QPointi
fun:_ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore
fun:_ZN19QWidgetBackingStore4syncEv
fun:_ZN14QWidgetPrivate16syncBackingStoreEv
fun:_ZN7QWidget5eventEP6QEvent
fun:_ZN11QMainWindow5eventEP6QEvent
}
{
<insert a suppression name here>
Memcheck:Cond
fun:_ZL13PolygonRegionPK6QPointii
fun:_ZN7QRegionC1ERK8QPolygonN2Qt8FillRuleE
fun:_ZN15QX11PaintEngine11updateStateERK17QPaintEngineState
fun:_ZN15QPainterPrivate15updateStateImplEP13QPainterState
fun:_ZN15QPainterPrivate11updateStateEP13QPainterState
fun:_ZN8QPainter13setClipRegionERK7QRegionN2Qt13ClipOperationE
fun:_ZNK14QWidgetPrivate15paintBackgroundEP8QPainterRK7QRegionRK6QPointi
fun:_ZN14QWidgetPrivate10drawWidgetEP12QPaintDeviceRK7QRegionRK6QPointiP8QPainterP19QWidgetBackingStore
fun:_ZN19QWidgetBackingStore4syncEv
fun:_ZN14QWidgetPrivate16syncBackingStoreEv
fun:_ZN7QWidget5eventEP6QEvent
fun:_ZN11QMainWindow5eventEP6QEvent
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:_ZN7QString7reallocEi
fun:_ZN7QString6resizeEi
fun:_ZN7QString8fromUtf8EPKci
fun:_ZL26fromPercentEncodingMutableP10QByteArray
fun:_ZNK11QUrlPrivate5parseENS_12ParseOptionsE
fun:_ZNK4QUrl7isValidEv
fun:_ZN4KUrl14_setEncodedUrlERK10QByteArray
fun:_ZN4KUrlC1ERK7QString
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
fun:_ZN11QMetaObject8activateEP7QObjectiiPPv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:realloc
obj:/usr/lib/libfontconfig.so.1.3.0
obj:/usr/lib/libfontconfig.so.1.3.0
fun:FcPatternDuplicate
fun:_ZL14tryPatternLoadP10_FcPatterniRK8QFontDefiPS0_
fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei
fun:_ZNK12QFontPrivate15engineForScriptEi
fun:_ZNK12QFontMetrics6ascentEv
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:_ZN8QMapData11node_createEPPNS_4NodeEi
fun:_ZN4QMapI7QStringS0_E11node_createEP8QMapDataPPNS2_4NodeERKS0_S8_
fun:_ZN4QMapI7QStringS0_E13detach_helperEv
fun:_ZN4QMapI7QStringS0_E6detachEv
fun:_ZN4QMapI7QStringS0_E5beginEv
fun:_ZN17XslTransformation20updateParametersListEv
fun:_ZN17XslTransformation13setParametersE4QMapI7QStringS1_E
fun:_ZN16ChatMessageStyle8setStyleERK7QString
fun:_ZN13ChatStylePage20slotChatStyleChangedERK7QString
fun:_ZN13ChatStylePage12loadSettingsEPK7Account
fun:_ZN21AccountSettingsDialog12loadSettingsEP7AccountbNS_4PageE
}
{
<insert a suppression name here>
Memcheck:Leak
fun:_Znwm
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
obj:/usr/lib/libkhtml.so.5.2.0
fun:_ZN9KHTMLPart5beginERK4KUrlii
fun:_ZN15ChatMessageView7setHtmlERK7QString
fun:_ZN15ChatMessageView9clearViewEb
fun:_ZN15ChatMessageViewC1EP7QWidget
fun:_ZN8ChatViewC2EP7QWidget
fun:_ZN4ChatC1EP7QWidget
}
{
<insert a suppression name here>
Memcheck:Leak
fun:_Znwm
fun:_ZN19QDockAreaLayoutInfo12restoreStateER11QDataStreamR5QListIP11QDockWidgetEb
fun:_ZN15QDockAreaLayout12restoreStateER11QDataStreamRK5QListIP11QDockWidgetEb
fun:_ZN22QMainWindowLayoutState11checkFormatER11QDataStreamb
fun:_ZN22QMainWindowLayoutState12restoreStateER11QDataStreamRKS_
fun:_ZN17QMainWindowLayout12restoreStateER11QDataStream
fun:_ZN11QMainWindow12restoreStateERK10QByteArrayi
fun:_ZN10ChatWindow14readPropertiesERK12KConfigGroup
fun:_ZN10ChatWindow10initializeEv
fun:_ZN10ChatMaster16createChatWindowEP4Chat
fun:_ZN10ChatMaster10createChatEP24MsnSwitchboardConnectionb
fun:_ZN10ChatMaster11qt_metacallEN11QMetaObject4CallEiPPv
}
{
<insert a suppression name here>
Memcheck:Leak
fun:malloc
fun:_ZN7QVectorI5QListIN14QObjectPrivate10ConnectionEEE7reallocEii
fun:_ZN14QObjectPrivate13addConnectionEiPNS_10ConnectionE
fun:_ZN11QMetaObject7connectEPK7QObjectiS2_iiPi
fun:_ZN7QObject7connectEPKS_PKcS1_S3_N2Qt14ConnectionTypeE
fun:_ZN14KActionPrivate4initEP7KAction
fun:_ZN7KActionC1ERK5KIconRK7QStringP7QObject
fun:_ZN8LikeBack18sendACommentActionEP17KActionCollection
fun:_ZN14KMessInterface10initializeEv
fun:_ZN5KMess10initializeEv
fun:_ZN16KMessApplication20initializeMainWindowEv
fun:_ZN16KMessApplicationC1Ev
}
{
<insert a suppression name here>
Memcheck:Leak
fun:realloc
fun:_ZN9QListData7reallocEi
fun:_ZN9QListData6appendEv
fun:_ZN5QListIP7QObjectE6appendERKS1_
fun:_ZN14QObjectPrivate16setParent_helperEP7QObject
fun:_ZN15QSocketNotifierC2EiNS_4TypeEP7QObject
fun:_ZN19QNativeSocketEngine27setWriteNotificationEnabledEb
fun:_ZN22QAbstractSocketPrivate23_q_connectToNextAddressEv
fun:_ZN22QAbstractSocketPrivate18_q_startConnectingERK9QHostInfo
fun:_ZN15QAbstractSocket27connectToHostImplementationERK7QStringt6QFlagsIN9QIODevice12OpenModeFlagEE
fun:_ZN15QAbstractSocket11qt_metacallEN11QMetaObject4CallEiPPv
fun:_ZNK11QMetaMethod6invokeEP7QObjectN2Qt14ConnectionTypeE22QGenericReturnArgument16QGenericArgumentS5_S5_S5_S5_S5_S5_S5_S5_S5_
}
{
<insert a suppression name here>
Memcheck:Leak
fun:realloc
obj:/usr/lib/libfontconfig.so.1.3.0
obj:/usr/lib/libfontconfig.so.1.3.0
fun:FcDefaultSubstitute
fun:_ZN13QFontDatabase4loadEPK12QFontPrivatei
fun:_ZNK12QFontPrivate15engineForScriptEi
fun:_ZNK12QFontMetrics6ascentEv
fun:_ZN5khtml18CachedFontInstanceC1EPNS_16CachedFontFamilyEi
fun:_ZN5khtml16CachedFontFamily9queryFontEi
fun:_ZNK5khtml4Font6updateEi
fun:_ZN5khtml4Font11initDefaultEv
fun:_ZN5khtml11RenderStyleC1Eb
}
+5444 -5454
View File
File diff suppressed because it is too large Load Diff
+4537 -4439
View File
File diff suppressed because it is too large Load Diff
+3333 -3001
View File
File diff suppressed because it is too large Load Diff
+3674 -3143
View File
File diff suppressed because it is too large Load Diff
+3566 -2919
View File
File diff suppressed because it is too large Load Diff
+3938 -3386
View File
File diff suppressed because it is too large Load Diff
+3238 -2934
View File
File diff suppressed because it is too large Load Diff
+3927 -3902
View File
File diff suppressed because it is too large Load Diff
+3498 -2935
View File
File diff suppressed because it is too large Load Diff
+3425 -2908
View File
File diff suppressed because it is too large Load Diff
+3817 -3280
View File
File diff suppressed because it is too large Load Diff
+4472 -4212
View File
File diff suppressed because it is too large Load Diff
+3316 -3005
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -1,5 +1,5 @@
#!/bin/sh
#
#
# Extract all messages from the source code.
# The messages are saved into kmess.pot
#
@@ -39,7 +39,8 @@ echo "rc.cpp" > $IN_LIST
find . -name '*.cpp' -o -name '*.h' -o -name '*.c' | sort >> $IN_LIST
cd $WDIR
xgettext --from-code=UTF-8 --language=C++ -kde \
xgettext --from-code=UTF-8 --language=C++ --kde \
--sort-by-file --indent \
-ci18n \
-ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -ktr2i18n:1 \
-kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \
+3253 -2931
View File
File diff suppressed because it is too large Load Diff
+3515 -3209
View File
File diff suppressed because it is too large Load Diff
+3660 -3118
View File
File diff suppressed because it is too large Load Diff
+3419 -3000
View File
File diff suppressed because it is too large Load Diff
+3265 -2936
View File
File diff suppressed because it is too large Load Diff
+3451 -2940
View File
File diff suppressed because it is too large Load Diff
+3383 -2993
View File
File diff suppressed because it is too large Load Diff
+3265 -2945
View File
File diff suppressed because it is too large Load Diff
+3336 -3007
View File
File diff suppressed because it is too large Load Diff
+3294 -2890
View File
File diff suppressed because it is too large Load Diff
+3280 -2911
View File
File diff suppressed because it is too large Load Diff
+22 -15
View File
@@ -164,28 +164,21 @@ SET(kmess_LIBS
${KDE4_KHTML_LIBS}
${KDE4_KNOTIFYCONFIG_LIBS}
${KDE4_KNEWSTUFF2_LIBS}
${KDE4_PHONON_LIBS}
${KDE4_SOLID_LIBS}
${LIBXML2_LIBRARIES}
${LIBXSLT_LIBRARIES}
${QCA2_LIBRARIES}
${QT_QTTEST_LIBRARY}
)
# If we're compiling in debug mode:
IF( ${KMESS_ENABLE_DEBUG_OUTPUT} EQUAL 1 )
# Enable the Network Window
SET(kmess_SOURCES ${kmess_SOURCES} dialogs/networkwindow.cpp)
SET(kmess_UI_FILES ${kmess_UI_FILES} dialogs/networkwindow.ui)
# Enable the Null Socket
SET(kmess_SOURCES ${kmess_SOURCES} network/msnsocketnull.cpp)
# Enable the testing class
SET(kmess_SOURCES ${kmess_SOURCES} kmesstest.cpp)
# Enable the old parser
SET(kmess_SOURCES ${kmess_SOURCES} ../tests/old_richtextparser.cpp)
# Enable the Models tester
IF( CMAKE_BUILD_TYPE STREQUAL debugfull )
SET( kmess_SOURCES ${kmess_SOURCES} ../tests/modeltest/modeltest.cpp )
ENDIF( CMAKE_BUILD_TYPE STREQUAL debugfull )
IF( ${GIF_FOUND} )
INCLUDE_DIRECTORIES( ${GIF_INCLUDE_DIR} )
SET( kmess_LIBS ${kmess_LIBS} ${GIF_LIBRARIES} )
ENDIF( ${GIF_FOUND} )
# If LikeBack is enabled, compile it
IF( NOT ${KMESS_DISABLE_LIKEBACK} EQUAL 1 )
# Enable LikeBack
SET( kmess_SOURCES ${kmess_SOURCES}
utils/likeback/likeback.cpp
@@ -194,7 +187,21 @@ IF( ${KMESS_ENABLE_DEBUG_OUTPUT} EQUAL 1 )
SET( kmess_UI_FILES ${kmess_UI_FILES}
utils/likeback/likebackbar.ui
utils/likeback/likebackdialog.ui )
ENDIF( NOT ${KMESS_DISABLE_LIKEBACK} EQUAL 1 )
# If we're compiling in debug mode:
IF( ${KMESS_ENABLE_DEBUG_OUTPUT} EQUAL 1 )
# Enable the Network Window
SET(kmess_SOURCES ${kmess_SOURCES} dialogs/networkwindow.cpp)
SET(kmess_UI_FILES ${kmess_UI_FILES} dialogs/networkwindow.ui)
# Enable the testing class
SET(kmess_SOURCES ${kmess_SOURCES} kmesstest.cpp)
# Enable the old parser
SET(kmess_SOURCES ${kmess_SOURCES} ../tests/old_richtextparser.cpp)
# Enable the Models tester
IF( CMAKE_BUILD_TYPE STREQUAL debugfull )
SET( kmess_SOURCES ${kmess_SOURCES} ../tests/modeltest/modeltest.cpp )
ENDIF( CMAKE_BUILD_TYPE STREQUAL debugfull )
ENDIF( ${KMESS_ENABLE_DEBUG_OUTPUT} EQUAL 1 )
# Enable BinReloc for Autopackage support. Also requires libpthread
+46 -9
View File
@@ -42,7 +42,7 @@
// The constructor
Account::Account()
: autoreplyMessage_( i18n("I'm away from my computer") ),
: autoreplyMessage_( i18n("I am away from my computer") ),
chatStyle_( "Fresh" ),
contactFontColor_("#000000"),
contactListDisplayMode_(VIEW_MIXED),
@@ -55,7 +55,7 @@ Account::Account()
guestAccount_(true),
groupFollowupMessages_(true),
handle_( i18n("you@hotmail.com") ),
hideNotificationsWhenBusy_(false),
hideNotificationsWhenBusy_(true),
idleTime_(5),
initialStatus_(STATUS_ONLINE),
listPictureSize_(0),
@@ -406,6 +406,14 @@ const int& Account::getSavedChatDirectoryStructure() const
// Return the user's saved password
QString Account::getSavedPassword() const
{
return savedPassword_;
}
// Read whether the password must be stored
bool Account::getSavePassword() const
{
@@ -733,7 +741,7 @@ void Account::readProperties( const QString &handle )
// Choose the main group
KConfigGroup profileGroup = KMessConfig::instance()->getAccountConfig( handle_, "Account" );
autoreplyMessage_ = profileGroup.readEntry( "autoreplymessage", i18n("I'm away from my computer") );
autoreplyMessage_ = profileGroup.readEntry( "autoreplymessage", i18n("I am away from my computer") );
chatStyle_ = profileGroup.readEntry( "chatStyle", "Fresh" );
contactFont_.setFamily ( profileGroup.readEntry( "contactfontfamily", "Arial" ) );
contactFont_.setBold ( profileGroup.readEntry( "contactfontbold", false ) );
@@ -755,7 +763,7 @@ void Account::readProperties( const QString &handle )
fontColor_ = profileGroup.readEntry( "fontColor" , "#000000" );
friendlyName_.setString ( profileGroup.readEntry( "friendlyName", handle_ ) );
groupFollowupMessages_ = profileGroup.readEntry( "groupfollowupmessages", true );
hideNotificationsWhenBusy_ = profileGroup.readEntry( "hideNotificationsWhenBusy", false );
hideNotificationsWhenBusy_ = profileGroup.readEntry( "hideNotificationsWhenBusy", true );
idleTime_ = profileGroup.readEntry( "idleTime", 5 );
initialStatus_ = (Status)profileGroup.readEntry( "initialStatus", (int) STATUS_ONLINE);
listPictureSize_ = profileGroup.readEntry( "listPictureSize", 0 );
@@ -938,6 +946,7 @@ void Account::saveTemporaryPassword()
if( ! temporaryPassword_.isEmpty() && temporaryPassword_ != password_ )
{
password_ = temporaryPassword_;
temporaryPassword_ = QString();
}
}
@@ -1003,8 +1012,18 @@ void Account::setAutoreplyMessage( const QString& autoreplyMessage)
* @brief Set chat information
*
* Set options related to chatting
* @param useChatFormatting whether to show MSN Plus formatting in chat
* @param shakeNudge whether the chat window should shake when a nudge is received or sent
* @param useContactFont whether or not the contact's font should be forced to some value.
* @param useEmoticons whether or not emoticons should be used.
* @param showWinks whether to show winks
* @param useFontEffects whether or not to use bold/italic/underline effects in chats.
* @param useChatFormatting whether to show MSN Plus formatting in chat.
* @param shakeNudge whether the chat window should shake when a nudge is received or sent.
* @param showMessageTime whether or not time information is shown for chat messages.
* @param timestampShowDate whether to show date in message timestamps.
* @param timestampShowSeconds whether to show seconds in message timestamps.
* @param groupFollowupMessages whether follow-up messages from the contact should be grouped.
* @param tabbedChatMode whether or not chats should be tabbed in one window.
* @param chatStyle the chat style to use.
*
*/
void Account::setChatInformation( bool useContactFont, bool useEmoticons, bool showWinks,
@@ -1038,6 +1057,7 @@ void Account::setAutoreplyMessage( const QString& autoreplyMessage)
useChatFormatting_ = useChatFormatting;
shakeNudge_ = shakeNudge;
showMessageTime_ = showMessageTime;
showWinks_ = showWinks;
timestampShowDate_ = timestampShowDate;
timestampShowSeconds_ = timestampShowSeconds;
groupFollowupMessages_ = groupFollowupMessages;
@@ -1392,11 +1412,25 @@ void Account::setOriginalPicturePath( const QString& picturePath )
// Set the account's saved password
void Account::setSavedPassword( const QString &password )
{
savedPassword_ = password;
}
// Set if the password must be stored
void Account::setSavePassword( bool savePassword )
{
savePassword_ = savePassword;
if( ! savePassword )
{
// Clear the password so the accountsmanager will remove it
password_.clear();
}
dirty_ = true;
#ifdef KMESSDEBUG_ACCOUNT_DIRTY
@@ -1589,7 +1623,7 @@ void Account::setStatusOptions( bool useIdleTimer, int idleTime, bool hideNotifi
idleTime_ = idleTime;
hideNotificationsWhenBusy_ = hideNotificationsWhenBusy;
emit changedViewMode();
emit changedTimerSettings();
dirty_ = true;
#ifdef KMESSDEBUG_ACCOUNT_DIRTY
@@ -1662,6 +1696,8 @@ void Account::setShowPicture( bool showPicture )
showPicture_ = showPicture;
dirty_ = true;
updateMsnObject();
#ifdef KMESSDEBUG_ACCOUNT_DIRTY
kDebug() << "Setting 'dirty' to true.";
#endif
@@ -1675,6 +1711,7 @@ void Account::updateMsnObject()
QString oldMsnString;
QString newMsnString;
// Remove the previous msn object if there is one
if( msnObject_ )
{
oldMsnString = msnObject_->objectString();
@@ -1702,7 +1739,7 @@ void Account::updateMsnObject()
QFile iFile( displayPicturePath_ );
if ( iFile.open( QIODevice::ReadOnly ) )
{
QByteArray data = iFile.readAll();
const QByteArray& data( iFile.readAll() );
iFile.close();
msnObject_ = new MsnObject( handle_, "KMess.tmp", "", MsnObject::DISPLAYPIC, data );
@@ -1715,7 +1752,7 @@ void Account::updateMsnObject()
}
// Detect if there was a change.
if(oldMsnString != newMsnString)
if( oldMsnString != newMsnString )
{
#ifdef KMESSDEBUG_ACCOUNT_MSNOBJECT
kDebug() << "result is: '" << newMsnString << "'";
+7 -1
View File
@@ -120,6 +120,8 @@ class Account : public QObject
const QString& getSaveChatPath() const;
// Return the code of the structure used to save chats.
const int& getSavedChatDirectoryStructure() const;
// Return the user's saved password
QString getSavedPassword() const;
// Read whether or not allowed contacts are shown.
bool getShowAllowedContacts() const;
// Read whether to show the user picture in chat windows
@@ -240,6 +242,8 @@ class Account : public QObject
void setPicturePath( const QString& picturePath );
// Save the location of the display picture original
void setOriginalPicturePath( const QString& picturePath );
// Set the account's saved password
void setSavedPassword( const QString &password );
// Set if the password must be stored
void setSavePassword( bool savePassword );
// Set whether or not allowed contacts are shown.
@@ -345,6 +349,8 @@ class Account : public QObject
int savedChatDirectoryStructure_;
// If the password must be stored
bool savePassword_;
// The password intially read from the store
QString savedPassword_;
// Whether the chat window shakes for nudges
bool shakeNudge_;
// Whether or not allowed contacts should be visible.
@@ -378,7 +384,7 @@ class Account : public QObject
bool showSessionInfo_;
// whether to show winks
bool showWinks_;
// The state of the tabbed chatting feature
// Whether or not chats should be tabbed in one window
int tabbedChatMode_;
// A temporary password for the account for login attempts from the initialview dialog
QString temporaryPassword_;
+210 -151
View File
@@ -45,7 +45,9 @@ AccountsManager* AccountsManager::instance_(0);
* Constructor
*/
AccountsManager::AccountsManager()
: passwordManager_( 0 )
: doPasswordRead_( false ),
doPasswordWrite_( false ),
passwordManager_( 0 )
{
// Load the saved accounts from disk and create them
readProperties();
@@ -246,7 +248,7 @@ const QList<Account *> AccountsManager::getAccounts() const
//Initialize the KWallet password manager
// Initialize the KWallet password manager
void AccountsManager::initializePasswordManager( bool block )
{
// Don't initialize if it is already
@@ -292,60 +294,221 @@ void AccountsManager::initializePasswordManager( bool block )
// Queue a read for all passwords
void AccountsManager::readPasswords( bool block )
{
doPasswordRead_ = true;
initializePasswordManager( block );
}
// Save passwords for all accounts (only actually saves when there are accounts to be updated!)
void AccountsManager::savePasswords( bool block )
{
bool passwordsToWrite = false;
// check if there are passwords to be written
foreach( const Account *account, accounts_ )
{
if( account->getSavedPassword() != account->getPassword() )
{
passwordsToWrite = true;
break;
}
}
if( passwordsToWrite )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "There were passwords to be updated, scheduling an update.";
#endif
doPasswordWrite_ = true;
initializePasswordManager( block );
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
else
{
kDebug() << "There were no passwords to be updated, skipping save request.";
}
#endif
}
// Read the passwords from the just opened wallet
void AccountsManager::slotWalletOpen( bool success )
{
KConfigGroup passwordGroup( KMessConfig::instance()->getGlobalConfig( "Passwords" ) );
QStringList passwordAccountList( passwordGroup.keyList() );
if( ! success || passwordManager_ == 0 )
// if the wallet couldn't be opened, delete it
if( ! success ||
( passwordManager_ != 0 && ! passwordManager_->isOpen() ) )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Wallet opening failed, falling back to plain text passwords.";
QStringList readPasswords;
#endif
// First delete the manager, as it won't be needed anymore
delete passwordManager_;
passwordManager_ = 0;
}
// Read the passwords from the KMess config file
foreach( const QString &accountHandle, passwordAccountList )
// initialize the wallet
if( passwordManager_ )
{
setupPasswordManager();
}
// Read the passwords
if( doPasswordRead_ )
{
if( passwordManager_ == 0 )
{
Account *account = getAccountByHandle( accountHandle );
// Skip passwords for invalid and deleted accounts, and remove them too
if( account == 0 )
{
passwordGroup.deleteEntry( accountHandle );
continue;
}
KConfigGroup passwordGroup( KMessConfig::instance()->getGlobalConfig( "Passwords" ) );
const QStringList& passwordAccountList( passwordGroup.keyList() );
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
readPasswords << accountHandle;
kDebug() << "Reading passwords from plain-text storage instead of KWallet!";
#endif
account->setPassword( passwordGroup.readEntry( accountHandle, QString() ) );
// Read the passwords from the KMess config file
foreach( const QString &accountHandle, passwordAccountList )
{
Account *account = getAccountByHandle( accountHandle );
// Skip passwords for invalid and deleted accounts, and remove them too
if( account == 0 )
{
passwordGroup.deleteEntry( accountHandle );
continue;
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Password have been read for account: " << accountHandle;
#endif
QString password = passwordGroup.readEntry( accountHandle, QString() );
account->setPassword( password );
account->setSavedPassword( password );
}
}
else // passwordManager_ != 0
{
QString password;
// Read the password for each account
foreach( Account *account, accounts_ )
{
if( passwordManager_->readPassword( account->getHandle(), password ) != 0 || password.isEmpty() )
{
continue;
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Password have been read for account: " << account->getHandle();
#endif
account->setPassword( password );
account->setSavedPassword( password );
}
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Passwords have been read for accounts" << readPasswords <<", emitting ready signal.";
#endif
emit passwordsReady();
return;
}
// Opening the wallet has failed, due to the user entering a wrong wallet password for example
if( ! passwordManager_->isOpen() )
// Write the passwords
if( doPasswordWrite_ )
{
if( passwordManager_ == 0 )
{
kWarning() << "KWallet is not available: saving passwords in plain text.";
KConfigGroup passwordGroup( KMessConfig::instance()->getGlobalConfig( "Passwords" ) );
// Store the password for each account
foreach( Account *account, accounts_ )
{
const QString& handle( account->getHandle() );
// If we have already the entry, check if the user want still save the password..
if( passwordGroup.hasKey( handle ) )
{
// If the password should not be saved, then delete any already saved password
if( account->getSavePassword() == false || account->getPassword().isEmpty() )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Opening KWallet failed!";
kDebug() << "Password for account" << handle << "removed.";
#endif
return;
account->setSavedPassword( "" );
passwordGroup.deleteEntry( handle );
continue;
}
}
// Save the password
account->setSavedPassword( account->getPassword() );
passwordGroup.writeEntry( handle, account->getPassword() );
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Password for account" << handle << "saved.";
#endif
}
}
else // passwordManager_ != 0
{
// Store the password for each account
foreach( Account *account, accounts_ )
{
const QString& handle( account->getHandle() );
bool savePassword = ( account->getSavePassword() && ! account->getPassword().isEmpty() );
if( passwordManager_->hasEntry( handle ) )
{
// If the password should not be saved, then delete any already saved password
if( savePassword == false )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Removing account" << handle << "from wallet";
#endif
account->setSavedPassword( "" );
passwordManager_->removeEntry( handle );
continue;
}
}
// Store the password only if it wasn't already
else if( savePassword == true && passwordManager_->writePassword( handle, account->getPassword() ) != 0 )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Couldn't store password for account" << handle;
#endif
}
account->setSavedPassword( account->getPassword() );
}
// Save the passwords to disk now
passwordManager_->sync();
}
}
doPasswordRead_ = false;
doPasswordWrite_ = false;
// Clean up the password manager, it's not needed anymore
// (not cleaning it up could result in weird issues if the program crashes or so)
delete passwordManager_;
passwordManager_ = 0;
}
// Set up the passwordManager_ (change to the KMess folder, import plaintext passwords, etc)
void AccountsManager::setupPasswordManager()
{
#ifdef KMESSTEST
KMESS_ASSERT( passwordManager_->isOpen() );
#endif
// Look for an existing kmess folder and create one if needed
if( ! passwordManager_->hasFolder( "KMess" ) )
{
@@ -358,14 +521,20 @@ void AccountsManager::slotWalletOpen( bool success )
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kWarning() << "Setting KWallet folder failed!";
#endif
delete passwordManager_;
passwordManager_ = 0;
return;
}
// Wallet is open: verify if the user has any useable plaintext password set.
// If so, ask if they should be deleted or copied to the wallet :)
KConfigGroup passwordGroup( KMessConfig::instance()->getGlobalConfig( "Passwords" ) );
const QStringList& passwordAccountList( passwordGroup.keyList() );
if( ! passwordAccountList.isEmpty() )
{
bool hasValidAccounts = false;
QStringList validAccounts;
foreach( const QString &accountHandle, passwordAccountList )
{
@@ -378,18 +547,20 @@ void AccountsManager::slotWalletOpen( bool success )
continue;
}
hasValidAccounts = true;
validAccounts << accountHandle;
}
// There are some accounts passwords. Ask the user
if( hasValidAccounts )
if( validAccounts.count() > 0 )
{
kWarning() << "Insecure account passwords found for accounts: " << validAccounts;
int res = KMessageBox::questionYesNoCancel( 0,
i18n( "<html>Some insecure account passwords have been found.<br />"
i18n( "<html>Some insecurely stored account passwords have been found.<br />"
"Do you want to import the passwords to the KDE Wallet "
"named '%1', keep the insecure passwords, or delete "
"named '%1', keep the insecurely stored passwords, or delete "
"them permanently?<br /><br />"
"<i>Note: it is not recommended to use insecure passwords "
"<i>Note: it is not recommended to keep insecurely stored passwords "
"if the KDE Wallet is available, because your passwords "
"will be easily readable in the KMess configuration files.</i></html>",
KWallet::Wallet::LocalWallet() ),
@@ -397,10 +568,10 @@ void AccountsManager::slotWalletOpen( bool success )
KGuiItem( i18nc( "Dialog button: Import passwords to a KDE wallet",
"Import" ),
"document-import" ), // Yes option
KGuiItem( i18nc( "Dialog button: Delete insecure passwords",
KGuiItem( i18nc( "Dialog button: Delete insecurely stored passwords",
"Delete" ),
"edit-delete-shred" ), // No option
KGuiItem( i18nc( "Dialog button: Keep insecure passwords",
KGuiItem( i18nc( "Dialog button: Keep insecurely stored passwords",
"Keep" ),
"mail-mark-notjunk" ), // Cancel option
"insecurePasswordsDetected" );
@@ -453,34 +624,8 @@ void AccountsManager::slotWalletOpen( bool success )
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "KWallet successfully opened, reading passwords.";
QStringList readPasswords;
kDebug() << "KWallet successfully opened.";
#endif
QString password;
// Read the password for each account
foreach( Account *account, accounts_ )
{
if( passwordManager_->readPassword( account->getHandle(), password ) != 0 || password.isEmpty() )
{
continue;
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
readPasswords << account->getHandle();
#endif
account->setPassword( password );
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Passwords have been read for accounts" << readPasswords <<", emitting ready signal.";
#endif
emit passwordsReady();
return;
}
@@ -574,90 +719,4 @@ void AccountsManager::showAccountSettings( Account *account, QWidget *parentWind
// Store the password of all accounts to the user's KWallet
void AccountsManager::storeAccountsPasswords()
{
QString handle;
bool savePassword;
if( passwordManager_ == 0 )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "KWallet is not available: saving passwords in plain text.";
#endif
KConfigGroup passwordGroup( KMessConfig::instance()->getGlobalConfig( "Passwords" ) );
// Store the password for each account
foreach( const Account *account, accounts_ )
{
handle = account->getHandle();
if( passwordGroup.hasKey( handle ) )
{
// If the password should not be saved, then delete any already saved password
if( account->getSavePassword() == false || account->getPassword().isEmpty() )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Password for account" << handle << "removed";
#endif
passwordGroup.deleteEntry( handle );
continue;
}
}
else
{
// Save the password only if it wasn't already
passwordGroup.writeEntry( handle, account->getPassword() );
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Password for account" << handle << "saved.";
#endif
}
}
return;
}
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
else
{
kDebug() << "KWallet is available: saving passwords in the user wallet.";
}
#endif
// Store the password for each account
foreach( Account *account, accounts_ )
{
handle = account->getHandle();
savePassword = ( account->getSavePassword() && ! account->getPassword().isEmpty() );
if( passwordManager_->hasEntry( handle ) )
{
// If the password should not be saved, then delete any already saved password
if( savePassword == false )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Removing account" << handle << "from wallet";
#endif
passwordManager_->removeEntry( handle );
continue;
}
}
// Store the password only if it wasn't already
else if( savePassword == true && passwordManager_->writePassword( handle, account->getPassword() ) != 0 )
{
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
kDebug() << "Couldn't store password for account" << handle;
#endif
}
}
// Save the passwords to disk now
passwordManager_->sync();
}
#include "accountsmanager.moc"
+13 -4
View File
@@ -47,15 +47,18 @@ class AccountsManager : public QObject
Account * getAccountByHandle( const QString &handle );
// Get the list of all saved accounts
const QList<Account *> getAccounts() const;
// Initialize the KWallet password manager
void initializePasswordManager( bool block = false );
// Load the accounts from disk
void readProperties();
// Warning: If a passwordManager_ is already being initialized with block=false and a
// second request comes in with block=true, the second request will *not* block (but it will be
// handled later!) - this doesn't happen in kmess as of now, I'm just including this here in case.
// Read passwords for all accounts
void readPasswords( bool block = false );
// Save passwords for all accounts (only actually saves when there are accounts to be updated!)
void savePasswords( bool block = false );
// Show the settings dialog for a given account
void showAccountSettings( Account *account = 0, QWidget *parentWindow = 0,
AccountSettingsDialog::Page startingPage = AccountSettingsDialog::PageAccount );
// Store the password of all accounts to the user's KWallet
void storeAccountsPasswords();
public slots:
@@ -82,6 +85,10 @@ class AccountsManager : public QObject
AccountsManager();
// Destructor
~AccountsManager();
// Initialize the KWallet password manager
void initializePasswordManager( bool block = false );
// Set up the passwordManager_ after initialization
void setupPasswordManager();
private slots:
@@ -94,6 +101,8 @@ class AccountsManager : public QObject
// A list of user accounts
QList<Account*> accounts_;
bool doPasswordRead_;
bool doPasswordWrite_;
private: // Private static members
+253 -150
View File
@@ -17,20 +17,13 @@
#include "chat.h"
#include "../contact/contact.h"
#include "../contact/contactextension.h"
#include "../contact/contactbase.h"
#include "../contact/invitedcontact.h"
#include "../contact/msnstatus.h"
#include "../contact/msnobject.h"
#include "../model/contactlist.h"
#include "../network/chatinformation.h"
#include "../network/chatmessage.h"
#include "../network/msnswitchboardconnection.h"
#include "../utils/kmessconfig.h"
#include "../utils/kmessshared.h"
#include "../utils/richtextparser.h"
#include "../utils/xmlfunctions.h"
#include "../accountaction.h"
#include "../currentaccount.h"
#include "../kmessapplication.h"
#include "../kmessdebug.h"
@@ -42,7 +35,6 @@
#include <QDir>
#include <QFile>
#include <QRegExp>
#include <QTextDocument>
#include <KFileDialog>
#include <KIO/NetAccess>
@@ -70,6 +62,7 @@ Chat::Chat( QWidget *parent )
// Setup the contact typing information timer
typingTimer_.setSingleShot( true );
connect( &typingTimer_, SIGNAL( timeout() ),
this, SLOT ( contactTyping() ) );
}
@@ -87,7 +80,7 @@ Chat::~Chat()
// Choose the contact to start an invitation with.
QString Chat::chooseContact()
const QString Chat::chooseContact()
{
if( KMESS_NULL(msnSwitchboardConnection_) ) return QString();
@@ -116,8 +109,8 @@ QString Chat::chooseContact()
// Multiple contacts in the chat.
// TODO: The official client opens a contact-choose dialog here, and starts a new chat with the selected contact.
KMessageBox::sorry( this, i18nc( "Error dialog box text",
"You can't send invitations when there are multiple contacts in a chat. "
"Please open a chat screen with the recipient, then re-send your invitation." ) );
"You cannot send invitations when there are multiple contacts in a chat. "
"Please start a separate chat with the contact you wanted to send the invitation to." ) );
return QString();
}
}
@@ -125,21 +118,22 @@ QString Chat::chooseContact()
// A contact joined the chat
void Chat::contactJoined( ContactBase* contact )
void Chat::contactJoined( ContactBase* contact, bool offlineContact )
{
QString handle ( contact->getHandle() );
QString friendlyName( contact->getFriendlyName( STRING_CLEANED_ESCAPED ) );
const QStringList &participants( getParticipants() );
// Don't replace the bool offlineContact with contact->isOffline(), because there may be
// real chats with invisible contacts
const QString& handle ( contact->getHandle() );
const QString& friendlyName( contact->getFriendlyName( STRING_CLEANED_ESCAPED ) );
const QStringList &participants( getParticipants() );
// Show message when the user has the contacts widget disabled,
// or when a multi-chat has started.
if( ( ! contactsWidget_->isVisible() && currentAccount_->getShowSessionInfo() )
|| ( participants.count() > 1 ) )
// Don't show the message when the contact went/is offline (because in such cases, the message
// is unreliable, and if we started the chat we're just pretending the contact joined)
if( ! offlineContact && ( currentAccount_->getShowSessionInfo() || participants.count() > 1 ) )
{
showMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_JOINED,
showMessage( ChatMessage( ChatMessage::TYPE_PRESENCE,
ChatMessage::CONTENT_PRESENCE_JOIN,
false,
i18n("<html>%1 has joined the chat.</html>", friendlyName ),
i18n("%1 has joined the chat.", friendlyName ),
handle,
friendlyName ) );
}
@@ -167,7 +161,7 @@ void Chat::contactJoined( ContactBase* contact )
// A contact left the chat
void Chat::contactLeft( ContactBase *contact, bool isChatIdle )
{
QString handle ( contact->getHandle() );
const QString& handle ( contact->getHandle() );
const QStringList &participants( getParticipants() );
#ifdef KMESSDEBUG_CHAT_GENERAL
@@ -182,29 +176,28 @@ void Chat::contactLeft( ContactBase *contact, bool isChatIdle )
disconnect( contact, 0, this, 0 );
}
// Show message when the user has the contacts widget hidden,
// or a user left a multi-chat
if( ( ! contactsWidget_->isVisible() && currentAccount_->getShowSessionInfo() )
|| ( participants.count() > 1 ) )
// Always show a message when this is a group chat,
// but never if it would be the first message.
if( ! firstMessage_ && ( currentAccount_->getShowSessionInfo() || participants.count() > 1 ) )
{
QString contactName( contact->getFriendlyName( STRING_CLEANED_ESCAPED ) );
const QString& contactName( contact->getFriendlyName( STRING_CLEANED_ESCAPED ) );
QString message;
if( isChatIdle )
{
message = i18nc( "Message shown in chat, %1 is the contact's friendly name",
"<html>The chat went idle, %1 has left the chat.</html>",
"The chat went idle, %1 has left it.",
contactName );
}
else
{
message = i18nc( "Message shown in chat, %1 is the contact's friendly name",
"<html>%1 has left the chat.</html>",
"%1 has left the chat.",
contactName );
}
showMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_LEFT,
showMessage( ChatMessage( ChatMessage::TYPE_PRESENCE,
ChatMessage::CONTENT_PRESENCE_LEAVE,
false,
message,
handle,
@@ -277,7 +270,7 @@ void Chat::contactTyping( ContactBase *contact, bool forceExpiration )
}
// Update the list to remove expired typing events
QMutableMapIterator<QString,QTime> it( typingContactsTimes_ );
QMutableHashIterator<QString,QTime> it( typingContactsTimes_ );
while( it.hasNext() )
{
it.next();
@@ -341,40 +334,41 @@ void Chat::contactTyping( ContactBase *contact, bool forceExpiration )
// Return a list of the contacts in the chat to be used as window caption
QString Chat::getCaption()
const QString Chat::getCaption()
{
// When there's no SB, we can't retrieve the contact names
if( msnSwitchboardConnection_ == 0 )
{
return QString();
}
// Grep the current participants or the last participant
const QStringList &participants( getParticipants() );
QString caption;
// How many people are there in here?
switch( participants.count() )
{
// The chat is completely empty - it is not even a chat!
case 0:
return QString();
break;
// One contact is connected; or the only contact of the session has left
case 1:
return currentAccount_->getContactFriendlyNameByHandle( participants[0], STRING_CLEANED );
caption = currentAccount_->getContactFriendlyNameByHandle( participants[0], STRING_CLEANED );
break;
// Two contacts are connected
case 2:
return i18nc( "Name of a chat tab", "%1 and %2",
currentAccount_->getContactFriendlyNameByHandle( participants[0], STRING_CLEANED ),
currentAccount_->getContactFriendlyNameByHandle( participants[1], STRING_CLEANED )
);
caption = i18nc( "Name of a chat tab", "%1 and %2",
currentAccount_->getContactFriendlyNameByHandle( participants[0], STRING_CLEANED ),
currentAccount_->getContactFriendlyNameByHandle( participants[1], STRING_CLEANED )
);
break;
// Three or more contacts are connected
default:
return i18nc( "Name of a chat tab", "%1 et al.",
currentAccount_->getContactFriendlyNameByHandle( participants[0], STRING_CLEANED )
);
caption = i18nc( "Name of a chat tab", "%1 et al.",
currentAccount_->getContactFriendlyNameByHandle( participants[0], STRING_CLEANED )
);
}
// Replace the 'return chars' with 'space chars'
return caption.replace( "\n", " " );
}
@@ -388,7 +382,7 @@ ChatWindow *Chat::getChatWindow()
// Return the list of contacts in the chat
QStringList Chat::getParticipants()
const QStringList Chat::getParticipants() const
{
if( msnSwitchboardConnection_ == 0 )
{
@@ -412,7 +406,7 @@ KIcon Chat::getParticipantsTabIcon()
}
// Else use the status icon of the current contact
QString handle( participants.first() );
const QString& handle( participants.first() );
// Find the contact, if it isn't in the contact list, use the "unknown" tab icon
const ContactBase *contact = currentAccount_->getContactByHandle( handle );
@@ -426,8 +420,16 @@ KIcon Chat::getParticipantsTabIcon()
// Return the list of previously sent messages
QStringList& Chat::getQuickRetypeList()
{
return quickRetypeList_;
}
// Return the list of contacts which are typing
QStringList Chat::getTypingContacts()
const QStringList Chat::getTypingContacts() const
{
return typingContactsNames_.values();
}
@@ -543,10 +545,8 @@ bool Chat::isContactInChat( const QString &handle, bool isExclusiveChatWithConta
return false;
}
bool check = false;
// Check if the contact is one of the participants to this chat.
check = participants.contains( handle );
bool check = participants.contains( handle );
// Check if is exclusive chat with the contact passed as the argument
if( check && isExclusiveChatWithContact )
@@ -632,11 +632,8 @@ void Chat::receivedMessage(const ChatMessage &message)
showMessage( message );
// Do not notify about some message content classes
ChatMessage::ContentsClass contents = message.getContentsClass();
if( contents == ChatMessage::CONTENT_NOTIFICATION_STATUS
|| contents == ChatMessage::CONTENT_NOTIFICATION_LEFT
|| contents == ChatMessage::CONTENT_NOTIFICATION_JOINED )
// Do not notify about presence messages
if( message.getType() == ChatMessage::TYPE_PRESENCE )
{
return;
}
@@ -778,9 +775,9 @@ void Chat::saveChatAutomatically( bool saveExternalFile )
break;
}
QString year ( startDate_.toString( "yyyy" ) );
QString month( startDate_.toString( "MM" ) );
QString day ( startDate_.toString( "dd" ) );
const QString& year ( startDate_.toString( "yyyy" ) );
const QString& month( startDate_.toString( "MM" ) );
const QString& day ( startDate_.toString( "dd" ) );
// Determine the path where to save the log file
switch( currentAccount_->getSavedChatDirectoryStructure() )
@@ -828,7 +825,7 @@ void Chat::saveChatAutomatically( bool saveExternalFile )
{
KMessageBox::sorry( getChatWindow(),
i18n( "<html>KMess could not save the log for this chat:<br />"
"The chat logs directory, '%1', does not exist.</html>",
"The chat logs directory, &quot;%1&quot;, does not exist.</html>",
dir.absolutePath() ) );
}
// TODO: show a KDE save file dialog
@@ -931,15 +928,37 @@ void Chat::sendTypingMessage()
// Send an wink to the current chat
void Chat::sendWink( const QString &message )
void Chat::sendWink( const MsnObject &msnObject )
{
msnSwitchboardConnection_->sendWink( message );
// TODO show the sended wink on the chat
receivedMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_WINK,
true,
i18n( "<html>You have sent a wink</html>" ),
"" ) );
QString winkHtml;
msnSwitchboardConnection_->sendWink( msnObject );
// Only show the sent wink if they're enabled
if( currentAccount_->getShowWinks() )
{
WinksWidget::getHtmlFromWink( msnObject.getLocation(), winkHtml );
}
// If the stored wink didn't have a name, don't show it:
QString notificationText;
if( msnObject.getFriendly().isEmpty() )
{
notificationText = i18nc( "Message shown in the chat window (when the wink name is unknown)",
"You have sent a wink!" );
}
else
{
notificationText = i18nc( "Message shown in the chat window, %1 is the wink name",
"You have sent the &quot;%1&quot; wink!",
msnObject.getFriendly() );
}
ChatMessage message( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_WINK,
false,
notificationText + winkHtml, // Add the actual wink after the message
QString() );
showMessage( message );
}
@@ -963,7 +982,7 @@ void Chat::setEnabled( bool isEnabled )
if( ! isEnabled )
{
getChatWindow()->showStatusMessage( ChatStatusBar::Disconnected, i18n("The chat has been disabled because you are no longer connected to the MSN server." ));
getChatWindow()->showStatusMessage( ChatStatusBar::Disconnected, i18n("The chat has been disabled because you are no longer connected to the Live Messenger server." ));
}
else
{
@@ -978,6 +997,12 @@ void Chat::setEnabled( bool isEnabled )
}
ChatView::setEnabled( isEnabled );
if ( isEnabled )
{
getChatWindow()->setUIState( ChatWindow::Connected );
}
}
@@ -1085,6 +1110,7 @@ void Chat::setSwitchboardConnection( MsnSwitchboardConnection *newConnection )
contact = currentAccount_->addInvitedContact( handle );
}
contactJoined( contact, true /* don't notify about the join */ );
contactsWidget_->contactJoined( contact );
}
}
@@ -1113,7 +1139,7 @@ void Chat::showWarning( MsnSwitchboardConnection::WarningType type, ContactBase
ChatMessage::CONTENT_SYSTEM_ERROR,
true,
i18nc( "Warning message shown in chat",
"<html>There has been a connection problem.</html>" ),
"There has been a connection problem." ),
handle,
friendlyName ) );
break;
@@ -1123,7 +1149,7 @@ void Chat::showWarning( MsnSwitchboardConnection::WarningType type, ContactBase
ChatMessage::CONTENT_SYSTEM_ERROR,
true,
i18nc( "Warning message shown in chat",
"<html>There were too many different custom emoticons in your last message. Only the first 7 will be sent.</html>" ),
"There were too many different custom emoticons in your last message. Only the first 7 will be sent." ),
handle,
friendlyName ) );
break;
@@ -1136,7 +1162,7 @@ void Chat::showWarning( MsnSwitchboardConnection::WarningType type, ContactBase
ChatMessage::CONTENT_SYSTEM_ERROR,
true,
i18nc( "Warning message shown in chat, %1 is the contact's friendly name",
"<html>%1 has sent you a voice clip, but KMess does not support voice clips yet, so you can't listen to it now.</html>",
"%1 has sent you a voice clip, but KMess does not support voice clips yet.",
friendlyName ),
handle,
friendlyName ) );
@@ -1150,7 +1176,7 @@ void Chat::showWarning( MsnSwitchboardConnection::WarningType type, ContactBase
ChatMessage::CONTENT_SYSTEM_ERROR,
true,
i18nc( "Warning message shown in chat, %1 is the contact's friendly name",
"<html>%1 has sent you an action message, but KMess does not support action messages yet.</html>",
"%1 has sent you an action message, but KMess does not support action messages yet.",
friendlyName ),
handle,
friendlyName ) );
@@ -1165,7 +1191,7 @@ void Chat::showWarning( MsnSwitchboardConnection::WarningType type, ContactBase
ChatMessage::CONTENT_SYSTEM_ERROR,
true,
i18nc( "Warning message shown in chat, %1 is the contact's friendly name",
"<html>%1 has sent you an MSN feature that KMess does not support yet.</html>",
"%1 has sent you a Live Messenger feature that KMess does not support yet.",
friendlyName ),
handle,
friendlyName ) );
@@ -1176,23 +1202,42 @@ void Chat::showWarning( MsnSwitchboardConnection::WarningType type, ContactBase
// Show a wink received by a contact
void Chat::showWink( const QString &handle, const QString &filename, const QString &/*animationName*/ )
void Chat::showWink( const QString &handle, const QString &filename, const QString &animationName )
{
#ifdef KMESSDEBUG_CHAT_GENERAL
kDebug() << "Processing received wink data.";
#endif
QString message;
const QString& friendlyName( currentAccount_->getContactFriendlyNameByHandle( handle, STRING_CLEANED_ESCAPED ) );
// If we aren't showing winks, notify the user that we got one but don't actually display the animation.
if( ! currentAccount_->getShowWinks() )
{
showMessage( ChatMessage( ChatMessage::TYPE_SYSTEM,
ChatMessage::CONTENT_SYSTEM_ERROR,
if( animationName.isEmpty() )
{
message = i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"You received a wink from %1, but displaying "
"winks has been disabled. "
"You can re-enable it in the <a href='kmess://accountconfig'>"
"account settings</a>.",
friendlyName );
}
else
{
message = i18nc( "Message shown in the chat window, %1 is the contact's "
"friendly name, %2 is the wink name",
"You received the &quot;%2&quot; wink from %1, but displaying "
"winks has been disabled. "
"You can re-enable it in the <a href='kmess://accountconfig'>"
"account settings</a>.",
friendlyName,
animationName );
}
showMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_WINK,
false,
i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"<html>You received a wink from %1, but displaying winks has been disabled in the account options. "
"You can re-enable them in the <a href='kmess://accountconfig'>account configuration</a>.</html>", friendlyName ),
message,
handle ) );
return;
}
@@ -1207,52 +1252,105 @@ void Chat::showWink( const QString &handle, const QString &filename, const QStri
QString html;
WinksWidget::CABEXTRACTOR value = WinksWidget::getHtmlFromWink( filename, html );
switch( value )
if( value == WinksWidget::SUCCESS )
{
case WinksWidget::SUCCESS:
break;
if( animationName.isEmpty() )
{
message = i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"%1 has sent you a wink!",
friendlyName );
}
else
{
message = i18nc( "Message shown in the chat window, %1 is the contact's "
"friendly name, %2 is the wink name",
"%1 has sent you a wink: &quot;%2&quot;!",
friendlyName,
animationName );
}
case WinksWidget::NOTINSTALLED:
showMessage( ChatMessage( ChatMessage::TYPE_SYSTEM,
ChatMessage::CONTENT_SYSTEM_ERROR,
false,
i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"<html>You received a wink from %1, but it could not be displayed. Make sure you have"
" the 'cabextract' program installed. Check your distributions package manager for more help.</html>", friendlyName ),
handle ) );
return;
case WinksWidget::FAILED:
showMessage( ChatMessage( ChatMessage::TYPE_SYSTEM,
ChatMessage::CONTENT_SYSTEM_ERROR,
false,
i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"<html>You received a wink from %1, but it could not be displayed, because extracting the wink"
" package with 'cabextract' failed.</html>", friendlyName ),
handle ) );
return;
case WinksWidget::UNKNOW:
default:
showMessage( ChatMessage( ChatMessage::TYPE_SYSTEM,
ChatMessage::CONTENT_SYSTEM_ERROR,
false,
i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"<html>You received a wink from %1, but it could not be displayed. The data could not be"
" read.</html>", friendlyName ),
handle ) );
return;
// Show a notification
receivedMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_WINK,
true,
message + html,
handle,
friendlyName ) );
return;
}
// Show a notification
receivedMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_WINK,
true,
i18n( "<html>%1 has sent you a wink!</html>", friendlyName ) + html,
handle,
friendlyName ) );
// TODO: include contact meta data in ChatMessage() constructor to show wink nicer
// Extraction failed
switch( value )
{
case WinksWidget::NOTINSTALLED:
if( animationName.isEmpty() )
{
message = i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"You received a wink from %1, but it "
"could not be displayed. Make sure you have "
"the &quot;cabextract&quot; program installed.",
friendlyName );
}
else
{
message = i18nc( "Message shown in the chat window, %1 is the contact's "
"friendly name, %2 is the wink name",
"You received the &quot;%2&quot; wink from %1, but it "
"could not be displayed. Make sure you have "
"the &quot;cabextract&quot; program installed.",
friendlyName,
animationName );
}
break;
case WinksWidget::FAILED:
if( animationName.isEmpty() )
{
message = i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"You received a wink from %1, but it "
"could not be displayed. Extracting the wink "
"package with &quot;cabextract&quot; has failed.",
friendlyName );
}
else
{
message = i18nc( "Message shown in the chat window, %1 is the contact's "
"friendly name, %2 is the wink name",
"You received the &quot;%2&quot; wink from %1, but it "
"could not be displayed. Extracting the wink "
"package with &quot;cabextract&quot; has failed.",
friendlyName,
animationName );
}
break;
default:
if( animationName.isEmpty() )
{
message = i18nc( "Message shown in the chat window, %1 is the contact's friendly name",
"You received a wink from %1, but it "
"could not be displayed. The data could not be "
"read.",
friendlyName );
}
else
{
message = i18nc( "Message shown in the chat window, %1 is the contact's "
"friendly name, %2 is the wink name",
"You received the &quot;%2&quot; wink from %1, but it "
"could not be displayed. The data could not be "
"read.",
friendlyName,
animationName );
}
break;
}
showMessage( ChatMessage( ChatMessage::TYPE_SYSTEM,
ChatMessage::CONTENT_SYSTEM_ERROR,
false,
message,
handle ) );
}
@@ -1281,12 +1379,12 @@ void Chat::slotContactChangedStatus()
// Show a different one depending if this is an exclusive chat (which means we send offline IMs)
if( getParticipants().size() == 1 )
{
message = i18n( "<html>%1 has gone offline. Any messages you send will be delivered the next time he or she signs in.</html>",
message = i18n( "%1 has gone offline. Any messages you send will be delivered the next time he or she logs in.",
friendlyName );
}
else if( currentAccount_->getShowSessionInfo() )
{
message = i18n( "<html>%1 has gone offline.</html>",
message = i18n( "%1 has gone offline.",
friendlyName );
}
else
@@ -1296,7 +1394,7 @@ void Chat::slotContactChangedStatus()
}
else if( currentAccount_->getShowSessionInfo() )
{
message = i18n( "<html>%1 has changed his or her status to \"%2\"</html>",
message = i18n( "%1 has changed his or her status to &quot;%2&quot;.",
friendlyName,
MsnStatus::getName( contact->getStatus() ) );
}
@@ -1305,8 +1403,8 @@ void Chat::slotContactChangedStatus()
return;
}
receivedMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_STATUS,
receivedMessage( ChatMessage( ChatMessage::TYPE_PRESENCE,
ChatMessage::CONTENT_PRESENCE_STATUS,
true,
message,
contact->getHandle() ) );
@@ -1322,12 +1420,12 @@ void Chat::slotReceivedNudge( ContactBase *contact )
#endif
// Get friendly name
QString friendlyName( contact->getFriendlyName( STRING_CLEANED_ESCAPED ) );
const QString& friendlyName( contact->getFriendlyName( STRING_CLEANED_ESCAPED ) );
ChatMessage message( ChatMessage::TYPE_NOTIFICATION,
ChatMessage::CONTENT_NOTIFICATION_NUDGE,
true,
i18n( "<html>%1 has sent you a nudge!</html>", friendlyName ),
i18n( "%1 has sent you a nudge!", friendlyName ),
contact->getHandle(),
friendlyName );
@@ -1346,9 +1444,9 @@ void Chat::slotReceivedNudge( ContactBase *contact )
// Signal that a message could not be sent to the switchboard
void Chat::slotSendingFailed( const QString &handle, const MimeMessage &message )
{
const QString& contentType( message.getValue( "Content-Type" ) );
QString errorMessage;
QString friendlyName;
QString contentType( message.getValue( "Content-Type" ) );
#ifdef KMESSDEBUG_CHAT_GENERAL
kDebug() << "Showing a sending failure notice.";
@@ -1373,12 +1471,12 @@ void Chat::slotSendingFailed( const QString &handle, const MimeMessage &message
{
case 1: // Nudge
errorMessage = i18nc( "Error message shown in chat, %1 is the contact's friendly name",
"<html>Failed to send the nudge to %1.</html>",
"Failed to send the nudge to %1.",
friendlyName );
break;
case 2: // Wink
errorMessage = i18nc( "Error message shown in chat, %1 is the contact's friendly name",
"<html>Failed to send the wink to %1..</html>",
"Failed to send the wink to %1.",
friendlyName );
break;
default: // Unsupported datacast?!
@@ -1386,9 +1484,9 @@ void Chat::slotSendingFailed( const QString &handle, const MimeMessage &message
return;
}
}
else if( contentType.startsWith( "image/gif" ) )
else if( contentType.startsWith( "image/gif" ) || contentType.startsWith( "application/x-ms-ink" ) )
{
errorMessage = i18nc( "Error message shown in chat, %1 is the contact's friendly name", "<html>Failed to send the drawing to %1.</html>",
errorMessage = i18nc( "Error message shown in chat, %1 is the contact's friendly name", "Failed to send the handwritten message to %1.",
friendlyName );
}
else if( contentType.startsWith( "text/plain" ) && ! message.getBody().isEmpty() )
@@ -1403,7 +1501,7 @@ void Chat::slotSendingFailed( const QString &handle, const MimeMessage &message
}
errorMessage = i18nc( "Error message shown in chat, %1 is the sent message, %2 is the contact's friendly name",
"<html>Failed to send the message to %2:<br/>%1</html>",
"Failed to send the message to %2:<br/>%1",
body,
friendlyName );
}
@@ -1431,7 +1529,7 @@ void Chat::startFileTransfer( QList<QUrl> fileList )
if( KMESS_NULL(msnSwitchboardConnection_) ) return;
// Ask for a contact
QString handle( chooseContact() );
const QString& handle( chooseContact() );
// If no contact can be chosen, stop
if( handle.isEmpty() )
@@ -1486,8 +1584,8 @@ void Chat::startFileTransfer( QList<QUrl> fileList )
showMessage( ChatMessage( ChatMessage::TYPE_SYSTEM,
ChatMessage::CONTENT_APP_FAILED,
false,
i18n( "<html>The file '%1' could not be found on "
"your computer, and the download failed.</html>",
i18n( "The file &quot;%1&quot; could not be found on "
"your computer, and the download failed.",
localFileUrl.prettyUrl() ),
handle ) );
continue;
@@ -1523,13 +1621,13 @@ void Chat::slotSendNudge()
if( contactsInChat.count() == 1 && msnSwitchboardConnection_->isConnected() )
{
messageText = i18nc( "Message shown in chat window, %1 is the contact's friendly name",
"You've sent a nudge to %1!",
"You have sent a nudge to %1!",
currentAccount_->getContactFriendlyNameByHandle( contactsInChat.first(), STRING_CLEANED_ESCAPED ) );
}
else
{
// Chat is either empty (should resume), or a multi-chat
messageText = i18n( "You've sent a nudge!" );
messageText = i18n( "You have sent a nudge!" );
}
// Display message
@@ -1587,10 +1685,15 @@ void Chat::startChat()
ContactBase *contact = currentAccount_->getContactByHandle( getParticipants().first() );
if( contact && contact->isOffline() )
{
receivedMessage( ChatMessage( ChatMessage::TYPE_NOTIFICATION,
#ifdef KMESSDEBUG_CHAT_GENERAL
kDebug() << "Initial chat participant " << contact->getHandle() << " is offline; pretending the contact joined";
#endif
contactJoined( contact, true );
receivedMessage( ChatMessage( ChatMessage::TYPE_PRESENCE,
ChatMessage::CONTENT_SYSTEM_NOTICE,
false,
i18n( "<html>%1 is currently offline. Any messages you send will be delivered the next time he or she signs in.</html>",
i18n( "%1 is currently offline. Any messages you send will be delivered the next time he or she logs in.",
contact->getFriendlyName( STRING_CLEANED_ESCAPED ) ),
contact->getHandle() ) );
}
@@ -1620,7 +1723,7 @@ void Chat::startConversation()
void Chat::startMeeting()
{
// Choose the contact.
QString handle( chooseContact() );
const QString& handle( chooseContact() );
if( KMESS_NULL(msnSwitchboardConnection_) )
{
@@ -1639,7 +1742,7 @@ void Chat::startMeeting()
void Chat::startWebcamTransfer()
{
// Choose the contact.
QString handle( chooseContact() );
const QString& handle( chooseContact() );
if( KMESS_NULL(msnSwitchboardConnection_) )
{
+14 -12
View File
@@ -18,12 +18,10 @@
#ifndef CHAT_H
#define CHAT_H
#include "../contact/contactbase.h"
#include "chatview.h"
#include "../network/msnswitchboardconnection.h"
#include <QList>
#include <QMap>
#include <QHash>
#include <QStringList>
#include <QTimer>
@@ -73,17 +71,19 @@ class Chat : public ChatView
// The destructor
~Chat();
// Return a list of the contacts in the chat to be used as window caption
QString getCaption();
const QString getCaption();
// Return the chat window which currently contains this Chat
ChatWindow *getChatWindow();
// Return the list of contacts in the chat
QStringList getParticipants();
const QStringList getParticipants() const;
// Return the icon to use in the tab icon chat
KIcon getParticipantsTabIcon();
// Return the list of previously sent messages
QStringList &getQuickRetypeList();
// Return the date and time the chat has started
QDateTime getStartTime() const;
// Return the list of contacts which are typing
QStringList getTypingContacts();
const QStringList getTypingContacts() const;
// Initialize the object
bool initialize( MsnSwitchboardConnection *switchboardConnection );
// Return the switchboard connection used by the chat window.
@@ -105,7 +105,7 @@ class Chat : public ChatView
// Send an "user is typing" message to the contacts
void sendTypingMessage();
// Send an wink to the current chat
void sendWink( const QString &message );
void sendWink( const MsnObject &message );
// The user wants to block or unblock a contact.
void setContactBlocked( QString handle, bool isBlocked );
// Enable or disable the parts of the window which allow user interaction
@@ -133,13 +133,13 @@ class Chat : public ChatView
private: // Private methods
// Choose the contact to start an invitation with.
QString chooseContact();
// Save the chat if needed
const QString chooseContact();
// save the chat if needed.
void saveChatAutomatically( bool saveExternalFile = false );
private slots: // Private slots
// A contact joined the chat
void contactJoined( ContactBase *contact );
void contactJoined( ContactBase *contact, bool offlineContact = false );
// A contact left the chat
void contactLeft ( ContactBase *contact, bool isChatIdle );
// A contact is typing
@@ -164,13 +164,15 @@ class Chat : public ChatView
QTime lastSentAutoMessage_;
// The object that connects to the switchboard server.
MsnSwitchboardConnection *msnSwitchboardConnection_;
// List of previously sent messages, to allow sending them again quickly
QStringList quickRetypeList_;
// The date/time the chat started
QDate startDate_;
QTime startTime_;
// The list of names of contacts which are currently typing
QMap<QString,QString> typingContactsNames_;
QHash<QString,QString> typingContactsNames_;
// The list of times when the contacts have started typing
QMap<QString,QTime> typingContactsTimes_;
QHash<QString,QTime> typingContactsTimes_;
// A timer to update the typing information
QTimer typingTimer_;
// Handle a command from ChatView (e.g. '/online')
+108 -59
View File
@@ -46,6 +46,9 @@
#include <KWindowSystem>
#ifdef Q_WS_X11
# include <QX11Info>
#endif
// Settings for debugging
#define CHATMASTER_SEND_FILES_MSNFTP 0
@@ -133,9 +136,8 @@ void ChatMaster::connected()
if( participants.count() > 1 )
{
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "This is a group chat, closing it.";
kDebug() << "This is a group chat, skipping it.";
#endif
chat->getChatWindow()->removeChatTab( chat );
continue;
}
@@ -203,6 +205,20 @@ void ChatMaster::disconnected()
}
}
// close down all switchboards first.
if( ! switchboardConnections_.isEmpty() )
{
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Closing" << switchboardConnections_.count() << "open switchboards.";
#endif
// give each switchboard a chance to close properly.
foreach( MsnSwitchboardConnection *conn, switchboardConnections_ )
{
conn->closeConnection();
}
}
if( ! chats_.isEmpty() )
{
#ifdef KMESSDEBUG_CHATMASTER
@@ -216,16 +232,9 @@ void ChatMaster::disconnected()
}
}
if( ! switchboardConnections_.isEmpty() )
{
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Closing" << switchboardConnections_.count() << "open switchboards.";
#endif
// Cleanup switchboard connections.
qDeleteAll( switchboardConnections_ );
switchboardConnections_.clear();
}
// Cleanup switchboard connections.
qDeleteAll( switchboardConnections_ );
switchboardConnections_.clear();
}
@@ -569,7 +578,7 @@ void ChatMaster::requestChat( QString handle )
return;
}
// Append the requested chat with handle to the list
// Append the requested chat with handle to the list
// So when the chat will be created it will be raised
requestedChats_.append( handle );
emit requestSwitchboard( handle, connectionType );
@@ -703,8 +712,6 @@ void ChatMaster::raiseChat( Chat *chat, bool force )
return;
}
// Making windows raise and get focus interrupts the user... it's better to make them appear minimized,
// and let them just flash in the taskbar.
if( chatWindow->isVisible() && ! force )
{
#ifdef KMESSDEBUG_CHATMASTER
@@ -714,11 +721,14 @@ void ChatMaster::raiseChat( Chat *chat, bool force )
}
// Move the window on the current desktop if it wasn't shown before or if we're forcing its raise
// TODO: make this optional, maybe the user doesn't want the windows to span over desktops
if( ! chatWindow->isVisible() || force )
{
KWindowSystem::setOnDesktop( chatWindow->winId(), KWindowSystem::currentDesktop() );
}
// Making windows raise and get focus interrupts the user... it's better to make them appear minimized,
// and let them just flash in the taskbar.
if( ! force )
{
#ifdef KMESSDEBUG_CHATMASTER
@@ -749,11 +759,22 @@ void ChatMaster::raiseChat( Chat *chat, bool force )
else
{
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Window was not minimized, showing it again.";
kDebug() << "Window was not minimized, showing it again.";
#endif
chatWindow->show();
}
#ifdef Q_WS_X11
// Bypass focus stealing prevention (code from Quassel)
QX11Info::setAppUserTime( QX11Info::appTime() );
#endif
// Workaround a bug in KWin: force the window to get focus
if( chatWindow->windowState() & Qt::WindowMinimized) {
chatWindow->setWindowState( (chatWindow->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive );
chatWindow->show();
}
// Set the keyboard focus to the chat window
chatWindow->raise();
KWindowSystem::activateWindow( chatWindow->winId() );
@@ -895,8 +916,6 @@ void ChatMaster::showSpecialMessage( const ChatMessage &message, const MsnSwitch
case ChatMessage::CONTENT_MESSAGE_INK:
case ChatMessage::CONTENT_NOTIFICATION_NUDGE:
case ChatMessage::CONTENT_NOTIFICATION_WINK:
case ChatMessage::CONTENT_SYSTEM_NOTICE:
case ChatMessage::CONTENT_SYSTEM_ERROR:
case ChatMessage::CONTENT_APP_INVITE:
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Message is important, delivering it.";
@@ -1365,7 +1384,7 @@ void ChatMaster::slotGotMsnObject(const QString &msnObjectData, const QString &h
MsnObject::MsnObjectType objectType = msnObject.getType();
if( objectType == MsnObject::WINK )
{
statusMessage = i18n( "%1 is sending a wink: %2", friendlyName, msnObject.getFriendly() );
statusMessage = i18n( "%1 is sending a wink: &quot;%2&quot;", friendlyName, msnObject.getFriendly() );
}
// Show the status message
@@ -1515,51 +1534,72 @@ void ChatMaster::startApplication( P2PApplication *application )
// Start a connection with the information gathered from the Notification connection
MsnSwitchboardConnection *ChatMaster::startSwitchboard( const ChatInformation &chatInfo )
{
MsnSwitchboardConnection *switchboard = getContactSwitchboardConnection( chatInfo.getContactHandle(), true );
Chat *chat = getChatBySwitchboard( switchboard );
MsnSwitchboardConnection *switchboard = 0;
const QString &handle( chatInfo.getContactHandle() );
if( switchboard != 0 && chatInfo.getType() != ChatInformation::CONNECTION_REFRESH )
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Starting new switchboard session with" << handle;
#endif
/**
* Refresh requests are made by expired/disconnected switchboard sessions, and they are refreshed
* with the new connection data.
* All other types of chat request create a new switchboard session from the chat info.
* We could attach the newly created SB to a chat window, but we don't know what kind of chat it
* may be at this point (the list of initial participants will be received later, when the SB
* connection will be established). Therefore, we just don't attach it to any chat, and so we
* posticipate the decision to later.
* (Also remember that you may have more than one chat with a contact, a 1-on-1, a group one,
* and a data transfer one)
*/
if( chatInfo.getType() == ChatInformation::CONNECTION_REFRESH )
{
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Deleting old switchboard connection.";
kDebug() << "Finding the session to refresh.";
#endif
slotSwitchboardDelete( switchboard, true );
switchboard = 0;
}
if( switchboard == 0 )
{
if( chat == 0 )
foreach( MsnSwitchboardConnection *currentSwitchboard, switchboardConnections_ )
{
// Create a new switchboard connection
switchboard = createSwitchboardConnection();
}
else
{
// Replace the old switchboard connection with a new one
switchboard = createSwitchboardConnection( chat->getSwitchboardConnection() );
if( currentSwitchboard->getContactsInChat().contains( handle )
&& currentSwitchboard->isWaiting() )
{
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Session found, it will be refreshed.";
#endif
switchboard = currentSwitchboard;
break;
}
}
if( ! switchboard )
if( switchboard == 0 )
{
kWarning() << "Unable to register new switchboard, not starting it up.";
kWarning() << "Unable to find which session requested a refresh.";
return 0;
}
}
switchboard->start( chatInfo );
if( chat != 0 )
else
{
chat->setSwitchboardConnection( switchboard );
switchboard = createSwitchboardConnection();
if( KMESS_NULL(switchboard) ) return 0;
#ifdef KMESSDEBUG_CHATMASTER
kDebug() << "Creating new session.";
#endif
}
// If this switchboard is a background one, made to request a contact's picture,
// we can remove the pending request from the list now.
if( chatInfo.getType() == ChatInformation::CONNECTION_BACKGROUND
&& pendingDisplayPictures_.contains( chatInfo.getContactHandle() ) )
&& pendingDisplayPictures_.contains( handle ) )
{
pendingDisplayPictures_.removeAll( chatInfo.getContactHandle() );
pendingDisplayPictures_.removeAll( handle );
}
// Connect to the new server
switchboard->start( chatInfo );
Chat *chat = getChatBySwitchboard( switchboard );
if( chat )
{
chat->setEnabled( true );
}
return switchboard;
@@ -1578,23 +1618,20 @@ Chat *ChatMaster::createChat( MsnSwitchboardConnection *switchboard, bool reques
ChatWindow *newChatWindow;
// If the new chat is a group chat, find existing group chat windows; else find private chats
QStringList partecipants = switchboard->getContactsInChat();
const QStringList& partecipants( switchboard->getContactsInChat() );
newChat = getContactsChat( partecipants, true );
// Check if the chat was required by the user
if( ! requestedByUser )
// If the chat was requested by a contact, check if we have a chat request
// pending for that contact and remove it
if( ! requestedByUser && partecipants.count() < 2 )
{
// Else check if it's a single chat
if( partecipants.count() < 2 )
const QString& handle( partecipants.first() );
// Also change the request source to the user if we asked a chat with this contact first
requestedByUser = requestedChats_.contains( handle );
if( requestedByUser )
{
// Grep the contact handle and check if it is in the list
QString handle( partecipants.first() );
requestedByUser = requestedChats_.contains( handle );
if( requestedByUser )
{
// Remove it if we found the handle
requestedChats_.removeAll( handle );
}
// Remove the request
requestedChats_.removeAll( handle );
}
}
@@ -1605,6 +1642,18 @@ Chat *ChatMaster::createChat( MsnSwitchboardConnection *switchboard, bool reques
<< switchboard->getContactsInChat().join(",") << "already exists, raising it." << endl;
#endif
// The chat may have been disabled, reenable it just in case.
// Seen happening with group chats where you get reinvited to after a reconnection.
newChat->setEnabled( true );
// Delete the previous switchboard ( if it's different from the current one ) and attach the new
MsnSwitchboardConnection *oldConnection = newChat->getSwitchboardConnection();
if( oldConnection != switchboard )
{
newChat->setSwitchboardConnection( switchboard );
slotSwitchboardDelete( oldConnection, true );
}
// If we've requested a chat window, raise it forcing it open over other KMess' windows;
// if some contact wants to chat with us, the chat window will open minimized.
raiseChat( newChat, requestedByUser );
+62 -30
View File
@@ -35,6 +35,16 @@
#include <KStandardDirs>
#include <KUrl>
// Originally from libxml/chvalid.h, but with the last check in xmlIsCharQ removed;
// the last check was for four-byte characters, we only check shorts. Removing
// the last check fixes two warnings on the console. :)
#define xmlIsChar_ch(c) (((0x9 <= (c)) && ((c) <= 0xa)) || \
((c) == 0xd) || \
(0x20 <= (c)))
#define xmlIsCharQ(c) (((c) < 0x100) ? \
xmlIsChar_ch((c)) :\
(((0x100 <= (c)) && ((c) <= 0xd7ff)) || \
((0xe000 <= (c)) && ((c) <= 0xfffd))))
// The constructor
@@ -389,6 +399,12 @@ QString ChatMessageStyle::createFallbackMessage(const ChatMessage &message)
parseBody( KMessShared::htmlEscape( body ) );
return "<div dir='" + fontDir + "'><font color='blue'>" + body + "</font><br></div>";
}
else if( type == ChatMessage::TYPE_PRESENCE )
{
// Gray presence message
parseBody( KMessShared::htmlEscape( body ) );
return "<div dir='" + fontDir + "'><font color='gray'>" + body + "</font><br></div>";
}
else
{
// Purple notification message
@@ -402,7 +418,7 @@ QString ChatMessageStyle::createFallbackMessage(const ChatMessage &message)
// Convert the message as XML.
QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool isHistory )
{
uint timestamp;
uint timestamp = 0;
QString fontBefore;
QString fontAfter;
QString xmlMessage;
@@ -410,12 +426,32 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
QString typeString;
QString color;
QFont font;
// Remove any characters which are not allowed in XML
const ushort* utf16 = message.getBody().utf16();
ushort* newutf16 = new ushort[ message.getBody().size() ];
int j = 0;
for( int i = 0; i < message.getBody().size(); ++i )
{
// Utf16 sometimes uses more than two bytes for a character, but in those cases,
// both parts will be valid, so xmlIsCharQ (checking if a short is valid) will always return true.
if( xmlIsCharQ( utf16[i] ) )
{
newutf16[ j++ ] = utf16[i];
}
#ifdef KMESSDEBUG_CHATVIEW
else
{
kDebug() << "Found invalid character with code " << (int)utf16[i] << ", not showing";
}
#endif
}
QString body = QString::fromUtf16( newutf16, j );
// Get message info
int type = message.getType();
QString handle ( message.getContactHandle() );
QString name ( message.getContactName() );
QString body ( message.getBody() );
bool isRtl = body.isRightToLeft();
bool nameIsRtl = name.isRightToLeft();
@@ -456,6 +492,7 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
parseBody(body);
// Show the message time
// TODO: maybe timestamps should always available in the histories, just not necessarily shown?
if( showTime_ )
{
// Get the time
@@ -475,6 +512,7 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
case ChatMessage::TYPE_APPLICATION_AUDIO:
case ChatMessage::TYPE_APPLICATION: typeString = "application"; break;
case ChatMessage::TYPE_OFFLINE_INCOMING: typeString = "offlineIncoming"; break;
case ChatMessage::TYPE_PRESENCE: typeString = "presence"; break;
case ChatMessage::TYPE_NOTIFICATION:
default:
typeString = "notification";
@@ -491,27 +529,27 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
if ( isHistory )
{
xmlMessage = "<message"
" type='" + escapeAttribute(typeString) + "'"
" type='" + KMessShared::htmlEscape( typeString ) + "'"
+ " timestamp='" + QString::number( timestamp ) + "'" +
">\n";
}
else
{
QString timeS;
QDateTime datetime = QDateTime::fromTime_t( timestamp );
QString timeString;
const QDateTime &datetime = QDateTime::fromTime_t( timestamp );
if ( showDate_ )
{
timeS = KGlobal::locale()->formatDateTime( datetime, KLocale::ShortDate, showSeconds_ );
timeString = KGlobal::locale()->formatDateTime( datetime, KLocale::ShortDate, showSeconds_ );
}
else
{
timeS = KGlobal::locale()->formatTime( datetime.time(), showSeconds_ );
timeString = KGlobal::locale()->formatTime( datetime.time(), showSeconds_ );
}
xmlMessage = "<message"
" type='" + escapeAttribute(typeString) + "'"
+ ( ! showTime_ ? QString::null : " time='" + timeS + "'" ) +
" type='" + KMessShared::htmlEscape( typeString ) + "'" +
( ! showTime_ ? QString() : " time='" + timeString + "'" ) +
">\n";
}
@@ -519,17 +557,17 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
if(! message.getContactHandle().isEmpty() )
{
xmlMessage += " <from>\n"
" <contact contactId='" + escapeAttribute( message.getContactHandle() ) + "'>\n";
" <contact contactId='" + KMessShared::htmlEscape( message.getContactHandle() ) + "'>\n";
// If the user doesn't have a display picture, the style will use a default image.
if( ! message.getContactPicturePath().isEmpty() && QFile::exists( message.getContactPicturePath() ) )
{
xmlMessage += " <displayPicture url='" + escapeAttribute( message.getContactPicturePath() ) + "' />\n";
xmlMessage += " <displayPicture url='" + KMessShared::htmlEscape( message.getContactPicturePath() ) + "' />\n";
}
if( ! name.isEmpty() )
{
xmlMessage += " <displayName text='" + escapeAttribute( name ) + "' dir='" + (nameIsRtl ? "rtl" : "ltr") + "' />\n";
xmlMessage += " <displayName text='" + KMessShared::htmlEscape( name ) + "' dir='" + (nameIsRtl ? "rtl" : "ltr") + "' />\n";
}
xmlMessage += " </contact>\n"
@@ -538,30 +576,24 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
// Add message
xmlMessage += " <body"
" color='" + escapeAttribute( color ) + "'"
" fontFamily='" + escapeAttribute( font.family() ) + "'"
" fontSize='" + QString::number( font.pointSize() ) + "'"
" fontBold='" + (font.bold() ? "1" : "0") + "'"
" fontItalic='" + (font.italic() ? "1" : "0") + "'"
" fontUnderline='" + (font.underline() ? "1" : "0") + "'"
" fontBefore='" + escapeAttribute( fontBefore ) + "'"
" fontAfter='" + escapeAttribute( fontAfter ) + "'"
" dir='" + (isRtl ? "rtl" : "ltr") + "'"
">" + Qt::escape( body ) + "</body>\n" // escape again for XML
" color='" + KMessShared::htmlEscape( color ) + "'"
" fontFamily='" + KMessShared::htmlEscape( font.family() ) + "'"
" fontSize='" + QString::number( font.pointSize() ) + "'"
" fontBold='" + (font.bold() ? "1" : "0") + "'"
" fontItalic='" + (font.italic() ? "1" : "0") + "'"
" fontUnderline='" + (font.underline() ? "1" : "0") + "'"
" fontBefore='" + KMessShared::htmlEscape( fontBefore ) + "'"
" fontAfter='" + KMessShared::htmlEscape( fontAfter ) + "'"
" dir='" + (isRtl ? "rtl" : "ltr") + "'"
">\n" +
KMessShared::htmlEscape( body ) + '\n' +
"</body>\n" // escape again for XML
"</message>\n";
return xmlMessage;
}
// Escape the strings for use in XML attributes
QString ChatMessageStyle::escapeAttribute(const QString &value) const
{
return Qt::escape(value).replace("\"", "&quot;").replace("'", "&apos;");
}
// Return the base folder of the style.
const QString & ChatMessageStyle::getBaseFolder() const
{
-2
View File
@@ -126,8 +126,6 @@ class ChatMessageStyle : public QObject
// Convert the message as HTML, fallback method when XML fails.
QString createFallbackMessage(const ChatMessage &message);
// Escape the strings for use in XML attributes
QString escapeAttribute(const QString &value) const;
// Return whether the given result is empty
bool isEmptyResult( const QString &parsedMessage );
// Replace the newline characters
+12 -9
View File
@@ -43,10 +43,10 @@ ChatMessageView::ChatMessageView( QWidget *parent )
, lastMessageId_(0)
{
// Disable features that might do harm or are not useful
setJScriptEnabled(false);
setJavaEnabled(false);
setMetaRefreshEnabled(false);
setOnlyLocalReferences( true );
setJScriptEnabled( false );
setJavaEnabled( false );
setMetaRefreshEnabled( false );
setOnlyLocalReferences( false );
setSuppressedPopupIndicator( false );
// Enable winks
@@ -86,6 +86,8 @@ ChatMessageView::~ChatMessageView()
qDeleteAll( chatMessages_ );
chatMessages_.clear();
lastContactMessages_.clear();
delete chatStyle_;
}
@@ -305,7 +307,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool &app
}
// Not appending: also add a root element to the history
return "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
"<?xml-stylesheet type=\"text/xsl\" href=\"file://" + chatStyle_->getStyleSheet() + "\" media=\"all\" ?>\n"
"<!-- " + getStyleTag() + " -->\n"
"<messageRoot xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
@@ -750,16 +752,17 @@ void ChatMessageView::setXml( const QString &newXmlBody )
// Add the given message to the message browser.
void ChatMessageView::showMessage( const ChatMessage &message )
{
// Avoid duplicating the same notification message.
if( message.getContentsClass() == ChatMessage::CONTENT_NOTIFICATION_LEFT
// Avoid duplicating the same presence message.
if( message.getType() == ChatMessage::TYPE_PRESENCE
&& ! chatMessages_.isEmpty() )
{
ChatMessage *lastChatMessage = chatMessages_.last();
if( lastChatMessage->getContentsClass() == ChatMessage::CONTENT_NOTIFICATION_LEFT
if( lastChatMessage->getType() == message.getType()
&& lastChatMessage->getContentsClass() == message.getContentsClass()
&& lastChatMessage->getContactHandle() == message.getContactHandle() )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kDebug() << "Not showing 'contact left' message for the same contact again.";
kDebug() << "Not showing presence message for the same contact again.";
#endif
return;
}
+12 -5
View File
@@ -56,7 +56,7 @@ ChatView::ChatView( QWidget *parent )
, initialized_( false )
{
// Insert a KHTMLPart in the placeholder
chatMessageView_ = new ChatMessageView( parent );
chatMessageView_ = new ChatMessageView( this );
connect( chatMessageView_, SIGNAL( popupMenu(const QString&,const QPoint&) ),
this, SLOT ( slotShowContextMenu(const QString&,const QPoint&) ) );
connect( chatMessageView_, SIGNAL( openUrlRequest(const KUrl&) ),
@@ -275,7 +275,14 @@ bool ChatView::isEmpty() const
// Save the chat to the given file
/* Save the chat to the given file
*
* @param path The path to the file to save to
* @param format Format of the file (xml, text, ...)
* @param overwriteContents whether to append or overwrite the contents of the file
* @param allowUserInteraction whether to allow dialog boxes to be sent if something succeeds or fails
* @returns true if everything was saved correctly, false otherwise
*/
bool ChatView::saveChatToFile( const QString &path, Account::ChatExportFormat format, bool overwriteContents, bool allowUserInteraction )
{
#ifdef KMESSDEBUG_CHATVIEW
@@ -329,7 +336,7 @@ bool ChatView::saveChatToFile( const QString &path, Account::ChatExportFormat fo
QString chatHistory( chatMessageView_->getHistory( format, willAppend, appendPoint ) );
#ifdef KMESSDEBUG_CHATVIEW
kDebug() << "Will append to current file?" << willAppend;
kDebug() << "Will append to current file?" << willAppend;
#endif
if( willAppend )
@@ -400,7 +407,7 @@ void ChatView::setEnabled( bool isEnabled )
// Set the zoom factor of the text
void ChatView::setZoomFactor( int percentage )
{
chatMessageView_->setZoomFactor( percentage );
chatMessageView_->setFontScaleFactor( percentage );
}
@@ -824,7 +831,7 @@ void ChatView::slotShowContextMenu( const QString &clickedUrl, const QPoint &poi
urlAction = new KAction( KIcon( "list-add" ), i18n("Add this &Emoticon..."), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotAddNewEmoticon()) );
contextMenu->addAction( urlAction );
urlAction = new KAction( KIcon( "list-remove" ), i18n("Ignore this &Emoticon"), this );
urlAction = new KAction( KIcon( "list-remove" ), i18n("Hide this &Emoticon"), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotIgnoreEmoticon()) );
contextMenu->addAction( urlAction );
}
+178 -35
View File
@@ -55,6 +55,7 @@
#include <KTabBar>
#include <KToolBar>
#include <KToolInvocation>
#include <KWindowSystem>
#ifdef KMESSDEBUG_CHATWINDOW
@@ -84,6 +85,12 @@ ChatWindow::ChatWindow( QWidget *parent )
setupUi( mainWidget );
setCentralWidget( mainWidget );
#if KMESS_ENABLE_INK == 0
// Only enable the Ink button if GIFLib is available
inkButton_->hide();
inkEdit_->setEnabled( false );
#endif
// Connect the UI signals
connect( sendButton_, SIGNAL( clicked() ),
this, SLOT ( slotSendButtonClicked() ) );
@@ -322,10 +329,12 @@ bool ChatWindow::checkAndCloseWindow()
// The chat window is closing
bool ChatWindow::closeAllTabs()
{
if( chatTabs_->count() > 1 )
// Do not ask if there only is one tab, or if the user has
// explicitly requested all the tabs to be closed
if( chatTabs_->count() > 1 && sender() != closeAllAction_ )
{
int res = KMessageBox::questionYesNoCancel( this,
i18n( "<html>There are multiple tabs opened in this chat window. Do you want to close the "
i18n( "<html>There are multiple tabs open in this chat window. Do you want to close the "
"current tab only, or all tabs?<br /><br />"
"<i>Note: You can close all tabs at once by pressing Alt+F4.</i></html>" ),
i18nc( "Dialog box caption: closing a chatwindow with a single tab", "Closing a Chat Tab" ),
@@ -474,7 +483,7 @@ void ChatWindow::createMenus()
standardEmoticonsDockAction->setShortcut( QKeySequence( "Ctrl+E" ) );
customEmoticonsDockAction->setIcon( KIcon("face-smile-gearhead-female") );
customEmoticonsDockAction->setToolTip( i18n("Enable or disable the Custom Emoticons panel") );
customEmoticonsDockAction->setToolTip( i18n("Enable or disable the custom emoticons panel") );
customEmoticonsDockAction->setText( i18nc("Toolbar button","My Emoticons") );
customEmoticonsDockAction->setIconText( i18nc("Toolbar button","My Emoticons") );
customEmoticonsDockAction->setShortcut( QKeySequence( "Ctrl+Y" ) );
@@ -660,12 +669,14 @@ void ChatWindow::editorColorChanged(const QColor &color)
// Whenever the QTextEdit's contents is entirely deleted, the font color spontaneously resets to black;
// if this happens, set the color back to the user's color.
// HACK: This possibly is a Qt <= 4.4 bug exposed.
// UPDATE: Happens with Qt 4.5 too. Also resets the font weight.
if ( color.name() != currentAccount_->getFontColor() )
{
#ifdef KMESSDEBUG_CHATWINDOW
kDebug() << "Color was reset to" << color.name() << ". Restoring it to the account setting.";
#endif
messageEdit_->setTextColor( QColor( currentAccount_->getFontColor() ) );
messageEdit_->setFont( QFont ( currentAccount_->getFont() ) );
}
}
@@ -690,6 +701,7 @@ bool ChatWindow::eventFilter( QObject *obj, QEvent *event )
{
blinkTimer_.stop();
blinkToUpper_ = true;
setWindowTitle();
}
@@ -763,6 +775,7 @@ bool ChatWindow::eventFilter( QObject *obj, QEvent *event )
}
else if( ctrl )
{
QStringList& quickRetypeList = getCurrentChat()->getQuickRetypeList();
switch( key )
{
// Detect text copying from the message editor, or the Message View
@@ -772,51 +785,54 @@ bool ChatWindow::eventFilter( QObject *obj, QEvent *event )
// Detect 'save chat' command
case Qt::Key_S:
getCurrentChat()->showSaveChatDialog();;
getCurrentChat()->showSaveChatDialog();
break;
// Detect fast-retype (ctrl+UpArrow)
case Qt::Key_Up:
if( quickRetypeList_.isEmpty() )
if( quickRetypeList.isEmpty() )
{
break;
}
if( indexSentences_ == quickRetypeList_.size() )
if( indexSentences_ == quickRetypeList.size() )
{
// store the last sentence in writing
lastSentence_ = messageEdit_->toPlainText();
}
if( indexSentences_ > 0 )
{
indexSentences_--;
}
if( indexSentences_ >= 0 )
{
messageEdit_->setPlainText( quickRetypeList_[ indexSentences_ ] );
messageEdit_->setPlainText( quickRetypeList[ indexSentences_ ] );
}
break;
// Detect fast-retype (ctrl+DownArrow)
case Qt::Key_Down:
if( quickRetypeList_.isEmpty() )
if( quickRetypeList.isEmpty() )
{
break;
}
if( indexSentences_ == quickRetypeList_.size() - 1
&& ! lastSentence_.isEmpty() )
if( indexSentences_ == quickRetypeList.size() - 1 )
{
messageEdit_->setPlainText( lastSentence_ );
indexSentences_ = quickRetypeList_.size();
indexSentences_ = quickRetypeList.size();
}
if( indexSentences_ < quickRetypeList_.size() - 1 )
indexSentences_++;
if( indexSentences_ < quickRetypeList_.size() )
if( indexSentences_ < quickRetypeList.size() - 1 )
{
messageEdit_->setPlainText( quickRetypeList_[ indexSentences_ ] );
indexSentences_++;
}
if( indexSentences_ < quickRetypeList.size() )
{
messageEdit_->setPlainText( quickRetypeList[ indexSentences_ ] );
}
break;
@@ -976,8 +992,8 @@ bool ChatWindow::handleCommand( QString command )
KMessageBox::sorry( this,
i18n( "<html>You used an incorrect syntax for the /status command. The correct syntax "
"is: <b>/status online|away|idle|brb|busy|lunch|phone|invisible</b>.<br/>"
"Or you can use the <b>/online</b>, <b>/phone</b> etc. shortcuts.</html>" ),
i18nc( "Dialog box caption for wrong command syntax warning", "Incorrect /status syntax" )
"You can also use shortcuts like <b>/online</b> or <b>/phone</b>.</html>" ),
i18nc( "Dialog box caption for wrong command syntax warning", "Incorrect /status Syntax" )
);
return true;
}
@@ -1040,9 +1056,9 @@ bool ChatWindow::handleCommand( QString command )
if( participants.count() != 1 )
{
KMessageBox::sorry( this,
i18n( "<html>You can't block anyone in a group chat.</html>" ),
i18nc( "Caption when trying to block someone when in a group chat",
"Can't Block Right Now!" )
i18n( "<html>You cannot use the /block command in a group chat.</html>" ),
i18nc( "Caption when trying to block someone in a group chat",
"Cannot use /block command" )
);
return true;
}
@@ -1053,9 +1069,9 @@ bool ChatWindow::handleCommand( QString command )
if( participants.count() != 1 )
{
KMessageBox::sorry( this,
i18n( "<html>You can't block anyone in a group chat.</html>" ),
i18nc( "Caption when trying to block someone when in a group chat",
"Can't Block Right Now!" )
i18n( "<html>You cannot use the /unblock command in a group chat.</html>" ),
i18nc( "Caption when trying to unblock someone in a group chat",
"Cannot use /unblock command!" )
);
return true;
}
@@ -1326,7 +1342,7 @@ void ChatWindow::sendInk()
sendButton_->setEnabled( false );
// Show the message in the browser window
const QString& text( "<img src='data:image/png;base64," + ink.toBase64() + "'>" );
const QString& text( "<img src='data:image/gif;base64," + ink.toBase64() + "'>" );
ChatMessage message( ChatMessage::TYPE_OUTGOING,
ChatMessage::CONTENT_MESSAGE_INK,
@@ -1432,12 +1448,13 @@ void ChatWindow::sendMessage()
getCurrentChat()->showMessage( message );
// Add it to the list of sent messages, to allow fast retyping
quickRetypeList_.append( message.getBody() );
QStringList &quickRetypeList = getCurrentChat()->getQuickRetypeList();
quickRetypeList.append( message.getBody() );
lastSentence_ = QString();
// Reset the last sentence counter.
// showMessage() updates chatMessages_
indexSentences_ = quickRetypeList_.size();
indexSentences_ = quickRetypeList.size();
}
@@ -1471,7 +1488,6 @@ void ChatWindow::setEnabled( bool isEnabled )
messageEdit_ ->setEnabled( isEnabled );
newLineButton_ ->setEnabled( isEnabled );
sendButton_ ->setEnabled( isEnabled );
inkButton_ ->setEnabled( isEnabled );
standardEmoticonButton_ ->setEnabled( isEnabled );
customEmoticonButton_ ->setEnabled( isEnabled );
inviteButton_ ->setEnabled( isEnabled );
@@ -1492,6 +1508,9 @@ void ChatWindow::setEnabled( bool isEnabled )
cutAction_ ->setEnabled( isEnabled );
pasteAction_ ->setEnabled( isEnabled );
// Update the winks and handwriting buttons
updateModeButtons();
// The window is being enabled back, replace some stuff which changes
// on every connection
if( isEnabled )
@@ -1541,7 +1560,7 @@ void ChatWindow::setWindowTitle( const QString &caption )
if( currentChat != 0 )
{
// Avoid newlines which would cause problems to the UI layout
caption_ = currentChat->getCaption().replace( "\n", " " );
caption_ = currentChat->getCaption();
}
else
{
@@ -1953,8 +1972,8 @@ void ChatWindow::slotSendButtonClicked()
}
else if( winksButton_->isChecked() )
{
const QString& msnObject( winksWidget_->getMsnObjectWinkSelected() );
if( ! msnObject.isEmpty() )
const MsnObject &msnObject = winksWidget_->getMsnObjectWinkSelected();
if( msnObject.isValid() )
{
getCurrentChat()->sendWink( msnObject );
}
@@ -2140,6 +2159,7 @@ void ChatWindow::slotTabChanged( int currentIndex )
#endif
messageEdit_->setDocument( new QTextDocument( messageEdit_ ) );
updateModeButtons();
updateEditorFont();
inkEdit_->setImage( 0 );
return;
@@ -2176,12 +2196,16 @@ void ChatWindow::slotTabChanged( int currentIndex )
messageEdit_ ->blockSignals( false );
inkEdit_ ->blockSignals( false );
// Reset quick re-type index
indexSentences_ = chat->getQuickRetypeList().size();
// Set the font style/color
updateEditorFont();
// Update the window UI with this chat's details
slotSwitchEditor();
setWindowTitle();
updateModeButtons();
slotGotTypingMessage( chat );
}
@@ -2250,7 +2274,7 @@ bool ChatWindow::slotTabRemoved( QWidget *chatWidget )
// Update a chat's tab title when the participants names change
void ChatWindow::slotUpdateChatInfo( Chat *chat )
{
// If called without a parameter, we've been called by a chat's signal
// If called without a parameter, we've been called by a chat's signal
if( chat == 0 )
{
// Find the chat which has emitted the signal
@@ -2273,7 +2297,7 @@ void ChatWindow::slotUpdateChatInfo( Chat *chat )
QString chatCaption( chat->getCaption() );
// Change the tab caption
chatTabs_->setTabText( index, chatCaption );
chatTabs_->setTabText( index, chatCaption.replace( '&', "&&" ) );
chatTabs_->setTabIcon( index, chat->getParticipantsTabIcon() );
// Create a tool tip with details on the chat
@@ -2305,13 +2329,18 @@ void ChatWindow::slotUpdateChatInfo( Chat *chat )
chatTabs_->setTabToolTip( index, toolTip );
// If chat is current chat then calls update caption method
// If it is the current one, the UI must be updated
if ( chat == getCurrentChat() )
{
#ifdef KMESSDEBUG_CHATWINDOW
kDebug() << "Source chat is the current one, updating window title.";
kDebug() << "Source chat is the current one, updating UI.";
#endif
// Update the window title
setWindowTitle();
// Update the status of the writing mode buttons (winks, handwriting,...)
// This is needed in case the contact has changed status
updateModeButtons();
}
}
@@ -2386,6 +2415,120 @@ void ChatWindow::toggleSpellCheck( bool useSpellCheck )
// Update the status of the tiny writing mode buttons
void ChatWindow::updateModeButtons()
{
// don't do anything when the window / chat was just closed
if( getCurrentChat() == NULL )
{
return;
}
#if KMESS_ENABLE_INK == 1
bool enableInkButton = true;
#else
bool enableInkButton = false;
#endif
bool enableWinksButton = true;
const QStringList &participants( getCurrentChat()->getParticipants() );
foreach( const QString &handle, participants )
{
const ContactBase *contact = currentAccount_->getContactByHandle( handle );
if( contact == 0 )
{
continue;
}
#if KMESS_ENABLE_INK == 1
if( enableInkButton )
{
// Disable the Ink button if the contact doesn't support GIF Ink
if( ! contact->hasCapability( ContactBase::MSN_CAP_INK_GIF ) )
{
enableInkButton = false;
}
// TODO Fix sending Ink to WLM 8.5 and 2009 (probably by implementing ISF support)
// Disable the Ink button also if we're chatting with an ISF-enabled WLM8.5 / WLM2009
if( ( contact->getClientName() == "Windows Live Messenger 8.5"
|| contact->getClientName() == "Windows Live Messenger 2009" )
&& contact->hasCapability( ContactBase::MSN_CAP_INK_ISF ) )
{
enableInkButton = false;
}
}
#endif
// Disable the Winks button if the contact doesn't support Winks
if( enableWinksButton
&& ! contact->hasCapability( (ContactBase::MsnClientCapabilities) ( ContactBase::MSN_CAP_WINKS | ContactBase::MSN_CAP_MULTI_PACKET ) ) )
{
enableWinksButton = false;
}
}
#ifdef KMESSDEBUG_CHATWINDOW
kDebug() << "Winks/Ink button disabling check: all contacts support winks?" << enableWinksButton
<< "and ink?" << enableInkButton;
#endif
inkButton_ ->setEnabled( enableInkButton );
winksButton_->setEnabled( enableWinksButton );
// Set a tooltip or a status bar message to either buttons.
// The tooltip covers the status message otherwise.
#if KMESS_ENABLE_INK == 1 // else, the ink button isn't showed anyway
if( enableInkButton )
{
inkButton_->setToolTip ( i18n( "Handwriting mode" ) );
inkButton_->setStatusTip( QString() );
}
else
{
inkButton_->setToolTip ( QString() );
if( getCurrentChat()->getParticipants().count() > 1 )
{
inkButton_->setStatusTip( i18nc( "Label text",
"Handwriting is disabled: KMess cannot send drawings to "
"some of the contacts." ) );
}
else
{
inkButton_->setStatusTip( i18nc( "Label text",
"Handwriting is disabled: KMess cannot send drawings to "
"this contact." ) );
}
}
#endif
if( enableWinksButton )
{
winksButton_->setToolTip ( i18n( "Winks" ) );
winksButton_->setStatusTip( QString() );
}
else
{
winksButton_->setToolTip ( QString() );
if( getCurrentChat()->getParticipants().count() > 1 )
{
winksButton_->setStatusTip( i18nc( "Label text",
"Winks are disabled: KMess cannot send winks to "
"some of the contacts." ) );
}
else
{
winksButton_->setStatusTip( i18nc( "Label text",
"Winks are disabled: KMess cannot send winks to "
"this contact." ) );
}
}
}
// Update the editor's font to match the account's font
void ChatWindow::updateEditorFont()
{
+3 -3
View File
@@ -204,6 +204,8 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
void toggleSessionInfo( bool showSessionMessages );
// Called when the "use spell checking" action is called.
void toggleSpellCheck( bool useSpellCheck );
// Update the status of the tiny writing mode buttons
void updateModeButtons();
// Clean up the view of the current chat tab
void viewClearChat();
// enlarge the text size
@@ -242,7 +244,7 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
KAction *emoticonAction_;
// The first item in the Chat Menu (used to add the Invite menu before it)
QAction *firstChatMenuItem_;
// Index for fast-retype
// Index for quick-retype
int indexSentences_;
// Whether or not the object was initialized
bool initialized_;
@@ -264,8 +266,6 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
KAction *pasteAction_;
// Action to switch to the previous tab
KAction *prevTabAction_;
// List of previously sent messages, to allow sending them again quickly
QStringList quickRetypeList_;
// Action to start a file transfer
KAction *sendAction_;
// Toggle actions for showing and hiding the menu bar
+5 -5
View File
@@ -181,7 +181,7 @@
<string>Standard text mode</string>
</property>
<property name="whatsThis">
<string>Click this button to switch to standard text mode.</string>
<string>Click this button to switch to the standard text mode.</string>
</property>
<property name="text">
<string/>
@@ -200,10 +200,10 @@
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Ink message</string>
<string>Handwriting mode</string>
</property>
<property name="whatsThis">
<string>Click this button to switch to ink mode, so you can write or paint an ink message.</string>
<string>Click this button to switch to the handwriting mode, so you can write or paint a handwritten message.</string>
</property>
<property name="text">
<string/>
@@ -229,7 +229,7 @@
<string>Standard emoticons</string>
</property>
<property name="whatsThis">
<string>Click this button to show all default MSN emoticons, so you can easily insert them in your messages.</string>
<string>Click this button to show all default Live Messenger emoticons, so you can easily insert them in your messages.</string>
</property>
<property name="text">
<string/>
@@ -248,7 +248,7 @@
<string>Custom emoticons</string>
</property>
<property name="whatsThis">
<string>If you have added any custom emoticons, click this button to view them, so you can easily insert them in your messages.</string>
<string>Click this button to show all custom emoticons, so you can easily insert them in your messages.</string>
</property>
<property name="text">
<string/>
+139 -79
View File
@@ -27,6 +27,11 @@
#include "../emoticonmanager.h"
#include "../kmessdebug.h"
// HACK: Must go after 2.0-final
#include "../network/msnnotificationconnection.h"
#include "../kmess.h"
#include "../kmessapplication.h"
#include <QClipboard>
#include <QFileInfo>
#include <QMouseEvent>
@@ -48,15 +53,15 @@
ContactFrame::ContactFrame( QWidget *parent )
: QWidget(parent)
, Ui::ContactFrame()
, activated_(false)
, contact_(0)
, contactActionPopup_(0)
, contactPixmapLabelEnabled_(true)
, contactPropertiesDialog_(0)
, detailedContact_(0)
, handle_(QString::null)
, currentMode_(ModeNormal)
, infoLabelEnabled_(true)
, locked_(false)
, locked_(true)
{
// Setup the UI as first thing
setupUi( this );
@@ -89,7 +94,8 @@ ContactFrame::~ContactFrame()
// Activate the frame by giving it a contact
void ContactFrame::activate( ContactBase *contact )
{
if ( contact_ && contact_ != contact )
// Disconnect the signals linked to previous contact( if there is anyone )
if ( contact_ != 0 )
{
disconnect( contact_, 0, this, 0 );
}
@@ -102,7 +108,6 @@ void ContactFrame::activate( ContactBase *contact )
contact_ = 0;
detailedContact_ = 0;
activated_ = false;
locked_ = true;
qDeleteAll( copyLinkActionsList_ );
@@ -114,14 +119,11 @@ void ContactFrame::activate( ContactBase *contact )
handle_ = contact_->getHandle();
detailedContact_ = CurrentAccount::instance()->getContactList()->getContactByHandle( handle_ );
if( detailedContact_ == 0 )
{
activated_ = false;
locked_ = true;
}
else
if( detailedContact_ != 0 )
{
// Connect the contact, to update the frame on presence info changes
connect( detailedContact_, SIGNAL( changedList(Contact*) ),
this, SLOT ( contactChangedList() ) );
connect( detailedContact_, SIGNAL( changedFriendlyName() ),
this, SLOT ( updateStatusWidgets() ) );
connect( detailedContact_, SIGNAL( changedStatus() ),
@@ -132,9 +134,6 @@ void ContactFrame::activate( ContactBase *contact )
this, SLOT ( updateStatusWidgets() ) );
connect( detailedContact_, SIGNAL( destroyed(QObject*) ),
this, SLOT ( contactDestroyed(QObject*) ) );
activated_ = true;
locked_ = false;
}
}
@@ -145,6 +144,8 @@ void ContactFrame::activate( ContactBase *contact )
updatePicture();
updateStatusWidgets();
locked_ = false;
show();
}
@@ -160,6 +161,15 @@ void ContactFrame::allowContact()
emit contactAllowed( handle_ );
locked_ = true;
}
// Foward the changed list signal from contact
void ContactFrame::contactChangedList()
{
locked_ = false;
updateStatusWidgets();
}
@@ -188,7 +198,6 @@ void ContactFrame::contactDestroyed( QObject *object )
Q_UNUSED( object );
#endif
activated_ = false;
contact_ = 0;
detailedContact_ = 0;
}
@@ -216,6 +225,10 @@ void ContactFrame::copyText()
{
kapp->clipboard()->setText( detailedContact_->getPersonalMessage( STRING_CLEANED ) );
}
else if( action == popupCopyMusic_ && detailedContact_ != 0 )
{
kapp->clipboard()->setText( detailedContact_->getCurrentMediaString() );
}
else if( detailedContact_ != 0 )
{
// Copy the link from PM or Friendly Name
@@ -225,27 +238,6 @@ void ContactFrame::copyText()
void ContactFrame::editNotes()
{
// Check if there are details for contact
if( detailedContact_ != 0 && detailedContact_->getExtension() != 0 )
{
// Create the contact properties dialog
if( contactPropertiesDialog_ == 0 )
{
contactPropertiesDialog_ = new ContactPropertiesDialog( this );
}
else
{
contactPropertiesDialog_->clearLists();
}
contactPropertiesDialog_->launch( detailedContact_, true );
}
}
// The personal status message received an event.
bool ContactFrame::eventFilter( QObject *obj, QEvent *event )
{
@@ -274,7 +266,7 @@ bool ContactFrame::eventFilter( QObject *obj, QEvent *event )
return false; // don't stop processing.
}
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
// Show the menu regardlessly of where the mouse button has been pressed
showContactPopup( mouseEvent->globalPos() );
@@ -285,7 +277,7 @@ bool ContactFrame::eventFilter( QObject *obj, QEvent *event )
// Return the handle of this frame's contact
QString ContactFrame::getHandle() const
const QString& ContactFrame::getHandle() const
{
return handle_;
}
@@ -295,7 +287,8 @@ QString ContactFrame::getHandle() const
// Initialize the contact popup
bool ContactFrame::initContactPopup()
{
if( contact_ == 0 )
// Check if there is a valid contact_ and if contact action menu was already initialized
if( contact_ == 0 || contactActionPopup_ != 0 )
{
return false;
}
@@ -304,7 +297,8 @@ bool ContactFrame::initContactPopup()
popupStartPrivateChat_ = new KAction( KIcon("user-group-new"), i18n("&Start Private Chat"), this);
popupEmailContact_ = new KAction( KIcon("mail-message-new"), i18n("&Send Email"), this );
popupMsnProfile_ = new KAction( KIcon("preferences-desktop-user"), i18n("&View Profile"), this );
popupEditNotes_ = new KAction( KIcon("user-properties"), i18n("Ed&it Notes"), this );
//popupEditNotes_ = new KAction( KIcon("user-properties"), i18n("Ed&it Notes"), this );
popupContactProperties_ = new KAction( KIcon("user-properties"), i18n("&Properties"), this );
popupAddContact_ = new KAction( KIcon("list-add"), i18n("&Add Contact"), this );
popupAllowContact_ = new KAction( KIcon("dialog-ok-apply"), i18n("A&llow Contact"), this );
@@ -316,6 +310,12 @@ bool ContactFrame::initContactPopup()
popupCopyFriendlyName_ = new KAction( i18n("&Friendly Name"), this );
popupCopyPersonalMessage_ = new KAction( i18n("&Personal Message"), this );
popupCopyHandle_ = new KAction( i18n("&Email Address"), this );
popupCopyMusic_ = new KAction( i18n("Song &Name"), this );
popupPropGeneral_ = new KAction( KIcon("user-properties"), i18n("&Information"), this );
popupPropImages_ = new KAction( KIcon("draw-brush"), i18n("Display Pictures"), this );
popupPropNotes_ = new KAction( KIcon("document-edit"), i18n("&Notes"), this );
popupPropEmoticons_ = new KAction( KIcon("face-smile"), i18n("&Emoticons"), this );
// Connect the actions
@@ -323,7 +323,8 @@ bool ContactFrame::initContactPopup()
connect( popupEmailContact_, SIGNAL(triggered(bool)), this, SLOT( sendEmail() ) );
connect( popupMsnProfile_, SIGNAL(triggered(bool)), this, SLOT( showProfile() ) );
connect( popupEditNotes_, SIGNAL(triggered(bool)), this, SLOT( editNotes() ) );
//connect( popupEditNotes_, SIGNAL(triggered(bool)), this, SLOT( showContactProperties() ) );
//connect( popupContactProperties_, SIGNAL(triggered(bool)), this, SLOT( showContactProperties() ) );
connect( popupAddContact_, SIGNAL(triggered(bool)), this, SLOT( toggleContactAdded() ) );
connect( popupAllowContact_, SIGNAL(triggered(bool)), this, SLOT( allowContact() ) );
@@ -335,14 +336,26 @@ bool ContactFrame::initContactPopup()
connect( popupCopyFriendlyName_, SIGNAL(triggered(bool)), this, SLOT( copyText() ) );
connect( popupCopyPersonalMessage_, SIGNAL(triggered(bool)), this, SLOT( copyText() ) );
connect( popupCopyHandle_, SIGNAL(triggered(bool)), this, SLOT( copyText() ) );
connect( popupCopyMusic_, SIGNAL(triggered(bool)), this, SLOT( copyText() ) );
connect( popupPropGeneral_, SIGNAL(triggered(bool)), this, SLOT( showContactProperties() ) );
connect( popupPropImages_, SIGNAL(triggered(bool)), this, SLOT( showContactProperties() ) );
connect( popupPropNotes_, SIGNAL(triggered(bool)), this, SLOT( showContactProperties() ) );
connect( popupPropEmoticons_, SIGNAL(triggered(bool)), this, SLOT( showContactProperties() ) );
// Initialize sub popups
popupCopyMenu_ = new KActionMenu( i18n("&Copy"), this );
popupCopyMenu_ ->addAction( popupCopyFriendlyName_ );
popupCopyMenu_ ->addAction( popupCopyPersonalMessage_ );
popupCopyMenu_ ->addAction( popupCopyHandle_ );
popupCopyMenu_->addSeparator();
popupCopyMenu_ ->addAction( popupCopyMusic_ );
popupCopyMenu_ ->addSeparator();
popupPropMenu_ = new KActionMenu( i18n("&Properties"), this );
popupPropMenu_ ->addAction( popupPropGeneral_ );
popupPropMenu_ ->addAction( popupPropImages_ );
popupPropMenu_ ->addAction( popupPropNotes_ );
popupPropMenu_ ->addAction( popupPropEmoticons_ );
// Initialize the popup popup
contactActionPopup_ = new KMenu( handle_, this );
@@ -354,7 +367,7 @@ bool ContactFrame::initContactPopup()
contactActionPopup_->addAction( popupEmailContact_ );
contactActionPopup_->addAction( popupMsnProfile_ );
contactActionPopup_->addAction( popupCopyMenu_ );
contactActionPopup_->addAction( popupEditNotes_ );
//contactActionPopup_->addAction( popupEditNotes_ );
contactActionPopup_->addSeparator();
contactActionPopup_->addAction( popupAddContact_ );
@@ -365,19 +378,15 @@ bool ContactFrame::initContactPopup()
contactActionPopup_->addAction( popupRemoveContact_ );
contactActionPopup_->addSeparator();
contactActionPopup_->addAction( popupPropMenu_ );
return true;
}
// Whether or not the frame has been activated
bool ContactFrame::isActivated() const
{
return activated_;
}
// The user received a message from this contact
void ContactFrame::messageReceived()
{
@@ -460,35 +469,23 @@ void ContactFrame::setEnabled( bool isEnabled )
void ContactFrame::showContactPopup( const QPoint &point )
{
bool isAdded = false;
bool isAddable = ! locked_;
bool isAllowed = true;
bool isAllowed = false;
bool isBlocked = false;
bool isBlockable = ! locked_;
bool hasPersonalMessage = false;
bool hasMediaMessage = false;
// If detailed contact information is available
if( detailedContact_ != 0 )
{
isAddable = true;
isBlockable = true;
// We have the contact already in our list, but is possible to block/allow/unblock it
isAdded = detailedContact_->isFriend();
isAllowed = detailedContact_->isAllowed();
isBlocked = detailedContact_->isBlocked();
hasPersonalMessage = ! detailedContact_->getPersonalMessage().isEmpty();
}
hasMediaMessage = ! detailedContact_->getCurrentMediaString().isEmpty();
popupAllowContact_ ->setVisible( ! isAllowed );
popupCopyPersonalMessage_->setVisible( hasPersonalMessage );
popupAddContact_ ->setVisible( isAddable && ! isAdded );
popupRemoveContact_ ->setVisible( isAddable && isAdded );
popupBlockContact_ ->setVisible( isBlockable && ! isBlocked );
popupUnblockContact_ ->setVisible( isBlockable && isBlocked );
// If detailed contact information is available, search for links
if( detailedContact_ != 0 )
{
// Search for links
qDeleteAll( copyLinkActionsList_ );
copyLinkActionsList_.clear();
@@ -528,11 +525,78 @@ void ContactFrame::showContactPopup( const QPoint &point )
}
}
//popupEditNotes_ ->setVisible( detailedContact_ != 0 );
popupContactProperties_ ->setVisible( detailedContact_ != 0 );
popupMsnProfile_ ->setVisible( detailedContact_ != 0 );
popupAllowContact_ ->setVisible( ! isAllowed && ! isAdded && detailedContact_ != 0 );
popupCopyPersonalMessage_->setVisible( hasPersonalMessage );
popupCopyMusic_ ->setVisible( hasMediaMessage );
popupAddContact_ ->setVisible( ! locked_ && ! isAdded );
popupRemoveContact_ ->setVisible( ! locked_ && isAdded );
popupBlockContact_ ->setVisible( ! locked_ && ! isBlocked && detailedContact_ != 0 );
popupUnblockContact_ ->setVisible( ! locked_ && isBlocked );
contactActionPopup_->popup( point );
}
// Show the contact properties window
void ContactFrame::showContactProperties()
{
// Check if there are details for contact
if( detailedContact_ != 0 && detailedContact_->getExtension() != 0 )
{
// Default is not to open notes tab
ContactPropertiesDialog::DefaultTab defaultTab = ContactPropertiesDialog::Information;
// If we've been called via the edit notes action, open that tab
if( sender() == popupEditNotes_ )
{
defaultTab = ContactPropertiesDialog::Notes;
}
else if( sender() == popupPropImages_ )
{
defaultTab = ContactPropertiesDialog::Images;
}
else if( sender() == popupPropEmoticons_ )
{
defaultTab = ContactPropertiesDialog::Emoticons;
}
else if( sender() == popupPropImages_ )
{
defaultTab = ContactPropertiesDialog::Images;
}
else if( sender() == popupPropNotes_ )
{
defaultTab = ContactPropertiesDialog::Notes;
}
// the qlistwidget in the dialog doesn't seem to handle being reopened from
// a saved instance (unknown why). it causes display issues (i.e., displays the same
// groups multiple times or doesn't display them at all). This resolves the problem.
ContactPropertiesDialog *dialog = new ContactPropertiesDialog(this);
KMess *kmess = static_cast<KMessApplication*>( kapp )->getContactListWindow();
// HACK: MUST GO AFTER 2.0-final!!
connect( dialog, SIGNAL(addContactToGroup(QString, QString)),
kmess->getNsConnection(), SLOT( addContactToGroup(QString, QString) ) );
connect( dialog, SIGNAL(removeContactFromGroup(QString, QString)),
kmess->getNsConnection(), SLOT( removeContactFromGroup(QString, QString) ) );
dialog->launch( detailedContact_, defaultTab );
delete dialog;
}
}
// Show the contact's profile
void ContactFrame::showProfile()
{
@@ -542,7 +606,7 @@ void ContactFrame::showProfile()
}
// Create a URL to the msn profile page, localized with our system's locale.
KUrl url = KUrl( "http://members.msn.com/default.msnw?mem=" + handle_ + "&mkt=" + KGlobal::locale()->language() );
const KUrl url( "http://members.msn.com/default.msnw?mem=" + handle_ + "&mkt=" + KGlobal::locale()->language() );
// Launch the browser for the given URL
KMessShared::openBrowser( url );
@@ -584,16 +648,14 @@ void ContactFrame::toggleContactAdded()
if( detailedContact_ == 0 )
{
emit contactAdded( handle_, true );
// Disallow adding unknown contacts more than once
locked_ = true;
}
else
{
emit contactAdded( handle_, ! detailedContact_->isFriend() );
}
updateStatusWidgets();
// Disallow adding unknown contacts more than once
locked_ = true;
}
@@ -604,16 +666,14 @@ void ContactFrame::toggleContactBlocked()
if( detailedContact_ == 0 )
{
emit contactBlocked( handle_, true );
// Disallow adding unknown contacts more than once
locked_ = true;
}
else
{
emit contactBlocked( handle_, ! detailedContact_->isBlocked() );
}
updateStatusWidgets();
// Disallow adding unknown contacts more than once
locked_ = true;
}
@@ -701,7 +761,7 @@ void ContactFrame::updateStatusWidgets()
friendlyNameLabel_->setText( contact_->getFriendlyName( STRING_CHAT_SETTING_ESCAPED ) );
friendlyNameLabel_->setToolTip( contact_->getFriendlyName() );
statusPixmapLabel_->setToolTip( i18nc( "Tooltip for a contact's status icon, "
"arg %1 is the MSN Status, like 'Online'",
"arg %1 is the Live Messenger status, like 'Online'",
"The contact is %1",
statusIdentifier ) );
statusPixmapLabel_->setPixmap( MsnStatus::getIcon( status, flags ) );
+17 -9
View File
@@ -64,13 +64,11 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
// The destructor
~ContactFrame();
// Activate the frame by giving it a contact
void activate(ContactBase *contact);
void activate( ContactBase *contact );
// Return the handle of this frame's contact
QString getHandle() const;
const QString& getHandle() const;
// Initialize the contact popup
bool initContactPopup();
// Whether or not the frame has been activated
bool isActivated() const;
// The user received a message from this contact
void messageReceived();
// Change the display mode of the frame when the contact leaves the chat or there are many active contacts
@@ -87,16 +85,18 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
private slots: // Private slots
// Allow this contact to see our MSN status
void allowContact();
// Foward the changed list signal from contact
void contactChangedList();
// The contact was destroyed
void contactDestroyed( QObject *object );
// Copy some details of the contact to the clipboard
void copyText();
// Edit notes
void editNotes();
// Email the contact
void sendEmail();
// Update and show the contact popup menu
void showContactPopup( const QPoint &point );
// Show the contact properties window
void showContactProperties();
// Show the contact's profile
void showProfile();
// Request to start private chat
@@ -113,8 +113,6 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
void updateStatusWidgets();
private: // Private attributes
// Whether or not the frame has been activated
bool activated_;
// The contact whom the frame represents
ContactBase *contact_;
// The menu of actions possible to perform on a given contact
@@ -149,7 +147,9 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
KAction *popupAllowContact_;
// Contact popup KAction to block the contact
KAction *popupBlockContact_;
// Contact popup menu to show the friendly name/personal message copying options
// Contact popup menu to show the contact's properties window
KAction *popupContactProperties_;
// Contact popup menu to show the friendly name/personal message/media copying options
KActionMenu *popupCopyMenu_;
// Contact popup KAction to copy the contact's friendly name to clipboard
KAction *popupCopyFriendlyName_;
@@ -159,6 +159,8 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
KAction *popupCopyHandle_;
// Contact popup KAction to copy links from pm and friendly name
KAction *popupCopyLink_;
// Contact popup KAction to copy contact's media message
KAction *popupCopyMusic_;
// Contact popup KAction to edit notes
KAction *popupEditNotes_;
// Contact popup KAction to send an email to the contact
@@ -171,6 +173,12 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
KAction *popupStartPrivateChat_;
// Contact popup KAction to unblock the contact
KAction *popupUnblockContact_;
// popup actions for the properties menu
KActionMenu *popupPropMenu_;
KAction *popupPropGeneral_;
KAction *popupPropImages_;
KAction *popupPropNotes_;
KAction *popupPropEmoticons_;
// A timer to time the duration that the typing label is shown
QTimer typingTimer_;
+6 -6
View File
@@ -5,8 +5,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>86</width>
<height>119</height>
<width>112</width>
<height>149</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout" >
@@ -108,14 +108,14 @@
</property>
<property name="minimumSize" >
<size>
<width>64</width>
<height>64</height>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="maximumSize" >
<size>
<width>64</width>
<height>64</height>
<width>96</width>
<height>96</height>
</size>
</property>
<property name="cursor" >
+15 -33
View File
@@ -21,6 +21,7 @@
#include "../accountsmanager.h"
#include "../currentaccount.h"
#include "../kmessdebug.h"
#include "../network/msnswitchboardconnection.h"
#include <QDockWidget>
@@ -74,13 +75,10 @@ ContactsWidget::~ContactsWidget()
void ContactsWidget::contactAdded( Contact *contact )
{
// Update any invited contact frame
foreach( ContactFrame *frame, contactFrames_ )
ContactFrame *contactFrame = getContactFrameByHandle( contact->getHandle() );
if ( contactFrame != 0 )
{
if( frame->getHandle() == contact->getHandle() )
{
frame->activate( contact );
break;
}
contactFrame->activate( contact );
}
}
@@ -107,7 +105,7 @@ void ContactsWidget::contactJoined( ContactBase* contact )
ContactFrame::DisplayMode frameMode;
// Get the first available contact frame
contactFrame = getFirstInactiveContactFrame();
contactFrame = createContactFrame();
if( KMESS_NULL(contactFrame) ) return;
// Activate the frame
@@ -140,6 +138,7 @@ void ContactsWidget::contactLeft( ContactBase *contact, bool /*isChatIdle*/ )
kDebug() << handle;
#endif
ContactFrame::DisplayMode frameMode;
// Delete the frames whenever there is more than one; when only one is left, grey it out instead.
@@ -170,13 +169,10 @@ void ContactsWidget::contactLeft( ContactBase *contact, bool /*isChatIdle*/ )
void ContactsWidget::contactRemoved( Contact *contact )
{
// Update any invited contact frame
foreach( ContactFrame *frame, contactFrames_ )
ContactFrame *contactFrame = getContactFrameByHandle( contact->getHandle() );
if ( contactFrame != 0 )
{
if( frame->getHandle() == contact->getHandle() )
{
frame->activate( 0 );
break;
}
contactFrame->activate( 0 );
}
}
@@ -256,7 +252,6 @@ inline ContactFrame::DisplayMode ContactsWidget::getBestFrameMode()
// Find out how many are chatting at the moment
int count = contactFrames_.count();
if( count > 5 )
{
// More than 5 contacts in chat with us: it's a big group chat and we need to be able to display as many frames as possible
@@ -280,7 +275,7 @@ inline ContactFrame::DisplayMode ContactsWidget::getBestFrameMode()
// Find the contact frame with the given handle
ContactFrame* ContactsWidget::getContactFrameByHandle(const QString& handle)
ContactFrame* ContactsWidget::getContactFrameByHandle( const QString& handle )
{
foreach( ContactFrame *contactFrame, contactFrames_ )
{
@@ -295,22 +290,10 @@ ContactFrame* ContactsWidget::getContactFrameByHandle(const QString& handle)
// Return the first inactive contact frame
ContactFrame* ContactsWidget::getFirstInactiveContactFrame()
// Return one new contact frame
ContactFrame* ContactsWidget::createContactFrame()
{
ContactFrame *contactFrame;
// If there's an inactive frame, use it
foreach( contactFrame, contactFrames_ )
{
if( ! contactFrame->isActivated() )
{
return contactFrame;
}
}
// Well we don't have any, so make another.
contactFrame = new ContactFrame( container_ );
ContactFrame *contactFrame = new ContactFrame( container_ );
connect( contactFrame, SIGNAL( startPrivateChat( const QString& ) ),
this, SIGNAL( startPrivateChat( const QString& ) ) );
@@ -333,10 +316,9 @@ ContactFrame* ContactsWidget::getFirstInactiveContactFrame()
// A message was received from one of the contacts... notify its frame
void ContactsWidget::messageReceived(const QString& handle)
void ContactsWidget::messageReceived( const QString& handle )
{
ContactFrame *frame;
frame = getContactFrameByHandle( handle );
ContactFrame *frame = getContactFrameByHandle( handle );
if ( frame != 0 )
{
frame->messageReceived();
+3 -3
View File
@@ -88,14 +88,14 @@ class ContactsWidget : public QWidget, private Ui::ContactsWidget
void startPrivateChat( const QString &handle );
private: // Private methods
// The user picture frame received an event
// Return one new contact frame
ContactFrame* createContactFrame();
// The user picture frame received an event
bool eventFilter( QObject *obj, QEvent *event );
// Get the most suitable frame size, depending on how many contacts are currently in chat with us
ContactFrame::DisplayMode getBestFrameMode();
// Find the contact frame with the given handle
ContactFrame* getContactFrameByHandle(const QString& handle);
// Return the first inactive contact frame
ContactFrame* getFirstInactiveContactFrame();
private: // Private attributes
// The list of frames contained in the widget
+6
View File
@@ -22,6 +22,9 @@
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="styleSheet">
<string>QScrollArea#area_ { background-color: transparent }</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
@@ -40,6 +43,9 @@
<height>120</height>
</rect>
</property>
<property name="styleSheet">
<string>QWidget#container_ { background-color: transparent }</string>
</property>
</widget>
</widget>
</item>
+4 -2
View File
@@ -92,6 +92,8 @@ EmoticonListWidget::EmoticonListWidget( QWidget *parent )
setViewMode( QListView::IconMode );
setResizeMode( QListView::Adjust );
setIconSize( QSize( 16,16 ) );
setGridSize( QSize( 20,20 ) );
setUniformItemSizes( true );
setMovement( QListView::Static );
setSelectionMode( QAbstractItemView::SingleSelection );
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
@@ -284,7 +286,7 @@ void EmoticonsWidget::slotThemeUpdated()
noEmoticonsWarning_->setScaledContents( true );
noEmoticonsWarning_->setWordWrap( true );
noEmoticonsWarning_->setText( i18nc( "Informative label on the chat's emoticons bar",
"<html><p><b>You haven't added any custom emoticons yet.</b></p>"
"<html><p><b>You have not added any custom emoticons yet.</b></p>"
"<p>To add new emoticons, <a href='#'>click here</a>!</p></html>" ) );
// Enable the link click action
@@ -324,7 +326,7 @@ void EmoticonsWidget::slotThemeUpdated()
continue;
}
QListWidgetItem *item = new QListWidgetItem( QIcon( emoticon->getPicturePath() ), "", list_ );
QListWidgetItem *item = new QListWidgetItem( QIcon( emoticon->getPicturePath() ), QString(), list_ );
// Set the shortcut into data of current item widget
item->setData( ShortcutRole, emoticon->getShortcut() );
+173 -25
View File
@@ -3,7 +3,9 @@
-------------------
begin : Wed May 14 2008
copyright : (C) 2008 by Antonio Nastasi
(C) 2009 by Sjors Gielen
email : sifcenter@gmail.com
dazjorz@kmess.org
***************************************************************************/
/***************************************************************************
@@ -18,14 +20,25 @@
#include "inkedit.h"
#include "../kmessdebug.h"
#include "config-kmess.h"
#if KMESS_ENABLE_INK == 1
#include <gif_lib.h>
#endif
#include <KIcon>
#include <KColorDialog>
#include <QBuffer>
#include <QMouseEvent>
#include <QPainter>
#include <QPen>
#include <QTemporaryFile>
#ifdef KMESSDEBUG_INKEDIT
#define KMESSDEBUG_INKEDIT_GENERAL
#endif
@@ -81,12 +94,7 @@ void InkEdit::clearImage()
// Change color for current pen
void InkEdit::changeColor()
{
QColor color;
int result = KColorDialog::getColor( color );
if ( result == KColorDialog::Accepted )
{
color_ = color;
}
KColorDialog::getColor( color_ );
}
@@ -102,32 +110,49 @@ void InkEdit::cropImage( QPoint position )
int sizePen = sizePen_->value();
int minX = position.x() - sizePen;
int maxX = position.x() + sizePen;
int minY = position.y() - sizePen;
int maxY = position.y() + sizePen;
// Fix min and max to never spread larger than the image
// First fix max to not be bigger than the image, then fix min, then max again
maxX = qBound( 0, maxX, image_->pixels.width() );
minX = qBound( 0, minX, maxX );
maxX = qBound( minX, maxX, maxX );
// Same for Y
maxY = qBound( 0, maxY, image_->pixels.height() );
minY = qBound( 0, minY, maxY );
maxY = qBound( minY, maxY, maxY );
// Adjust the initial size and position
if( image_->area.topLeft().x() == - 1 || image_->area.topLeft().y() == -1 )
if( image_->area.right() == -1 || image_->area.bottom() == -1 )
{
image_->area.setTopLeft( QPoint( position.x(), position.y() ) );
image_->area.setBottomRight( QPoint( position.x() + sizePen , position.y() + sizePen ) );
image_->area.setLeft ( minX );
image_->area.setRight ( maxX );
image_->area.setTop ( minY );
image_->area.setBottom( maxY );
return;
}
// Adjust the x position and width
if( position.x() < image_->area.topLeft().x() )
if( minX < image_->area.left() )
{
image_->area.setTopLeft( QPoint( position.x() - sizePen , image_->area.topLeft().y() ) );
image_->area.setLeft( minX );
}
else if( position.x() > image_->area.bottomRight().x() )
if( maxX > image_->area.right() )
{
image_->area.setBottomRight( QPoint( position.x() + sizePen, image_->area.bottomRight().y() ) );
image_->area.setRight( maxX );
}
// Adjust the y position and height
if( position.y() < image_->area.topLeft().y() )
if( minY < image_->area.top() )
{
image_->area.setTopLeft( QPoint( image_->area.topLeft().x(), position.y( ) - sizePen ) );
image_->area.setTop( minY );
}
else if( position.y() > image_->area.bottomRight().y() )
if( maxY > image_->area.bottom() )
{
image_->area.setBottomRight( QPoint( image_->area.bottomRight().x() , position.y()+ sizePen ) );
image_->area.setBottom( maxY );
}
}
@@ -143,6 +168,7 @@ void InkEdit::drawLineTo( const QPoint &endPoint )
}
QPainter painter( &(image_->pixels) );
painter.setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform, true );
QColor color = color_;
if( erasingImage_ )
@@ -181,7 +207,7 @@ void InkEdit::eraseBrush()
// Return if the image is empty
// Returns true if the image is empty
bool InkEdit::isEmpty()
{
return isEmpty_;
@@ -247,8 +273,10 @@ void InkEdit::mouseReleaseEvent(QMouseEvent *event)
void InkEdit::paintEvent(QPaintEvent */*event*/)
void InkEdit::paintEvent(QPaintEvent *event)
{
Q_UNUSED( event );
if( image_ == 0 || image_->pixels.isNull() )
{
kWarning() << "Uninitialized usage of InkEdit!";
@@ -290,7 +318,7 @@ InkImage *InkEdit::getImage()
// Return the bytes rapresents the image
// Return the bytes representing the image
const QByteArray& InkEdit::getImageBytes()
{
if( image_ == 0 )
@@ -300,11 +328,131 @@ const QByteArray& InkEdit::getImageBytes()
return imageBytes_;
}
QBuffer buffer( &imageBytes_ );
buffer.open( QIODevice::WriteOnly );
image_->pixels.copy( image_->area ).save( &buffer, "PNG" );
//image_->pixels.scaled( size(), Qt::KeepAspectRatio, Qt::SmoothTransformation ).save( &buffer, "PNG" );
#if KMESS_ENABLE_INK == 1
// Copy the interesting piece of the image over to a new image
QImage image = image_->pixels.copy( image_->area ).convertToFormat( QImage::Format_Indexed8, Qt::ThresholdDither );
// Initialise the gif variables
GifFileType *gft = NULL;
ColorMapObject *cmap = NULL;
int height = image.height();
int width = image.width();
bool gifError = false;
// Open a temporary file
QTemporaryFile tempFile( "kmess-ink-XXXXXX.gif" );
QFile tempFile2;
if( ! tempFile.open() )
{
kWarning() << "Couldn't open temporary file for GIF conversion.";
goto error;
}
#ifdef KMESSDEBUG_INKEDIT_GENERAL
kDebug() << "Created temporary file to convert ink to GIF image.";
#endif
// Convert the image to GIF using libgif
// This is needed because Windows Live Messenger (at least 2009) does not display inks
// which are not in GIF format (it doesn't even give an error).
gifError = true;
// Open the gif file
gft = EGifOpenFileHandle( tempFile.handle() );
if( gft == 0 )
{
kWarning() << "Couldn't initialize gif library.";
goto error;
}
// Create the color map
cmap = MakeMapObject( image.numColors(), NULL );
if( cmap == 0 )
{
kWarning() << "Couldn't create map object for gif conversion (num colors = " << image.numColors() << ")";
goto error;
}
// Fill in the color map with the colors in the image color table
for( int i = 0; i < image.numColors(); i++ )
{
QRgb color = image.color( i );
cmap->Colors[i].Red = qRed( color );
cmap->Colors[i].Green = qGreen( color );
cmap->Colors[i].Blue = qBlue( color );
}
// Initialize the GIF file
if( EGifPutScreenDesc( gft, width, height, 8, 0, cmap) == GIF_ERROR )
{
kWarning() << "EGifPutScreenDesc failed.";
goto error;
}
// Initialize the GIF image
if( EGifPutImageDesc( gft, 0, 0, width, height, 0, NULL) == GIF_ERROR )
{
kWarning() << "EGifPutImageDesc failed.";
goto error;
}
// Write every line
for( int j = 0; j < height; j++ )
{
// FIXME: This is the point where the artifacts are made. I don't know why, but if you run:
// EGifPutLine( gft, image.bits(), image.width() * image.height() ) // i.e. convert the complete image in one call
// then the image is mangled, so something is wrong with the width or so, it seems to be off by two pixels or so. (Try it!)
//if( EGifPutLine( gft, image.scanLine( j ), width ) == GIF_ERROR )
if( EGifPutLine( gft, image.scanLine( j ), width ) == GIF_ERROR )
{
kWarning() << "EGifPutLine failed for scanline" << j << "(height=" << image.height() << ";width=" << image.width() << ";bytesperline=" << image.bytesPerLine() << ")";
goto error;
}
}
// Clean up the GIF converter etc
EGifCloseFile( gft );
FreeMapObject( cmap );
gifError = false;
// Read the file back in
// Because the QTemporaryFile is opened in unbuffered mode, we have to flush it then re-open it with QFile.
tempFile.flush();
tempFile2.setFileName( tempFile.fileName() );
if( ! tempFile2.open( QIODevice::ReadOnly | QIODevice::Unbuffered ) )
{
kWarning() << "Couldn't reopen temporary file: " << tempFile2.errorString();
goto error;
}
imageBytes_ = tempFile2.readAll();
tempFile2.close();
tempFile.close();
#ifdef KMESSDEBUG_INKEDIT_GENERAL
kDebug() << "Converted ink to GIF (" << image.height() << "x" << image.width() << "), sending " << imageBytes_.size() << " bytes of image data.";
#endif
return imageBytes_;
error:
if( gifError )
{
kWarning() << "A GIF error occured in getImageBytes, returning empty byte array. The error was: ";
PrintGifError();
}
else
{
kWarning() << "A non-GIF error occured in getImageBytes, returning empty byte array.";
}
imageBytes_.clear();
return imageBytes_;
#else // KMESS_ENABLE_INK
imageBytes_.clear();
return imageBytes_;
#endif // KMESS_ENABLE_INK
}

Some files were not shown because too many files have changed in this diff Show More