Compare commits

...

19 Commits

Author SHA1 Message Date
Mario Fetka 0823ec1137 Bump version to 6.0 alpha6 2026-07-07 18:44:21 +02:00
Mario Fetka 1c4ebcccd1 Restore KF6 single instance behavior 2026-07-07 18:40:15 +02:00
Mario Fetka 9fd7e99274 Bump version to 6.0 alpha5 2026-07-06 13:58:09 +02:00
Mario Fetka bf567146d8 Clean up KF6 chat window warnings 2026-07-06 13:51:57 +02:00
Mario Fetka 3bade98d2f Harden address book updates for Escargot 2026-07-06 13:38:43 +02:00
Mario Fetka bd03359d79 Bump version to 6.0 alpha4 2026-07-06 13:21:16 +02:00
Mario Fetka 89b4218853 Handle missing Escargot profile URL 2026-07-06 13:14:56 +02:00
Mario Fetka f9f479588f Fix Escargot privacy mode mapping 2026-07-06 12:40:45 +02:00
Mario Fetka 40e81af6c6 Keep Escargot login alive without storage profile 2026-07-06 11:48:10 +02:00
Mario Fetka 10db33e21e Bump version to 6.0 alpha3 2026-07-06 09:46:58 +02:00
Mario Fetka 78cb2bc641 Port isf-qt to giflib 5 and clean build warnings 2026-07-06 09:37:59 +02:00
Mario Fetka 0c67ad480c Point roaming storage at Escargot service host 2026-07-06 08:05:06 +02:00
Mario Fetka 141bff5dd3 Bump version to 6.0 alpha2 2026-07-06 07:42:20 +02:00
Mario Fetka ae8f851b06 Fix KF6 runtime integration warnings 2026-07-06 07:37:58 +02:00
Mario Fetka 65d3f78a14 Fix contact list model teardown crash 2026-07-06 07:29:12 +02:00
Mario Fetka f2fbc7463b Port KMess to KF6 and Qt6 2026-07-06 07:16:41 +02:00
Mario Fetka 91626a9c87 Import release 2.0.6.2 2012-03-02 20:51:47 +00:00
Mario Fetka 858a70fe82 Import release 2.0.6.1 2011-02-17 09:46:29 +00:00
Mario Fetka 3200be221c Import release 2.0.6 2011-02-08 19:31:37 +00:00
284 changed files with 7103 additions and 6954 deletions
-16
View File
@@ -1,16 +0,0 @@
# Build files and dirs
build*
# KDevelop and other IDE-specific project files
*.kdev*
# Doxygen files
apidocs/
kmess.tag
# Mac stuff
.DS_Store
finkbuild
# ./configure script stuff
Makefile
-3
View File
@@ -1,3 +0,0 @@
[submodule "contrib/isf-qt"]
path = contrib/isf-qt
url = git://gitorious.org/kmess/libisf-qt.git
+2 -1
View File
@@ -115,7 +115,7 @@
Japanese:
Daniel E. Moctezuma <shinsen27@gmail.com>
Daniel E. Moctezuma <dmoctezuma@kmess.org>
Korean:
@@ -253,6 +253,7 @@
Timo Tambet <ttambet@gmail.com>
- Contact Changed and Group Changed notifications.
- Contact added user dialog tabbing
KMerlin <http://kmerlin.olsd.de/>
- Inspiration and assorted code
+86 -252
View File
@@ -1,267 +1,101 @@
PROJECT( kmess )
cmake_minimum_required(VERSION 3.16)
project(kmess VERSION 6.0.0 LANGUAGES C CXX)
#### System checks ####
find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH}
${ECM_MODULE_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# To add checks, see in one or more of these paths
# /usr/share/cmake/Modules
# /usr/share/kde4/apps/cmake/modules
# /usr/share/apps/cmake
set(BUILD_WITH_QT6 ON CACHE BOOL "Build against Qt 6" FORCE)
set(QT_DEFAULT_MAJOR_VERSION 6)
# Check for cmake, same as minimum for KDE 4.0.0
CMAKE_MINIMUM_REQUIRED( VERSION 2.4.5 )
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
# Check for KDE 4
FIND_PACKAGE( KDE4 REQUIRED )
INCLUDE( KDE4Defaults )
find_package(Qt6 REQUIRED COMPONENTS Core Core5Compat DBus Gui Multimedia Network Test WebEngineWidgets Widgets Xml)
find_package(KF6 REQUIRED COMPONENTS
Codecs
Completion
Config
ConfigWidgets
CoreAddons
Crash
DBusAddons
IdleTime
I18n
IconThemes
KIO
Notifications
NotifyConfig
Parts
Service
Solid
StatusNotifierItem
TextWidgets
WidgetsAddons
WindowSystem
Wallet
XmlGui
)
# Make sure the rest still works
IF( NOT KDE4_FOUND )
# The macro's MACRO_LOG_FEATURE, MACRO_OPTIONAL_FIND_PACKAGE, MACRO_BOOL_TO_01
# are part of the KDE cmake modules, so these can't be used now.
find_package(LibXml2 REQUIRED)
find_package(LibXslt REQUIRED)
find_package(GCrypt REQUIRED)
MESSAGE( FATAL_ERROR "\n"
" The KDE Development Platform was not found.\n"
" \n"
" You will need this package and the matching development package.\n"
" Usually the package names for this library are:\n"
" on Debian and Ubuntu: 'kdebase-runtime' and 'kdelibs5-dev'\n"
" on openSUSE: 'kdebase4-runtime' and 'libkde4-devel'\n"
" \n"
" Please refer to the KMess board for more info,\n"
" and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
ENDIF( NOT KDE4_FOUND )
set(ISFQT_IS_BUNDLED TRUE)
set(USE_BUNDLED_LIBRARIES ISFQT)
add_subdirectory(contrib/isf-qt)
# Check for libxml2
FIND_PACKAGE( LibXml2 )
MACRO_LOG_FEATURE( LIBXML2_FOUND "LibXML2" "Libraries used to develop XML-aware applications" "http://www.xmlsoft.org/" TRUE ""
"Required for the chat styles system.
* You will need this package and the matching development package: for example, 'libxml2' and 'libxml2-dev' or 'libxml2-devel'.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libxml2' and 'libxml2-dev'
on openSUSE: 'libxml2' and 'libxml2-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
option(KMESS_DISABLE_LIKEBACK "Disable the old LikeBack feedback UI" ON)
if(KMESS_DISABLE_LIKEBACK)
set(KMESS_DISABLE_LIKEBACK 1)
else()
set(KMESS_DISABLE_LIKEBACK 0)
endif()
# Check for libxslt
FIND_PACKAGE( LibXslt )
MACRO_LOG_FEATURE( LIBXSLT_FOUND "LibXSLT" "A library to transform XML into other formats" "http://www.xmlsoft.org/XSLT" TRUE ""
"Required for the chat styles system.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libxslt' and 'libxslt1-dev'
on openSUSE: 'libxslt' and 'libxslt-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
set(KMESS_VERSION "6.0_alpha6")
set(KMESS_ENABLE_DEBUG_OUTPUT 0)
set(KMESS_BUILT_DEBUGFULL FALSE)
set(HAVE_LIBISFQT 1)
set(HAVE_NEW_TRAY 1)
# Add cmake directory to the MODULE_PATH, so cmake can find GCrypt
SET( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} $ENV{CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake )
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Check for GCrypt
FIND_PACKAGE( GCrypt )
IF( NOT GCRYPT_FOUND )
MACRO_LOG_FEATURE( GCRYPT_FOUND "GCrypt" "A library to encrypt messages with various cyphers" "http://www.gnupg.org/" TRUE ""
"It is required for the Live Messenger login process.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libgcrypt' and 'libgcrypt11-dev'
on openSUSE: 'libgcrypt' and 'libgcrypt-devel'
on Fedora: 'gcrypt' and 'gcrypt-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
ELSE()
MESSAGE( STATUS "Looking for GCrypt - found" )
ENDIF()
add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050F00 -DQT_NO_URL_CAST_FROM_STRING)
# Check for XScreenSaver extension
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 Debian and Ubuntu: 'libxss-dev'
on openSUSE: 'xorg-x11-libs'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
ELSE( X11_FOUND )
MESSAGE( STATUS "NOTE: The auto-away feature is not supported on this platform yet." )
ENDIF( X11_FOUND )
ENDIF( WANT_XSCREENSAVER )
# Compatibility variables kept for old subdirectory install rules while the
# source tree is being ported away from KDE4-era CMake.
set(BIN_INSTALL_DIR ${KDE_INSTALL_BINDIR})
set(CONFIG_INSTALL_DIR ${KDE_INSTALL_CONFDIR})
set(DATA_INSTALL_DIR ${KDE_INSTALL_DATADIR})
set(HTML_INSTALL_DIR ${KDE_INSTALL_DOCBUNDLEDIR})
set(ICON_INSTALL_DIR ${KDE_INSTALL_ICONDIR})
set(LOCALE_INSTALL_DIR ${KDE_INSTALL_LOCALEDIR})
set(PLUGIN_INSTALL_DIR ${KDE_INSTALL_PLUGINDIR})
set(SERVICES_INSTALL_DIR ${KDE_INSTALL_KSERVICESDIR})
set(SHARE_INSTALL_PREFIX ${KDE_INSTALL_DATADIR})
set(SOUND_INSTALL_DIR ${KDE_INSTALL_SOUNDDIR})
set(XDG_APPS_INSTALL_DIR ${KDE_INSTALL_APPDIR})
# Check for libkonq
# QUIET is to fix compiling on systems like Debian Lenny, which don't have FindLibKonq.cmake
# (for an optional feature, we don't want that to be fatal)
MACRO_OPTIONAL_FIND_PACKAGE( LibKonq QUIET )
MACRO_LOG_FEATURE( LIBKONQ_FOUND "LibKonq" "Integration with Konqueror context menu" "http://www.kde.org/" FALSE ""
"This is an optional feature.
* Usually the package names for this library are:
on Debian and Ubuntu: 'libkonq5' and 'libkonq5-dev'
on openSUSE: 'libkonq5' and 'libkonq-devel'
* Please refer to the KMess board for more info,
and specially to this guide: http://trac.kmess.org/wiki/Compiling%20KMess" )
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/config-kmess.h.in
${CMAKE_CURRENT_BINARY_DIR}/config-kmess.h)
# Check for libisf-qt
MACRO_OPTIONAL_FIND_PACKAGE( IsfQt QUIET )
MACRO_LOG_FEATURE( ISFQT_FOUND "LibISF-Qt" "Library to manage Microsoft's Mobile Ink" "http://www.kmess.org/" FALSE ""
"Support to send handwriting messages in a format compatible with Windows Live Messenger.
In absence of an installed isf-qt version, the bundled version will be compiled.")
MACRO_BOOL_TO_01( ISFQT_FOUND HAVE_LIBISFQT ) # For config-kmess.h.in
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${LIBXML2_INCLUDE_DIR}
${LIBXSLT_INCLUDE_DIR}
${GCRYPT_INCLUDE_DIRS}
)
# Check for KNotificationItem. KDE 4.3.1 and later have it integrated in kdelibs/experimental.
# It will be available by default in 4.4.
IF( ${KDE_VERSION} VERSION_LESS 4.3.70 ) # KDE trunk has a higher version number than this.
MACRO_OPTIONAL_FIND_PACKAGE(LibKNotificationItem-1)
MACRO_LOG_FEATURE( LIBKNOTIFICATIONITEM-1_FOUND "LibKNotificationItem-1" "The experimental new KDE systray library" "http://www.kde.org" FALSE ""
"LibKNotificationItem-1 is the experimental new KDE systray library. It will be included
by default in KDE 4.4 and is available for use in KDE 4.3.1 and above." )
MACRO_BOOL_TO_01( LIBKNOTIFICATIONITEM-1_FOUND HAVE_NEW_TRAY )
ELSE()
SET( HAVE_NEW_TRAY 1 )
ENDIF()
# Display the dependency collection results
MACRO_DISPLAY_FEATURE_LOG()
#### Configure build ####
INCLUDE( MacroLibrary )
INCLUDE( KDE4Defaults )
IF( NOT ISFQT_FOUND )
# isf-qt is not installed on the system.
# use the bundled version.
SET( ISFQT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/isf-qt/include )
SET( ISFQT_LIBRARIES isf-qt )
SET( USE_BUNDLED_LIBRARIES ${USE_BUNDLED_LIBRARIES} ISFQT )
SET( HAVE_LIBISFQT 1 )
SET( ISFQT_FOUND TRUE )
ENDIF( NOT ISFQT_FOUND )
ADD_DEFINITIONS( ${QT_DEFINITIONS} ${KDE4_DEFINITIONS} )
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${LIBXML2_INCLUDE_DIR} )
#### 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-git-version.sh OUTPUT_VARIABLE KMESS_VERSION )
SET( KMESS_VERSION "2.0.5" )
#### Define compiler flags ####
# Tune the debug build with even more flags
# also see FindKDE4Internal.cmake for more defaults
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" )
# 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 )
# Define the default build type
# Possible values:
# - none
# - release
# - debug
# - debugfull (even fewer optimisations)
# - relwithdebinfo (release with debug info)
# - minsizerel (minsize release)
# Uncomment the next line to always force building in full debug mode
# SET( CMAKE_BUILD_TYPE debugfull )
# Enable the KMess debug output when compiling a debug build
IF( CMAKE_BUILD_TYPE STREQUAL debugfull OR KMESS_DEBUG_OUTPUT EQUAL 1 )
SET( KMESS_ENABLE_DEBUG_OUTPUT "1" )
ELSE( CMAKE_BUILD_TYPE STREQUAL debugfull OR KMESS_DEBUG_OUTPUT EQUAL 1 )
SET( KMESS_ENABLE_DEBUG_OUTPUT "0" )
ENDIF( CMAKE_BUILD_TYPE STREQUAL debugfull OR KMESS_DEBUG_OUTPUT EQUAL 1 )
# Change symbol visibility, to obtain clearer KDE backtraces
SET( __KDE_HAVE_GCC_VISIBILITY 0 )
# 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 )
# Set a default installation path
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 ####
# Generate config-kmess.h
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/config-kmess.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-kmess.h )
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
# continue in directories
ADD_SUBDIRECTORY( po )
ADD_SUBDIRECTORY( data )
ADD_SUBDIRECTORY( doc )
ADD_SUBDIRECTORY( src )
IF( LIBKONQ_FOUND )
ADD_SUBDIRECTORY( src/utils/kmess-send )
ENDIF( LIBKONQ_FOUND )
IF( USE_BUNDLED_LIBRARIES MATCHES "ISFQT" )
ADD_SUBDIRECTORY( contrib/isf-qt )
ENDIF( )
# Also add the tests if compiling in development mode
IF( CMAKE_BUILD_TYPE STREQUAL debugfull AND KMESS_DEBUG_OUTPUT EQUAL 1 )
ADD_SUBDIRECTORY( tests )
ENDIF( CMAKE_BUILD_TYPE STREQUAL debugfull AND KMESS_DEBUG_OUTPUT EQUAL 1 )
add_subdirectory(po)
add_subdirectory(data)
add_subdirectory(src)
+67
View File
@@ -1,3 +1,70 @@
--- 2.0.6.2 released ---
2011-11-26 (Dmoctezuma)
* Follow Location redirects, MS seems to have moved some accounts
to other servers. (patch by Lekensteyn)
2011-04-12 (Sjors)
* Apply a patch by Francesco Nwokeka, fixing a part of #480 by moving
file transfer settings into its own tab in the settings screen.
* Include Phonon headers correctly.
2011-04-10 (Ruben)
* Fixed XML for DBus interface
2011-04-03 (Dmoctezuma)
* Updated email address.
2011-03-14 (Dmoctezuma)
* Updated Japanese translation.
2011-02-27 (Dmoctezuma)
* Updated Japanese translation.
2011-02-25 (Adam)
* Fix bug where KMess would fail to build on relwithdebinfo builds when
--enable-debug-output was set
--- 2.0.6.1 released ---
2011-02-16 (Adam)
* Fix yet another login bug caused because our initial profile data no
longer includes a language preference.
--- 2.0.6 released ---
2011-01-13 (Adam)
* Fix bug where KMess couldn't login due to badly formed URL commands.
2011-01-08 (Valerio)
* Fixed crash when taking any action in the Contact Added User dialog.
Also removed an unnecessary signal-bouncing slot.
* Fixed a dangling pointer issue when the Contact Added User dialog was
shown, closed and shown again.
2011-01-05 (Adam)
* Add new widget, FaderWidget, which smoothly fades between the initial view
and the contact list. Disable by setting NoFadeEffect to true under the
MainWindow section of kmessrc.
2011-01-02 (Pano)
* Merged an updated Japanese translation by Daniel E. Moctezuma.
* Merged an updated Spanish translation by Daniel E. Moctezuma.
* Merged an updated German translation.
2010-12-24 (Adam)
* Fix retrieval of roaming display picture.
2010-12-23 (Adam)
* Fix a problem where roaming service profile data was invalid.
2010-12-13 (Valerio)
* Fixed "Visit Link" context-menu icon in chat. Thanks to IRC's agostino for the
heads-up.
2010-11-16 (Adam)
* (Finally) merged in a modified patch by Timo Tambet that groups all
"contact added user" windows as tabs under a single dialog.
--- 2.0.5 released ---
+1 -1
View File
@@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = KMess
PROJECT_NUMBER = 2.0.5
PROJECT_NUMBER = 2.0.6.2
OUTPUT_DIRECTORY = ./apidocs
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
+30 -3
View File
@@ -1,8 +1,35 @@
Changes between KMess SVN and 2.0.5:
Changes between KMess Git and 2.0.6.2:
--------------------------------------
- None yet.
- None yet
Changes between KMess 2.0.6.2 and 2.0.6.1:
------------------------------------------
- Follow redirects, fixing connection issue. Thanks to Lekensteyn.
- Moved file transfer settings into own tab.
- updated Japanese translation by Daniel E. Moctezuma.
Changes between KMess 2.0.6.1 and 2.0.6:
----------------------------------------
- fix bug where KMess couldn't login due to missing language preference information.
Changes between KMess 2.0.6 and 2.0.5:
--------------------------------------
- fix bug where KMess couldn't login due to badly formed URL commands.
- fixed crash when taking any action in the Contact Added User dialog.
- fixed a possible crash when using the Contact Added User dialog.
- Added a fading effect when switching between the initial view and the contact list.
- fixed retrieval of display pictures from online MSN storage.
- fixed a problem where roaming service profile data was invalid.
- fixed "Visit Link" context-menu icon in chat. Thanks to IRC's agostino.
- improved Contact Added User dialog with tabs. Thanks ti Timo Tambet.
- updated Japanese translation by Daniel E. Moctezuma.
- updated Spanish translation by Daniel E. Moctezuma.
- updated German translation.
Changes between KMess 2.0.5 and 2.0.4:
--------------------------------------
Executable → Regular
View File
+4 -1
View File
@@ -11,6 +11,9 @@
/* Define if debug output should be enabled */
#define KMESS_DEBUG ${KMESS_ENABLE_DEBUG_OUTPUT}
/* Define what the build type of KMess is */
#cmakedefine KMESS_BUILT_DEBUGFULL ${KMESS_BUILD_DEBUGFULL}
/* Define the fallback prefix */
#define KMESS_PREFIX "${CMAKE_INSTALL_PREFIX}"
@@ -24,4 +27,4 @@
#define KMESS_ENABLE_INK ${HAVE_LIBISFQT}
/* Define whether we have the new system tray */
#cmakedefine HAVE_NEW_TRAY
#cmakedefine HAVE_NEW_TRAY
Executable → Regular
View File
Vendored Executable → Regular
+1 -1
View File
@@ -54,7 +54,7 @@ DEBUG=0
# Globals
cd `dirname $0`
SRC_DIR="$PWD"
KMESS_VER="`./cmake/get-svn-version.sh`"
KMESS_VER="`./cmake/get-git-version.sh`"
+3 -4
View File
@@ -1,5 +1,5 @@
PROJECT( isf-qt )
CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
CMAKE_MINIMUM_REQUIRED( VERSION 3.16 )
PROJECT( isf-qt LANGUAGES CXX )
#### Main switches ####
@@ -38,7 +38,7 @@ SET( ISFQT_VERSION "1.0dev" )
#### Inclusions ####
FIND_PACKAGE( Qt4 REQUIRED )
FIND_PACKAGE( Qt6 REQUIRED COMPONENTS Core Core5Compat Gui Widgets )
OPTION( WANT_GIF "Enable support for reading and writing Fortified-GIF images" ON )
IF( WANT_GIF )
@@ -129,4 +129,3 @@ IF( NOT ISFQT_IS_BUNDLED )
INSTALL( FILES cmake/FindIsfQt.cmake
DESTINATION ${CMAKE_ROOT}/Modules )
ENDIF()
+8
View File
@@ -0,0 +1,8 @@
#ifndef ISFQT_QMATRIX_COMPAT_H
#define ISFQT_QMATRIX_COMPAT_H
#include <QTransform>
using QMatrix = QTransform;
#endif
+6 -6
View File
@@ -105,7 +105,7 @@ namespace Isf
PenType penType();
void save( QIODevice&, bool = false );
void setDrawing( Isf::Drawing* );
virtual QSize sizeHint() const;
QSize sizeHint() const override;
public slots:
void clear();
@@ -115,11 +115,11 @@ namespace Isf
void setPenType( PenType );
protected: // protected methods
void mousePressEvent( QMouseEvent* );
void mouseMoveEvent( QMouseEvent* );
void mouseReleaseEvent( QMouseEvent* );
void paintEvent( QPaintEvent* );
void resizeEvent( QResizeEvent* );
void mousePressEvent( QMouseEvent* ) override;
void mouseMoveEvent( QMouseEvent* ) override;
void mouseReleaseEvent( QMouseEvent* ) override;
void paintEvent( QPaintEvent* ) override;
void resizeEvent( QResizeEvent* ) override;
private: // private methods
void drawLineTo( const QPoint& );
+7 -5
View File
@@ -29,8 +29,10 @@ SET( ISFQT_PUBLIC_HEADERS
)
SET( ISFQT_LIBS
${QT_QTCORE_LIBRARY}
${QT_QTGUI_LIBRARY}
Qt6::Core
Qt6::Core5Compat
Qt6::Gui
Qt6::Widgets
)
SET( ISFQT_RCCS
@@ -45,11 +47,11 @@ ENDIF( GIF_FOUND )
#### Compilation ####
QT4_WRAP_CPP( MOC_SRCS ../include/isfinkcanvas.h )
QT6_WRAP_CPP( MOC_SRCS ../include/isfinkcanvas.h )
QT4_ADD_RESOURCES( ISFQT_RCC_SRCS ${ISFQT_RCCS} )
QT6_ADD_RESOURCES( ISFQT_RCC_SRCS ${ISFQT_RCCS} )
INCLUDE_DIRECTORIES( ${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} )
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
# Do not install the library if we're bundling it into an application
IF( ISFQT_IS_BUNDLED )
+2 -2
View File
@@ -131,14 +131,14 @@ namespace Isf
{
}
/// Quick comparison operator
bool operator ==( const AttributeSet& other )
bool operator ==( const AttributeSet& other ) const
{
return color == other.color
&& flags == other.flags
&& penSize == other.penSize;
}
/// Quick comparison operator
bool operator !=( const AttributeSet& other )
bool operator !=( const AttributeSet& other ) const
{
return color != other.color
|| flags != other.flags
+45 -34
View File
@@ -341,7 +341,7 @@ Drawing& Stream::readerPng( const QByteArray& pngRawBytes, bool decodeFromBase64
#ifdef ISFQT_DEBUG_VERBOSE
qDebug() << "Picture data is valid: checking for the ISF data tag...";
#endif
isfData = imageData.text( "application/x-ms-ink" ).toAscii();
isfData = imageData.text( "application/x-ms-ink" ).toLatin1();
if( ! isfData.isEmpty() )
{
@@ -381,7 +381,7 @@ bool Stream::supportsGif()
*/
QByteArray Stream::writer( const Drawing& drawing, bool encodeToBase64 )
{
if( &drawing == 0 || drawing.isNull() || drawing.error() != ISF_ERROR_NONE )
if( drawing.isNull() || drawing.error() != ISF_ERROR_NONE )
{
#ifdef ISFQT_DEBUG
qDebug() << "The drawing was not valid!";
@@ -478,18 +478,20 @@ QByteArray Stream::writerGif( const Drawing& drawing, bool encodeToBase64 )
// Initialise the gif variables
QBuffer gifData;
GifFileType* gifImage = NULL;
ColorMapObject* cmap = NULL;
int height = isfImage.height();
int width = isfImage.width();
int numColors = 0;
bool gifError = true;
GifFileType* gifImage = NULL;
ColorMapObject* cmap = NULL;
int height = isfImage.height();
int width = isfImage.width();
int colorCount = 0;
int numColors = 0;
int gifErrorCode = 0;
bool gifError = true;
// Convert the image to GIF using libgif
// Open the gif file
gifData.open( QIODevice::WriteOnly );
gifImage = EGifOpen( (void*)&gifData, GifWriteToByteArray );
gifImage = EGifOpen( (void*)&gifData, GifWriteToByteArray, &gifErrorCode );
if( gifImage == 0 )
{
qWarning() << "Couldn't initialize gif library!";
@@ -497,21 +499,22 @@ QByteArray Stream::writerGif( const Drawing& drawing, bool encodeToBase64 )
}
// Create the color map
numColors = ( isfImage.numColors() << 2 );
if( numColors > 256 )
colorCount = isfImage.colorCount();
numColors = 2;
while( numColors < colorCount && numColors < 256 )
{
numColors = 256;
numColors <<= 1;
}
cmap = MakeMapObject( numColors, NULL );
if( cmap == 0 && isfImage.numColors() > 1 )
cmap = GifMakeMapObject( numColors, NULL );
if( cmap == 0 && colorCount > 1 )
{
qWarning() << "Couldn't create map object for gif conversion (colors:" << isfImage.numColors() << ")!";
qWarning() << "Couldn't create map object for gif conversion (colors:" << colorCount << ")!";
goto writeError;
}
// Fill in the color map with the colors in the image color table
for( int i = 0; i < isfImage.numColors(); ++i )
for( int i = 0; i < colorCount && i < numColors; ++i )
{
const QRgb &color( isfImage.color( i ) );
cmap->Colors[i].Red = qRed ( color );
@@ -543,7 +546,7 @@ QByteArray Stream::writerGif( const Drawing& drawing, bool encodeToBase64 )
// Write every scanline
for( int line = 0; line < height; ++line )
{
if( EGifPutLine( gifImage, isfImage.scanLine( line ), width ) == GIF_ERROR )
if( EGifPutLine( gifImage, reinterpret_cast<GifPixelType*>( isfImage.scanLine( line ) ), width ) == GIF_ERROR )
{
qWarning() << "EGifPutLine failed at scanline" << line
<< "(height:" << isfImage.height()
@@ -576,9 +579,15 @@ QByteArray Stream::writerGif( const Drawing& drawing, bool encodeToBase64 )
else
{
// Write the extension
if( EGifPutExtensionFirst( gifImage, COMMENT_EXT_FUNC_CODE, MAX_GIF_BYTE, isfData.left( MAX_GIF_BYTE ).data() ) == GIF_ERROR )
if( EGifPutExtensionLeader( gifImage, COMMENT_EXT_FUNC_CODE ) == GIF_ERROR )
{
qWarning() << "EGifPutExtensionFirst failed!";
qWarning() << "EGifPutExtensionLeader failed!";
goto writeError;
}
if( EGifPutExtensionBlock( gifImage, MAX_GIF_BYTE, isfData.left( MAX_GIF_BYTE ).constData() ) == GIF_ERROR )
{
qWarning() << "EGifPutExtensionBlock failed!";
goto writeError;
}
@@ -590,9 +599,9 @@ QByteArray Stream::writerGif( const Drawing& drawing, bool encodeToBase64 )
// Write all the full data blocks
while( length >= MAX_GIF_BYTE )
{
if( EGifPutExtensionNext( gifImage, 0, MAX_GIF_BYTE, isfData.mid( pos, MAX_GIF_BYTE ).data() ) == GIF_ERROR )
if( EGifPutExtensionBlock( gifImage, MAX_GIF_BYTE, isfData.mid( pos, MAX_GIF_BYTE ).constData() ) == GIF_ERROR )
{
qWarning() << "EGifPutExtensionNext failed!";
qWarning() << "EGifPutExtensionBlock failed!";
goto writeError;
}
@@ -603,19 +612,17 @@ QByteArray Stream::writerGif( const Drawing& drawing, bool encodeToBase64 )
// Write the last block
if( length > 0 )
{
if( EGifPutExtensionLast( gifImage, 0, length, isfData.mid( pos, MAX_GIF_BYTE ).data() ) == GIF_ERROR )
if( EGifPutExtensionBlock( gifImage, length, isfData.mid( pos, MAX_GIF_BYTE ).constData() ) == GIF_ERROR )
{
qWarning() << "EGifPutExtensionLast (n) failed!";
qWarning() << "EGifPutExtensionBlock (tail) failed!";
goto writeError;
}
}
else
if( EGifPutExtensionTrailer( gifImage ) == GIF_ERROR )
{
if( EGifPutExtensionLast( gifImage, 0, 0, 0 ) == GIF_ERROR )
{
qWarning() << "EGifPutExtensionLast (0) failed!";
goto writeError;
}
qWarning() << "EGifPutExtensionTrailer failed!";
goto writeError;
}
}
@@ -623,13 +630,19 @@ QByteArray Stream::writerGif( const Drawing& drawing, bool encodeToBase64 )
writeError:
// Clean up the GIF converter etc
EGifCloseFile( gifImage );
FreeMapObject( cmap );
if( gifImage != 0 && EGifCloseFile( gifImage, &gifErrorCode ) == GIF_ERROR )
{
gifError = true;
}
if( cmap != 0 )
{
GifFreeMapObject( cmap );
}
gifData.close();
if( gifError )
{
qWarning() << "GIF error code:" << GifLastError();
qWarning() << "GIF error code:" << gifErrorCode << GifErrorString( gifErrorCode );
}
else
{
@@ -704,5 +717,3 @@ QByteArray Stream::writerPng( const Drawing& drawing, bool encodeToBase64 )
return imageBytes.data();
}
}
+1 -1
View File
@@ -30,6 +30,7 @@
#include <IsfQtDrawing>
#include <QPainter>
#include <QPainterPath>
#include <QPixmap>
#include <cmath>
@@ -726,4 +727,3 @@ void Drawing::updateBoundingRect()
#endif
}
+7 -8
View File
@@ -26,6 +26,7 @@
#include "isfqt-internal.h"
#include <QPainterPath>
#include <QVector>
using namespace Isf;
@@ -169,7 +170,7 @@ void Stroke::bezierCalculateControlPoints()
}
// right hand side vector.
double rhs[n];
QVector<double> rhs( n );
// set RHS x values
for( int i = 1; i < n-1; i++ )
@@ -181,8 +182,8 @@ void Stroke::bezierCalculateControlPoints()
rhs[n-1] = ( 8 * bezierKnots_[n-1].x() + bezierKnots_[n].x() ) / 2.0;
// get the first ctl points x values.
double x[n];
bezierGetFirstControlPoints( rhs, x, n );
QVector<double> x( n );
bezierGetFirstControlPoints( rhs.data(), x.data(), n );
// now set RHS y-values.
@@ -194,8 +195,8 @@ void Stroke::bezierCalculateControlPoints()
rhs[0] = bezierKnots_[0].y() + 2 * bezierKnots_[1].y();
rhs[n-1] = ( 8 * bezierKnots_[n-1].y() + bezierKnots_[n].y() ) / 2.0;
double y[n];
bezierGetFirstControlPoints( rhs, y, n );
QVector<double> y( n );
bezierGetFirstControlPoints( rhs.data(), y.data(), n );
// now fill the output QList.
for( int i = 0; i < n; i++ )
@@ -226,7 +227,7 @@ void Stroke::bezierCalculateControlPoints()
void Stroke::bezierGetFirstControlPoints( double rhs[], double* xOut, int n )
{
double* x = xOut; // solution vector.
double tmp[n]; // temp workspace.
QVector<double> tmp( n ); // temp workspace.
double b = 2.0;
x[0] = rhs[0] / b;
@@ -513,5 +514,3 @@ QMatrix* Stroke::transform()
{
return transform_;
}
+5 -7
View File
@@ -406,7 +406,7 @@ IsfError TagsParser::parseUnsupported( StreamData* streamData, const QString& ta
*/
IsfError TagsParser::parseCustomTag( StreamData* streamData, Drawing* drawing, quint64 tagIndex )
{
quint64 tag = tagIndex - FIRST_CUSTOM_TAG_ID;
quint64 tag = tagIndex - static_cast<quint64>( FIRST_CUSTOM_TAG_ID );
// Find if we have this tag registered in the GUID table
if( tag >= (quint64)drawing->guids_.count() )
@@ -427,8 +427,8 @@ IsfError TagsParser::parseCustomTag( StreamData* streamData, Drawing* drawing, q
// String values
if(
guid == "{96E9B229-B657-DA4F-BFFD-F54DBA4C35F9}" // Unknown meaning, name?
|| guid == "{7C8E448A-390F-D94C-BB52-71FDA3221674}" // Unknown meaning, surname?
guid == QUuid( "{96E9B229-B657-DA4F-BFFD-F54DBA4C35F9}" ) // Unknown meaning, name?
|| guid == QUuid( "{7C8E448A-390F-D94C-BB52-71FDA3221674}" ) // Unknown meaning, surname?
)
{
// TODO: WTF is the first char for? Its value is always "0x08"
@@ -438,7 +438,7 @@ IsfError TagsParser::parseCustomTag( StreamData* streamData, Drawing* drawing, q
foreach( quint64 item, data )
{
string.append( (quint8)item );
string.append( QChar( static_cast<quint8>( item ) ) );
}
#ifdef ISFQT_DEBUG
@@ -1136,7 +1136,7 @@ IsfError TagsParser::parseTransformation( StreamData* streamData, Drawing* drawi
float dx = Compress::decodeFloat( dataSource );
float dy = Compress::decodeFloat( dataSource );
transform->setMatrix( scaleX, scaleY, shearX, shearY, dx, dy );
transform->setMatrix( scaleX, shearX, 0, shearY, scaleY, 0, dx, dy, 1 );
#ifdef ISFQT_DEBUG_VERBOSE
qDebug() << "- Transformation details - "
@@ -1611,5 +1611,3 @@ QByteArray TagsParser::analyzePayload( StreamData* streamData, const quint64 pay
return result;
}
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
Executable → Regular
View File
-4
View File
@@ -46,7 +46,3 @@ void TestAlgorithms::testDataSource()
QTEST_MAIN(TestAlgorithms)
#include "test_algorithms.moc"
-4
View File
@@ -132,7 +132,3 @@ void TestIsfDrawing::readTestIsfData( const QString& filename, QByteArray& byteA
QTEST_MAIN(TestIsfDrawing)
#include "test_isfdrawing.moc"
@@ -261,7 +261,3 @@ void TestMultibyteCoding::floatDecode()
QTEST_MAIN(TestMultibyteCoding)
#include "test_multibyte_coding.moc"
@@ -84,7 +84,3 @@ void TestPngFortification::testDecode()
QTEST_MAIN(TestPngFortification)
#include "test_png_fortification.moc"
+3 -2
View File
@@ -6,5 +6,6 @@ ADD_SUBDIRECTORY( emoticons )
ADD_SUBDIRECTORY( chatstyles )
INSTALL( FILES kmesschatstyles.knsrc DESTINATION ${CONFIG_INSTALL_DIR} )
INSTALL( FILES kmess.notifyrc DESTINATION ${DATA_INSTALL_DIR}/kmess )
INSTALL( FILES kmess.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
INSTALL( FILES kmess.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR} )
INSTALL( FILES kmess.desktop DESTINATION ${XDG_APPS_INSTALL_DIR}
RENAME org.kmess.kmess.desktop )
View File
View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

+11 -9
View File
@@ -1,14 +1,16 @@
KDE4_INSTALL_ICONS( ${ICON_INSTALL_DIR} )
SET( KMESS_ICON_INSTALL_DIR ${DATA_INSTALL_DIR}/kmess/icons/hicolor/16x16 )
# If Likeback is enabled, install the needed icons
IF( NOT ${KMESS_DISABLE_LIKEBACK} EQUAL 1 )
INSTALL( FILES likeback_bug.png DESTINATION ${KMESS_ICON_INSTALL_DIR}/actions )
INSTALL( FILES likeback_dislike.png DESTINATION ${KMESS_ICON_INSTALL_DIR}/actions )
INSTALL( FILES likeback_feature.png DESTINATION ${KMESS_ICON_INSTALL_DIR}/actions )
INSTALL( FILES likeback_like.png DESTINATION ${KMESS_ICON_INSTALL_DIR}/actions )
INSTALL( FILES likeback_bug.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/16x16/actions )
INSTALL( FILES likeback_dislike.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/16x16/actions )
INSTALL( FILES likeback_feature.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/16x16/actions )
INSTALL( FILES likeback_like.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/16x16/actions )
ENDIF( NOT ${KMESS_DISABLE_LIKEBACK} EQUAL 1 )
INSTALL( FILES kmess-shadow.png DESTINATION ${KMESS_ICON_INSTALL_DIR}/apps )
INSTALL( FILES hi16-app-kmess.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/16x16/apps RENAME kmess.png )
INSTALL( FILES hi22-app-kmess.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/22x22/apps RENAME kmess.png )
INSTALL( FILES hi32-app-kmess.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/32x32/apps RENAME kmess.png )
INSTALL( FILES hi48-app-kmess.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/48x48/apps RENAME kmess.png )
INSTALL( FILES hi64-app-kmess.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/64x64/apps RENAME kmess.png )
INSTALL( FILES hi128-app-kmess.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/128x128/apps RENAME kmess.png )
INSTALL( FILES kmess-shadow.png DESTINATION ${KDE_INSTALL_ICONDIR}/hicolor/256x256/apps )
+5 -5
View File
@@ -1,14 +1,15 @@
[Desktop Entry]
Name=KMess
Exec=kmess -caption "%c" %i
Exec=kmess
Icon=kmess
Type=Application
DocPath=kmess/index.html
Terminal=0
Terminal=false
Categories=Qt;KDE;Network;InstantMessaging;
StartupWMClass=kmess
Comment=Live Messenger Client for KDE
Comment[de]=Live-Messenger-Klon für KDE 4
Comment[nl]=MSN Messenger Kloon voor KDE 4
Comment[de]=Live-Messenger-Client für KDE
Comment[nl]=Live Messenger-client voor KDE
GenericName=Live Messenger Client
GenericName[af]=Irc Kliënt
GenericName[ar]=عميل MSN
@@ -67,4 +68,3 @@ GenericName[xx]=xxMSN Clientxx
GenericName[zh_CN]=MSN
GenericName[zh_TW]=MSN
GenericName[zu]=Umthengi we MSN
+2 -4
View File
@@ -1,5 +1,3 @@
include_directories( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} )
add_subdirectory( en )
# Documentation still uses the old KDE4 handbook macro. It will be ported
# once the application target itself configures and compiles with KF6.
+1 -1
View File
@@ -2172,7 +2172,7 @@
<member>Vincenzo Reale (More Italian) <email>smart2128@baslug.org</email></member>
<member>Andrea Decorte (More Italian) <email>adecorte@gmail.com</email></member>
<member>Daniel E. Moctezuma (Japanese) <email>shinsen27@gmail.com</email></member>
<member>Daniel E. Moctezuma (Japanese) <email>dmoctezuma@kmess.org</email></member>
<member>Park Dong Cheon (Korean) <email>pdc@kaist.ac.kr</email></member>
Executable → Regular
View File
+5 -2
View File
@@ -16,9 +16,12 @@ ELSE( NOT GETTEXT_MSGFMT_EXECUTABLE )
FOREACH( _poFile ${PO_FILES} )
GET_FILENAME_COMPONENT( _lang ${_poFile} NAME_WE )
SET( _gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo )
ADD_CUSTOM_COMMAND( TARGET translations
ADD_CUSTOM_COMMAND( OUTPUT ${_gmoFile}
COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_poFile}
DEPENDS ${_poFile})
DEPENDS ${_poFile}
VERBATIM )
ADD_CUSTOM_TARGET( translation_${_lang} DEPENDS ${_gmoFile} )
ADD_DEPENDENCIES( translations translation_${_lang} )
INSTALL( FILES ${_gmoFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_lang}/LC_MESSAGES/ RENAME ${catalogname}.mo )
ENDFOREACH( _poFile ${PO_FILES} )
+32 -41
View File
@@ -1,21 +1,21 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Adrià Arrufat <swiftscythe@gmail.com>, 2009, 2010.
# Adrià Arrufat <swiftscythe@gmail.com>, 2009, 2010, 2011.
msgid ""
msgstr ""
"Project-Id-Version: ca\n"
"Report-Msgid-Bugs-To: http://www.kmess.org/board/\n"
"POT-Creation-Date: 2010-08-04 19:23+0200\n"
"PO-Revision-Date: 2010-05-20 17:49+0200\n"
"Last-Translator: \n"
"PO-Revision-Date: 2011-02-08 00:53+0100\n"
"Last-Translator: Adrià Arrufat <swiftscythe@gmail.com>\n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Language: \n"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 1.0\n"
"X-Generator: Lokalize 1.2\n"
"First-Translator: Adrià Arrufat <swiftscythe@gmail.com>\n"
#: account.cpp:45 account.cpp:755
@@ -115,13 +115,14 @@ msgid "%1 (This message was sent automatically)"
msgstr "%1 (Aquest missatge ha estat enviat automàticament)"
#: chat/chat.cpp:821
#, fuzzy, kde-format
#, kde-format
msgid ""
"<html>KMess could not save the log for the chat with &quot;%1&quot;:<br /"
">The chat logs directory, &quot;%2&quot;, does not exist.</html>"
msgstr ""
"<html>KMess no ha pogut desar el registre d'aquesta conversa:<br />La "
"carpeta dels registres , &quot;%1&quot;, no existeix.</html>"
"<html>KMess no ha pogut desar el registre d'aquesta conversa amb &quot;%"
"1&quot;:<br /> "
"El directori de registres, &quot;%2&quot;, no existeix.</html>"
#: chat/chat.cpp:956
msgctxt "Message shown in the chat window (when the wink name is unknown)"
@@ -463,7 +464,6 @@ msgstr ""
"registres de conversa."
#: chat/chatview.cpp:563
#, fuzzy
msgctxt "Chat log saving dialog, file type filter"
msgid ""
"*.html *.htm|Web Page (*.html)\n"
@@ -471,7 +471,6 @@ msgid ""
msgstr ""
"*.html *.htm|Pàgina web (*.html)\n"
"*.txt|Document de text pla (*.txt)\n"
"*.xml|Document XML(*.xml)"
#: chat/chatview.cpp:581
#, kde-format
@@ -2040,9 +2039,8 @@ msgid "[%1] %2 goes offline"
msgstr "[%1] %2 s'ha desconnectat"
#: kmessview.cpp:440
#, fuzzy
msgid "Search in contact list..."
msgstr "Busca entre els contactes..."
msgstr "Cerca entre els contactes..."
#: kmessview.cpp:704
msgid "Cha&t"
@@ -4107,44 +4105,39 @@ msgstr "<html><b>%1</b><br/>ha anat a menjar</html>"
#: notification/macnotification.cpp:61
msgid "Contact changed status"
msgstr ""
msgstr "El contacte ha canviat l'estat"
#: notification/macnotification.cpp:66
#, fuzzy
msgid "You received a new e-mail message"
msgstr "%1 correu electrònic nou"
msgstr "Heu rebut un nou correu electrònic"
#: notification/macnotification.cpp:72
msgid "A contact nudged you!"
msgstr ""
msgstr "Un contacte us envia un avís!"
#: notification/macnotification.cpp:78
msgid "A contact started a chat with you"
msgstr ""
msgstr "Un contacte ha iniciat una conversa"
#: notification/macnotification.cpp:84
#, fuzzy
msgid "A contact messaged you"
msgstr "Per a contactes d'un mateix grup"
msgstr "Un contacte us ha enviat un missatge"
#: notification/macnotification.cpp:90
#, fuzzy
msgid "A contact came online"
msgstr "Aquest contacte no està connectat"
msgstr "Un contacte s'ha connectat"
#: notification/macnotification.cpp:96
#, fuzzy
msgid "A contact went offline"
msgstr "Aquest contacte no està connectat"
msgstr "Un contacte s'ha desconnectat"
#: notification/macnotification.cpp:102
msgid "A contact changed status"
msgstr ""
msgstr "Un contacte ha canviat l'estat"
#: notification/macnotification.cpp:107
#, fuzzy
msgid "KMess notification"
msgstr "Icona de KMess"
msgstr "Notificació de KMess"
#: notification/newemailnotification.cpp:92
#, kde-format
@@ -4153,15 +4146,16 @@ msgid "<html><b>New email:</b><br/>'%1'<br/>by '%2'</html>"
msgstr "<html><b>Nou correu electrònic:</b><br/>'%1'<br/>de '%2'</html>"
#: notification/newsystemtraywidget.cpp:94
#, fuzzy
msgid ""
"<p>Closing the main window will keep KMess running in the system tray.</"
"p><p>You can open KMess again by clicking on the bird icon, which is now "
"flashing.<br/>Use 'Quit' from the 'Connect' menu to quit the application.</p>"
msgstr ""
"Tancar la finestra principal de KMess farà que segueixi funcionant a la "
"safata del sistema. Feu servir 'Abandona' del menú 'Connecta' per sortir de "
"l'aplicació."
"<p>Tancar la finestra principal de KMess farà que segueixi funcionant a la "
"safata del sistema.</p><p>Podeu obrir KMess un altre cop clicant sobre la "
"icona de l'ocell, que ara fa pampallugues.</br>Feu servir 'Abandona' del menú "
"'Connecta' per sortir de "
"l'aplicació.<p>"
#: notification/newsystemtraywidget.cpp:108
#: notification/systemtraywidget.cpp:96 notification/systemtraywidget.cpp:195
@@ -4170,32 +4164,30 @@ msgid "Docking in System Tray"
msgstr "Anclant-se a la safata del sistema"
#: notification/newsystemtraywidget.cpp:205
#, fuzzy, kde-format
#, kde-format
msgctxt ""
"Tray icon text tooltip when connected, %1 is the friendly name, %2 is the "
"status"
msgid "Connected as %1 (%2)"
msgstr "Connectant-se a %1, port %2"
msgstr "Connectat a %1 (%2)"
#: notification/newsystemtraywidget.cpp:209
#, fuzzy, kde-format
#, kde-format
msgctxt ""
"Tray icon HTML tooltip when connected, %1 is the friendly name, %2 is the "
"status"
msgid "<p>Connected as:<br/><b>%1</b> (%2)</p>"
msgstr "<br><b>%1</b> (%2)%3"
msgstr "<p>Connectat com a: <br/><b>%1</b> (%2)</p>"
#: notification/newsystemtraywidget.cpp:216
#, fuzzy
msgctxt "Tray icon text tooltip when not connected"
msgid "Not connected"
msgstr "Connectat"
msgstr "No connectat"
#: notification/newsystemtraywidget.cpp:219
#, fuzzy
msgctxt "Tray icon HTML tooltip when not connected"
msgid "<p>Not connected</p>"
msgstr "<p>S'ha perdut la connexió.</p>"
msgstr "<p>No connectat</p>"
#: notification/notificationmanager.cpp:120
msgctxt "Button text for KDE notification boxes"
@@ -4876,9 +4868,8 @@ msgstr "Filtre del registre de converses"
#. i18n: file: dialogs/chathistorydialog.ui:83
#. i18n: ectx: property (text), widget (QLabel, label_)
#: rc.cpp:113
#, fuzzy
msgid "Chat date:"
msgstr "Estil de conversa"
msgstr "Data de la conversa:"
#. i18n: file: dialogs/contactaddeduserdialog.ui:52
#. i18n: ectx: property (title), widget (QGroupBox, groupBox)
@@ -6145,7 +6136,7 @@ msgid ""
"Contacts may send multiple nudges at once, but KMess only shakes the chat "
"window with the first nudge.</p></qt>"
msgstr ""
"<qt>Quan els vostres contactes vulguin cridar la vostra atenció, upo poden "
"<qt>Quan els vostres contactes vulguin cridar la vostra atenció, us poden "
"enviar un avís. Per defecte, la finestra de conversa es mou quan es rep un "
"avís. Desactiveu aquesta opció si l'efecte de moviment és massa intrusiu.</"
"p>\n"
+6 -6
View File
@@ -10,14 +10,14 @@ msgstr ""
"Project-Id-Version: de\n"
"Report-Msgid-Bugs-To: http://www.kmess.org/board/\n"
"POT-Creation-Date: 2010-08-04 19:23+0200\n"
"PO-Revision-Date: 2010-06-27 14:36+0200\n"
"PO-Revision-Date: 2010-08-29 00:07+0200\n"
"Last-Translator: Panagiotis Papadopoulos <pano_90@gmx.net>\n"
"Language-Team: German <kde-i18n-de@kde.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.0\n"
"X-Generator: Lokalize 1.1\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#: account.cpp:45 account.cpp:755
@@ -2984,8 +2984,8 @@ msgid ""
"If you feel your name is missing here, please contact us too!"
msgstr ""
"Sie sind eingeladen Fehlerkorrekturen und Verbesserungen im KMess-Forum zu "
"veröffentlichen!\n"
"Wenn Sie denken, dass Ihr Name hier fehlt kontaktieren Sie uns bitte!"
"veröffentlichen.\n"
"Wenn Sie denken, dass Ihr Name hier fehlt kontaktieren Sie uns bitte."
#: main.cpp:194
msgid "Your name here?"
@@ -5617,7 +5617,7 @@ msgid ""
"are not using the computer for a few minutes. If this option is not "
"available, KMess was built without support for this feature."
msgstr ""
"Ist diese Option aktiviert, wird Ihr Status automatisch auf „Inaktiv“ "
"Ist diese Option aktiviert, wird Ihr Status automatisch auf „Inaktiv“ "
"gesetzt, wenn Sie Ihren Computer für einige Minuten nicht benutzen. Falls "
"diese Option nicht verfügbar ist, wurde KMess ohne Unterstützung für diese "
"Funktion kompiliert."
@@ -6321,7 +6321,7 @@ msgid ""
msgstr ""
"Ist diese Option aktiviert, wird eine Benachrichtigung angezeigt, sobald "
"eine E-Mail in Ihrem Posteingang eintrifft. Die Anzahl der ungelesen E-Mail-"
"Nachrichten, wird über der Kontaktliste angezeigt. Diese Option ist nur für "
"Nachrichten wird über der Kontaktliste angezeigt. Diese Option ist nur für "
"„Live Mail“-Zugänge verfügbar."
#. i18n: file: settings/contactlistpage.ui:26
+30 -28
View File
@@ -9,19 +9,20 @@
# Alexis Medina <alexismedina@gmail.com>, 2009.
# Manuel Ramírez <elpreto@kde.org.ar>, 2009.
# Mauricio Muñoz Lucero <real_mml@gmail.com>, 2009, 2010.
# Daniel E. Moctezuma <democtezuma@gmail.com>, 2010.
msgid ""
msgstr ""
"Project-Id-Version: es\n"
"Report-Msgid-Bugs-To: http://www.kmess.org/board/\n"
"POT-Creation-Date: 2010-08-04 19:23+0200\n"
"PO-Revision-Date: 2010-03-01 09:45+0100\n"
"Last-Translator: Mauricio Muñoz Lucero <real_mml@gmail.com>\n"
"PO-Revision-Date: 2010-12-13 19:26-0800\n"
"Last-Translator: Daniel E. Moctezuma <democtezuma@gmail.com>\n"
"Language-Team: Spanish <kde-i18n-doc@kde.org>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.0\n"
"X-Generator: Lokalize 1.1\n"
"First-Translator: Javier Cuesta Alcocer <yovoya30ks@hotmail.com>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Language: es_AR\n"
@@ -128,8 +129,9 @@ msgid ""
"<html>KMess could not save the log for the chat with &quot;%1&quot;:<br /"
">The chat logs directory, &quot;%2&quot;, does not exist.</html>"
msgstr ""
"<html>KMess no pudo guardar el historial de esta conversación.<br />No "
"existe el directorio de historiales de conversación &quot;%1&quot;.</html>"
"<html>KMess no pudo guardar el historial de la conversación con "
"&quot;%1&quot;.<br />No "
"existe el directorio de historiales de conversación &quot;%2&quot;.</html>"
#: chat/chat.cpp:956
msgctxt "Message shown in the chat window (when the wink name is unknown)"
@@ -473,7 +475,6 @@ msgstr ""
"guardar los historiales."
#: chat/chatview.cpp:563
#, fuzzy
msgctxt "Chat log saving dialog, file type filter"
msgid ""
"*.html *.htm|Web Page (*.html)\n"
@@ -481,7 +482,6 @@ msgid ""
msgstr ""
"*.html *.htm|Página web (*.html)\n"
"*.txt|Documento de texto plano (*.txt)\n"
"*.xml|Documento XML (*.xml)"
#: chat/chatview.cpp:581
#, kde-format
@@ -2050,7 +2050,6 @@ msgid "[%1] %2 goes offline"
msgstr "[%1] %2 se desconectó"
#: kmessview.cpp:440
#, fuzzy
msgid "Search in contact list..."
msgstr "Buscar entre los contactos..."
@@ -2157,7 +2156,7 @@ msgstr "Presione aquí para cambiar su seudónimo"
#: kmessview.cpp:1845
msgctxt "Default personal message shown in the contact list"
msgid "[i]Click to set a personal message[/i]"
msgstr ""
msgstr "[i]Presione aquí para definir un mensale personal[/i]"
#: kmessview.cpp:1846
msgctxt "Default personal message tooltip"
@@ -2196,14 +2195,16 @@ msgstr[0] "%1 nuevo mensaje de correo electrónico"
msgstr[1] "%1 nuevos mensajes de correo electrónico"
#: kmessview.cpp:2253
#, fuzzy
msgid "Show contacts what you are listening to (click to disable)"
msgstr "Mostrarle a mis contactos la &canción que estoy escuchando"
msgstr ""
"Mostrarle a mis contactos la canción que estoy escuchando (presione para "
"deshabilitar)"
#: kmessview.cpp:2258
#, fuzzy
msgid "Show contacts what you are listening to (click to enable)"
msgstr "Mostrarle a mis contactos la &canción que estoy escuchando"
msgstr ""
"Mostrarle a mis contactos la canción que estoy escuchando (presione para "
"habilitar)"
#: kmessviewdelegate.cpp:298
#, kde-format
@@ -2881,8 +2882,10 @@ msgstr ""
"contacto en la ventana de conversacion"
#: main.cpp:182
#, fuzzy
msgid "Internationalization fixes, drag'n'drop of images into display pictures"
msgstr ""
"Correcciones a la internacionalización, drag'n'drop de imágenes para mostrar"
#: main.cpp:182
msgid "Marco Mentasti"
@@ -2890,7 +2893,7 @@ msgstr "Marco Mentasti"
#: main.cpp:183
msgid "Francesco Nwokeka"
msgstr ""
msgstr "Francesco Nwokeka"
#: main.cpp:183
msgid "Now Listening toggle button above the contact list."
@@ -2969,12 +2972,14 @@ msgstr "¿Su nombre aquí?"
#: main.cpp:197 rc.cpp:1
msgctxt "NAME OF TRANSLATORS"
msgid "Your names"
msgstr "Juan Pablo González Tognarelli,Manuel Ramírez,Guillermo Arana"
msgstr ""
"Juan Pablo González Tognarelli,Manuel Ramírez,Guillermo Arana,Daniel E. "
"Moctezuma"
#: main.cpp:198
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your email addresses"
msgstr ",,elgui02@gmail.com"
msgstr ",,elgui02@gmail.com,democtezuma@gmail.com"
#: main.cpp:204
msgid "Do not show the contact list window initially"
@@ -4137,9 +4142,8 @@ msgid "Contact changed status"
msgstr ""
#: notification/macnotification.cpp:66
#, fuzzy
msgid "You received a new e-mail message"
msgstr "%1 nuevo mensaje de correo electrónico"
msgstr "Ha recibido un nuevo correo electrónico"
#: notification/macnotification.cpp:72
msgid "A contact nudged you!"
@@ -4169,9 +4173,8 @@ msgid "A contact changed status"
msgstr ""
#: notification/macnotification.cpp:107
#, fuzzy
msgid "KMess notification"
msgstr "Icono de KMess"
msgstr "Notificaciones de KMess"
#: notification/newemailnotification.cpp:92
#, kde-format
@@ -4196,32 +4199,32 @@ msgid "Docking in System Tray"
msgstr "Minimizado en la bandeja de sistema"
#: notification/newsystemtraywidget.cpp:205
#, fuzzy, kde-format
#, kde-format
msgctxt ""
"Tray icon text tooltip when connected, %1 is the friendly name, %2 is the "
"status"
msgid "Connected as %1 (%2)"
msgstr "Conectando a %1, puerto %2"
msgstr "Conectado como %1 (%2)"
#: notification/newsystemtraywidget.cpp:209
#, fuzzy, kde-format
#, kde-format
msgctxt ""
"Tray icon HTML tooltip when connected, %1 is the friendly name, %2 is the "
"status"
msgid "<p>Connected as:<br/><b>%1</b> (%2)</p>"
msgstr "<br><b>%1</b> (%2)%3"
msgstr "<p>Conectado como:<br/><b>%1</b> (%2)</p>"
#: notification/newsystemtraywidget.cpp:216
#, fuzzy
msgctxt "Tray icon text tooltip when not connected"
msgid "Not connected"
msgstr "Conectado"
msgstr "No conectado"
#: notification/newsystemtraywidget.cpp:219
#, fuzzy
msgctxt "Tray icon HTML tooltip when not connected"
msgid "<p>Not connected</p>"
msgstr "<p>Se ha perdido la conexión con la red.</p>"
msgstr "<p>No conectado</p>"
#: notification/notificationmanager.cpp:120
msgctxt "Button text for KDE notification boxes"
@@ -4901,9 +4904,8 @@ msgstr "Filtro de historial"
#. i18n: file: dialogs/chathistorydialog.ui:83
#. i18n: ectx: property (text), widget (QLabel, label_)
#: rc.cpp:113
#, fuzzy
msgid "Chat date:"
msgstr "Estilo de &conversación:"
msgstr "Fecha de la conversación:"
#. i18n: file: dialogs/contactaddeduserdialog.ui:52
#. i18n: ectx: property (title), widget (QGroupBox, groupBox)
+1 -1
View File
@@ -17,7 +17,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Language: et\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Lokalize 1.1\n"
+1 -1
View File
@@ -15,7 +15,7 @@ msgstr ""
"PO-Revision-Date: 2009-11-07 17:26+0200\n"
"Last-Translator: \n"
"Language-Team: American English <kde-i18n-doc@kde.org>\n"
"Language: \n"
"Language: fi\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+1538 -2274
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -10,7 +10,7 @@ msgstr ""
"PO-Revision-Date: 2010-03-11 09:10+0100\n"
"Last-Translator: Indalecio Freiría Santos <ifreiria@gmail.com>\n"
"Language-Team: Galego <proxecto@trasno.net>\n"
"Language: \n"
"Language: gl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+1 -1
View File
@@ -15,7 +15,7 @@ msgstr ""
"PO-Revision-Date: 2009-07-24 21:20+0200\n"
"Last-Translator: Ralesk <ralesk@drangolin.net>\n"
"Language-Team: <NONE>\n"
"Language: \n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+58 -84
View File
@@ -4,21 +4,21 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Daniel E. Moctezuma <shinsen27@gmail.com>, 2009, 2010.
# Daniel E. Moctezuma <dmoctezuma@kmess.org>, 2009, 2010, 2011.
msgid ""
msgstr ""
"Project-Id-Version: ja\n"
"Report-Msgid-Bugs-To: http://www.kmess.org/board/\n"
"POT-Creation-Date: 2010-08-04 19:23+0200\n"
"PO-Revision-Date: 2010-07-07 20:43-0700\n"
"Last-Translator: Daniel E. Moctezuma <shinsen27@gmail.com>\n"
"Language-Team: 日本語 <Kdeveloper@kde.gr.jp>\n"
"PO-Revision-Date: 2011-03-13 16:56-0700\n"
"Last-Translator: Daniel E. Moctezuma <dmoctezuma@kmess.org>\n"
"Language-Team: Japanese <Kdeveloper@kde.gr.jp>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Lokalize 1.0\n"
"X-Generator: Lokalize 1.1\n"
#: account.cpp:45 account.cpp:755
msgid "I am away from my computer"
@@ -110,13 +110,13 @@ msgid "%1 (This message was sent automatically)"
msgstr "%1 (このメッセージは自動的に送信されました)"
#: chat/chat.cpp:821
#, fuzzy, kde-format
#, kde-format
msgid ""
"<html>KMess could not save the log for the chat with &quot;%1&quot;:<br /"
">The chat logs directory, &quot;%2&quot;, does not exist.</html>"
msgstr ""
"<html>KMess はの会話のチャット・ログを保存できませんでした:<br/>&quot;"
"%1&quot; のチャット・ログのディレクトリは存在しません。</html>"
"<html>KMess は &quot;%1&quot; さんとの会話のチャット・ログを保存できませんでした:<br/>&quot;"
"%2&quot; のチャット・ログのディレクトリは存在しません。</html>"
#: chat/chat.cpp:956
msgctxt "Message shown in the chat window (when the wink name is unknown)"
@@ -133,8 +133,7 @@ msgstr "&quot;%1&quot; のウインクを送信しました!"
msgid ""
"The chat has been disabled because you are no longer connected to the Live "
"Messenger server."
msgstr ""
"Live Messengerのサーバにもう接続していませんからチャットが無効にされました。"
msgstr "Live Messengerのサーバにもう接続していませんからチャットが無効にされました。"
#: chat/chat.cpp:1157
msgctxt "Warning message shown in chat"
@@ -155,8 +154,7 @@ msgstr ""
msgctxt "Warning message shown in chat, %1 is the contact's friendly name"
msgid ""
"%1 has sent you a voice clip, but KMess does not support voice clips yet."
msgstr ""
"%1 さんからボイスクリップを受信しましたがその機能はまだサポートしていません。"
msgstr "%1 さんからボイスクリップを受信しましたがその機能はまだサポートしていません。"
#: chat/chat.cpp:1194
#, kde-format
@@ -178,8 +176,7 @@ msgstr "知り合いは手書きメッセージをサポートしていません
msgctxt "Warning message shown in chat, %1 is the contact's friendly name"
msgid ""
"%1 has sent you a Live Messenger feature that KMess does not support yet."
msgstr ""
"%1 さんから KMess がまだサポートしないLive Messengerの機能を受信しました。"
msgstr "%1 さんから KMess がまだサポートしないLive Messengerの機能を受信しました。"
#: chat/chat.cpp:1245
#, kde-format
@@ -347,8 +344,7 @@ msgstr "%2 さんにこのメッセージの配信に失敗しました:<br/>%
msgid ""
"The file &quot;%1&quot; could not be found on your computer, and the "
"download failed."
msgstr ""
"&quot;%1&quot; のファイルは見つからなくて、ダウンロードに失敗しました。"
msgstr "&quot;%1&quot; のファイルは見つからなくて、ダウンロードに失敗しました。"
#: chat/chat.cpp:1649
#, kde-format
@@ -453,7 +449,6 @@ msgstr ""
"保存しているフォルダで書き込み許可があるのを検証してください。"
#: chat/chatview.cpp:563
#, fuzzy
msgctxt "Chat log saving dialog, file type filter"
msgid ""
"*.html *.htm|Web Page (*.html)\n"
@@ -461,7 +456,6 @@ msgid ""
msgstr ""
"*.html *.htm|Web Page (*.html)\n"
"*.txt|Plain Text Document (*.txt)\n"
"*.xml|XML Document (*.xml)"
#: chat/chatview.cpp:581
#, kde-format
@@ -645,7 +639,7 @@ msgstr "フォント(&F)"
#: chat/chatwindow.cpp:538
msgid "Font &Color"
msgstr "フォンの色(&C)"
msgstr "フォンの色(&C)"
#: chat/chatwindow.cpp:539
msgid "C&lear Chat Window"
@@ -701,16 +695,14 @@ msgstr "不明なコマンド"
#: chat/chatwindow.cpp:1548
msgctxt "Error message shown in chat"
msgid "Failed to send the handwritten message: the contacts do not support it."
msgstr ""
"手書きのメッセージの送信に失敗しました:知り合いはサポートしていません。"
msgstr "手書きのメッセージの送信に失敗しました:知り合いはサポートしていません。"
#: chat/chatwindow.cpp:1586
msgctxt "Error message shown in chat"
msgid ""
"Failed to send the handwritten message: an error has occurred while creating "
"it."
msgstr ""
"%1 さんに手書きのメッセージの送信に失敗しました:作成中エラーが発生しました。"
msgstr "%1 さんに手書きのメッセージの送信に失敗しました:作成中エラーが発生しました。"
#: chat/chatwindow.cpp:1867
msgctxt "Chat window caption, without contact name"
@@ -1708,8 +1700,7 @@ msgid ""
msgid_plural ""
"Waiting %1 seconds before reconnection...<br /><a href='%2'>Reconnect now!</"
"a>"
msgstr[0] ""
"再接続する前に%1秒を待っています...<br /><a href='%2'>すぐに再接続!</a>"
msgstr[0] "再接続する前に%1秒を待っています...<br /><a href='%2'>すぐに再接続!</a>"
#: initialview.cpp:662
msgctxt "Button label"
@@ -1734,8 +1725,7 @@ msgstr "有効なメールアドレスを入力してください"
#: kmess.cpp:218
#, kde-format
msgid "<html>The contact <b>%1</b> is already in your contact list.</html>"
msgstr ""
"<html><b>%1</b> の知り合いはあなたのコンタクトリストに既にいます。</html>"
msgstr "<html><b>%1</b> の知り合いはあなたのコンタクトリストに既にいます。</html>"
#: kmess.cpp:218
msgid "Contact Information"
@@ -1908,7 +1898,7 @@ msgstr "検索バーを表示(&S)"
#: kmessinterface.cpp:177
msgid "Show &Empty Groups"
msgstr "空グループを表示(&G)"
msgstr "空グループを表示(&G)"
#: kmessinterface.cpp:178
msgid "&Display Pictures Size"
@@ -1980,7 +1970,7 @@ msgstr "オンライン・オフライン"
#: kmessinterface.cpp:204
msgid "Mixed"
msgstr "混ぜる"
msgstr "混"
#: kmessinterface.cpp:294
msgid "Show &Network Window..."
@@ -2002,7 +1992,6 @@ msgid "[%1] %2 goes offline"
msgstr "[%1] %2 サインアウトしました"
#: kmessview.cpp:440
#, fuzzy
msgid "Search in contact list..."
msgstr "知り合いの検索..."
@@ -2828,7 +2817,7 @@ msgstr "Francesco Nwokeka"
#: main.cpp:183
msgid "Now Listening toggle button above the contact list."
msgstr ""
msgstr "コンタクトリストの上の「今聴いてる曲名を表示」のトグルボタン。"
#: main.cpp:186
msgid "Inspiration and assorted code"
@@ -2899,7 +2888,7 @@ msgstr "Daniel E. Moctezuma"
#: main.cpp:198
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your email addresses"
msgstr "shinsen27@gmail.com"
msgstr "dmoctezuma@kmess.org"
#: main.cpp:204
msgid "Do not show the contact list window initially"
@@ -3108,8 +3097,7 @@ msgstr "招待が中止されました。内部エラーが発生しました。
#: network/applications/mimeapplication.cpp:170
msgid "The invitation was aborted. Timeout while waiting for user to accept."
msgstr ""
"招待が中止されました。ユーザの承諾を待ちながら、タイムアウトが発生しました。"
msgstr "招待が中止されました。ユーザの承諾を待ちながら、タイムアウトが発生しました。"
#: network/applications/mimeapplication.cpp:175
msgid "The invitation was aborted. Timeout while waiting for file data."
@@ -3200,8 +3188,7 @@ msgstr ""
#: network/applications/p2papplication.cpp:3499
#: network/applications/p2papplication.cpp:3583
msgid "The invitation was cancelled. A timeout occurred waiting for data."
msgstr ""
"招待がキャンセルされました。データを待ちながら、タイムアウトが発生しました。"
msgstr "招待がキャンセルされました。データを待ちながら、タイムアウトが発生しました。"
#: network/applications/p2papplicationbase.cpp:622
#: network/applications/p2papplicationbase.cpp:1045
@@ -3214,8 +3201,7 @@ msgstr "転送に失敗しました。"
#: network/applications/p2papplicationbase.cpp:1030
msgid "The transfer failed. Timeout while waiting for user to accept."
msgstr ""
"転送に失敗しました。ユーザの承諾を待ちながら、タイムアウトが発生しました。"
msgstr "転送に失敗しました。ユーザの承諾を待ちながら、タイムアウトが発生しました。"
#: network/applications/p2papplicationbase.cpp:1049
msgid "The transfer failed. An internal error occured."
@@ -3359,15 +3345,13 @@ msgstr "知り合いは許可及び禁止リストに追加できません"
msgid ""
"The group name is already present in your contact list. Please use a "
"different name"
msgstr ""
"グループ名はコンタクトリストに既にあります。他の名前を入力してください。"
msgstr "グループ名はコンタクトリストに既にあります。他の名前を入力してください。"
#: network/msnconnection.cpp:437
msgid ""
"Your contact list has too many groups; you are allowed to only have at most "
"30"
msgstr ""
"コンタクトリストはたくさんのグループがあります。最大のグループ数は30つです。"
msgstr "コンタクトリストはたくさんのグループがあります。最大のグループ数は30つです。"
#: network/msnconnection.cpp:441
msgid "This group cannot be changed"
@@ -3379,7 +3363,7 @@ msgstr "知り合いはこのグループに追加していません"
#: network/msnconnection.cpp:450
msgid "This group is not empty"
msgstr "グループは空ではありません"
msgstr "グループは空ではありません"
#: network/msnconnection.cpp:454
msgid "The group name is too long; it cannot be longer than 61 characters"
@@ -3400,7 +3384,7 @@ msgstr "無効なグループ"
#: network/msnconnection.cpp:467
msgid "Empty domain"
msgstr "空きドメイン"
msgstr "ドメインが指定されていません"
#: network/msnconnection.cpp:471
msgid "Wrong ADL command format"
@@ -3499,8 +3483,7 @@ msgstr "不良 USR チケット"
#: network/msnconnection.cpp:576
msgid "Error accessing contact list, try again later"
msgstr ""
"コンタクトリストにアクセスできませんでした。後でもう一度試してください。"
msgstr "コンタクトリストにアクセスできませんでした。後でもう一度試してください。"
#: network/msnconnection.cpp:585
msgid ""
@@ -3774,8 +3757,7 @@ msgstr ""
#: network/msnsocketbase.cpp:135
msgctxt "Dialog box message"
msgid "Enter your username and password to access the network proxy."
msgstr ""
"ネットワークプロキシに接続するためにユーザ名とパスワードを入力してください。"
msgstr "ネットワークプロキシに接続するためにユーザ名とパスワードを入力してください。"
#: network/msnsockethttp.cpp:691
#, kde-format
@@ -3819,8 +3801,7 @@ msgctxt "Error message"
msgid ""
"The specified email address, \"%1\", does not belong to a Live Messenger "
"account!"
msgstr ""
"入力したメールアドレス \"%1\" は、Live Messengerのアカウントに属しません!"
msgstr "入力したメールアドレス \"%1\" は、Live Messengerのアカウントに属しません!"
#: network/soap/addressbookservice.cpp:853
#: network/soap/addressbookservice.cpp:876
@@ -4443,7 +4424,7 @@ msgid ""
"tool</a> to translate your message.<br/>"
msgstr ""
"メッセージを<b>%1</b>で書いてください、または開発者はあなたのコメントを読むこ"
"とができません。<br/><a href=\"%2\">翻訳機経由</a>でもできます)。<br/>"
"とができません。<br/><a href=\"%2\">オンライン翻訳ツール</a>を使ってもかまいません)。<br/>"
#: utils/likeback/likebackdialog.cpp:152
#, kde-format
@@ -4455,8 +4436,7 @@ msgid ""
"read your comment!<br/>You may want to use an <a href=\"%3\">online "
"translation tool</a> to translate your message.<br/>"
msgstr ""
"メッセージを<b>%1か%2</b>で書いてください(<a href=\"%3\">翻訳機経由</a>でも"
"できます)。<br/>"
"メッセージを<b>%1か%2</b>で書いてください(<a href=\"%3\">オンライン翻訳ツール</a>を使ってもかまいません)。<br/>"
#: utils/likeback/likebackdialog.cpp:168
msgctxt ""
@@ -4464,17 +4444,14 @@ msgctxt ""
msgid ""
"To make the comments you send more useful in improving this application, try "
"to send the same amount of positive and negative comments.<br/>"
msgstr ""
"このアプリケーションを改善するためにコメントを正負の同量を送信してみてくださ"
"い。<br/>"
msgstr "送信するコメントをアプリケーションの改善により反映させるために、なるべく良い点と悪い点の両方を書くようにしてみてください。<br/>"
#: utils/likeback/likebackdialog.cpp:177
msgctxt "Feedback dialog text, text to disallow feature requests"
msgid ""
"Please, do not ask for new features: this kind of request will be ignored."
"<br/>"
msgstr ""
"新しい機能を尋ねないでください:そのようなリクエストは無視します。<br/>"
msgstr "新しい機能を尋ねないでください:そのようなリクエストは無視します。<br/>"
#: utils/likeback/likebackdialog.cpp:183
#, kde-format
@@ -4485,7 +4462,7 @@ msgctxt ""
msgid ""
"<p>You can provide the developers a brief description of your opinions about "
"%1.<br/>%2 %3%4</p>"
msgstr "<p>開発者に %1 について意見を説明できます。<br/>%2 %3%4</p>"
msgstr "<p>開発者に %1 について意見を残すことができます。<br/>%2 %3%4</p>"
#: utils/likeback/likebackdialog.cpp:225
#, kde-format
@@ -4524,7 +4501,7 @@ msgstr "コメントの送信エラー"
#: rc.cpp:2
msgctxt "EMAIL OF TRANSLATORS"
msgid "Your emails"
msgstr "shinsen27@gmail.com"
msgstr "dmoctezuma@kmess.org"
#. i18n: file: chat/chatwindow.ui:190
#. i18n: ectx: property (toolTip), widget (QToolButton, textButton_)
@@ -4726,9 +4703,8 @@ msgstr "チャット履歴のフィルタ"
#. i18n: file: dialogs/chathistorydialog.ui:83
#. i18n: ectx: property (text), widget (QLabel, label_)
#: rc.cpp:113
#, fuzzy
msgid "Chat date:"
msgstr "チャットスタイル(&C):"
msgstr "チャット日付:"
#. i18n: file: dialogs/contactaddeduserdialog.ui:52
#. i18n: ectx: property (title), widget (QGroupBox, groupBox)
@@ -4967,7 +4943,7 @@ msgstr "送信"
#. i18n: ectx: property (text), widget (QLabel, label_2)
#: rc.cpp:248
msgid "Command payload (can be empty):"
msgstr "コマンドのペイロード(空きになれる):"
msgstr "コマンドのペイロード(指定しないでもいい):"
#. i18n: file: dialogs/transferentry.ui:196
#. i18n: ectx: property (text), widget (KUrlLabel, openLabel_)
@@ -5021,8 +4997,7 @@ msgstr ""
#: rc.cpp:277
msgid ""
"Enter here the email address of your registered Passport or Live account"
msgstr ""
"登録したパスポートまたはLiveアカウントのメールアドレスを入力してください。"
msgstr "登録したパスポートまたはLiveアカウントのメールアドレスを入力してください。"
#. i18n: file: initialview.ui:195
#. i18n: ectx: property (text), widget (QLabel, TextLabel3)
@@ -5085,8 +5060,7 @@ msgstr "自動的にサインイン"
#: rc.cpp:313
msgid ""
"Click this button to start using KMess, or to cancel a connection attempt"
msgstr ""
"このボタンをクリックして、KMess を使用するまたは接続の試しをキャンセルする。"
msgstr "このボタンをクリックして、KMess を使用するまたは接続の試しをキャンセルする。"
#. i18n: file: initialview.ui:444
#. i18n: ectx: property (text), widget (KUrlLabel, newAccountLabel_)
@@ -5507,8 +5481,7 @@ msgstr "チャット履歴を有効にする"
msgid ""
"If enabled, KMess additionaly saves your chat logs as HTML or plain text "
"files"
msgstr ""
"有効にすると、チャット履歴は HTML またはプレーンテキストとして保存します"
msgstr "有効にすると、チャット履歴は HTML またはプレーンテキストとして保存します"
#. i18n: file: settings/chatloggingpage.ui:39
#. i18n: ectx: property (title), widget (QGroupBox, saveChatsToFileCheckBox_)
@@ -5663,7 +5636,7 @@ msgstr "年、月、日"
#. i18n: ectx: property (toolTip), widget (QRadioButton, singleDirectoryRadioButton_)
#: rc.cpp:597
msgid "Place all saved chat logs directly in the directory specified below"
msgstr ""
msgstr "チャット履歴は以下の指定するディレクトリを保存"
#. i18n: file: settings/chatloggingpage.ui:227
#. i18n: ectx: property (whatsThis), widget (QRadioButton, singleDirectoryRadioButton_)
@@ -5758,7 +5731,7 @@ msgid ""
"If enabled, winks you send or receive will be displayed in the chat window. "
"Please note that in order to use this feature, you need to have a working "
"Flash-plugin installed."
msgstr ""
msgstr "有効にすると、送信するまたは受信するウインクをチャットウィンドウに表示します(Flash プラグインが必要です)。"
#. i18n: file: settings/chatstylepage.ui:249
#. i18n: ectx: property (text), widget (QCheckBox, showWinksCheckBox_)
@@ -5869,6 +5842,8 @@ msgid ""
"<html>Enables the use of \"Messenger Plus!\" formattings in the chat window. "
"For example, [b]this text[/b] will be replaced with <b>this text</b>.</html>"
msgstr ""
"<html>\"Messenger Plus!\" のフォーマットを有効します。"
"例:[b]このテキスト[/b]を<b>このテキスト</b>に置き換えます。</html>"
#. i18n: file: settings/chatstylepage.ui:558
#. i18n: ectx: property (text), widget (QCheckBox, enableChatFormattingCheckBox_)
@@ -6126,7 +6101,7 @@ msgstr "カスタムコマンド(&S)"
msgid ""
"Specify the path of a program to use to open links; a '%u' here will be "
"replaced with the links' URL."
msgstr ""
msgstr "ハイパーリンクを開くプログラムを指定できます。URL は '%u' として置き換えます。"
#. i18n: file: settings/miscellaneouspage.ui:126
#. i18n: ectx: property (text), widget (QLabel, customBrowserInfo_)
@@ -6161,8 +6136,7 @@ msgstr "アカウントがサポートしたら、Live Mailを使う(&L)"
#. i18n: ectx: property (toolTip), widget (QRadioButton, useKDEMailClientRadio_)
#: rc.cpp:858
msgid "Choose this option to use the email client used by the rest of KDE."
msgstr ""
"このオプションを選択して、KDE で使っているメールクライアントを使います。"
msgstr "このオプションを選択して、KDE で使っているメールクライアントを使います。"
#. i18n: file: settings/miscellaneouspage.ui:170
#. i18n: ectx: property (text), widget (QRadioButton, useKDEMailClientRadio_)
@@ -6217,7 +6191,7 @@ msgstr ""
#. i18n: ectx: property (toolTip), widget (QToolButton, m_likeButton)
#: rc.cpp:905
msgid "Click here to tell the developers about something you liked"
msgstr "ここをクリックして、開発者に好きなことについて伝えます"
msgstr "開発者に気に入った点を伝えます"
#. i18n: file: utils/likeback/likebackbar.ui:36
#. i18n: ectx: property (whatsThis), widget (QToolButton, m_likeButton)
@@ -6242,13 +6216,13 @@ msgstr ""
#. i18n: ectx: property (toolTip), widget (QToolButton, m_dislikeButton)
#: rc.cpp:912
msgid "Click here to tell the developers about something you did not like"
msgstr "ここをクリックして、開発者に好きではないことについて伝えます"
msgstr "開発者に気に入らなかった点を伝えます"
#. i18n: file: utils/likeback/likebackbar.ui:66
#. i18n: ectx: property (toolTip), widget (QToolButton, m_bugButton)
#: rc.cpp:919
msgid "Click here to tell the developers about a problem in the application"
msgstr "ここをクリックして、開発者にアプリケーションの問題について伝えます"
msgstr "開発者にアプリケーションの問題伝えます"
#. i18n: file: utils/likeback/likebackbar.ui:83
#. i18n: ectx: property (toolTip), widget (QToolButton, m_featureButton)
@@ -6256,31 +6230,31 @@ msgstr "ここをクリックして、開発者にアプリケーションの問
msgid ""
"Click here to tell the developers about new features you would like to have "
"in this application"
msgstr "ここをクリックして、開発者に希望する新しい機能について伝えます"
msgstr "開発者に望む新しい機能伝えます"
#. i18n: file: utils/likeback/likebackdialog.ui:48
#. i18n: ectx: property (text), widget (QLabel, label_2)
#: rc.cpp:933
msgid "Your comment:"
msgstr "コメント:"
msgstr "あなたのコメント:"
#. i18n: file: utils/likeback/likebackdialog.ui:74
#. i18n: ectx: property (title), widget (QGroupBox, groupBox)
#: rc.cpp:936
msgid "Your comment is about:"
msgstr "コメントについて"
msgstr "コメントの対象"
#. i18n: file: utils/likeback/likebackdialog.ui:86
#. i18n: ectx: property (text), widget (QRadioButton, likeRadio_)
#: rc.cpp:939
msgid "Something you like"
msgstr "好きなこと"
msgstr "あなたの好むもの"
#. i18n: file: utils/likeback/likebackdialog.ui:99
#. i18n: ectx: property (text), widget (QRadioButton, dislikeRadio_)
#: rc.cpp:942
msgid "Something you dislike"
msgstr "好きではないこと"
msgstr "あなたの嫌いなもの"
#. i18n: file: utils/likeback/likebackdialog.ui:112
#. i18n: ectx: property (text), widget (QRadioButton, bugRadio_)
@@ -6292,13 +6266,13 @@ msgstr "アプリケーションの不適切な挙動"
#. i18n: ectx: property (text), widget (QRadioButton, featureRadio_)
#: rc.cpp:948
msgid "A new feature you desire"
msgstr "希望する新しい機能"
msgstr "あなたの望む新しい機能"
#. i18n: file: utils/likeback/likebackdialog.ui:141
#. i18n: ectx: property (text), widget (QCheckBox, specifyEmailCheckBox_)
#: rc.cpp:951
msgid "Specify an email address to be contacted back:"
msgstr "連絡するためにメールアドレスを書いてください"
msgstr "返答用のメールアドレスを指定"
#. i18n: file: utils/likeback/likebackdialog.ui:188
#. i18n: ectx: property (text), widget (QLabel, label)
Executable → Regular
View File
Executable → Regular
View File
+418 -356
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -16,7 +16,7 @@ msgstr ""
"PO-Revision-Date: 2010-07-09 20:07-0300\n"
"Last-Translator: Morris\n"
"Language-Team: American English <>\n"
"Language: \n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+27 -37
View File
@@ -1,18 +1,18 @@
# translation of tr.po to Turkish
# Uğur Çetin <jnmbk@users.sourceforge.net>, 2006, 2007, 2009, 2010.
# Uğur Çetin <jnmbk@users.sourceforge.net>, 2006, 2007, 2009, 2010, 2011.
msgid ""
msgstr ""
"Project-Id-Version: tr\n"
"Report-Msgid-Bugs-To: http://www.kmess.org/board/\n"
"POT-Creation-Date: 2010-08-04 19:23+0200\n"
"PO-Revision-Date: 2010-03-01 06:55+0200\n"
"PO-Revision-Date: 2011-01-30 10:39+0200\n"
"Last-Translator: Uğur Çetin <jnmbk@users.sourceforge.net>\n"
"Language-Team: Turkish <kde-i18n-doc@kde.org>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.0\n"
"X-Generator: Lokalize 1.1\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: account.cpp:45 account.cpp:755
@@ -4114,12 +4114,12 @@ msgid "Connected as %1 (%2)"
msgstr "Bağlanıyor %1, port %2"
#: notification/newsystemtraywidget.cpp:209
#, fuzzy, kde-format
#, kde-format
msgctxt ""
"Tray icon HTML tooltip when connected, %1 is the friendly name, %2 is the "
"status"
msgid "<p>Connected as:<br/><b>%1</b> (%2)</p>"
msgstr "<br><b>%1</b> (%2)"
msgstr "<p>Bağlı hesap:<br/><b>%1</b> (%2)</p>"
#: notification/newsystemtraywidget.cpp:216
#, fuzzy
@@ -4328,9 +4328,8 @@ msgid "Accounts"
msgstr "Hesaplar"
#: settings/globalsettingsdialog.cpp:65 settings/globalsettingsdialog.cpp:67
#, fuzzy
msgid "Notifications"
msgstr "E-posta bildirimi"
msgstr "Bildirimler"
#: settings/miscellaneouspage.cpp:74
msgid "No selectable web browsers detected."
@@ -5560,9 +5559,8 @@ msgstr ""
#. i18n: file: settings/chatloggingpage.ui:39
#. i18n: ectx: property (title), widget (QGroupBox, saveChatsToFileCheckBox_)
#: rc.cpp:528
#, fuzzy
msgid "Additionally save chat logs to file"
msgstr "Sohbeti &Dosyaya Kaydet"
msgstr "Sohbetleri başka dosyaya da kaydet"
#. i18n: file: settings/chatloggingpage.ui:51
#. i18n: ectx: property (toolTip), widget (QLabel, label_2)
@@ -5573,9 +5571,8 @@ msgstr ""
#. i18n: file: settings/chatloggingpage.ui:54
#. i18n: ectx: property (text), widget (QLabel, label_2)
#: rc.cpp:534
#, fuzzy
msgid "Save chat logs as:"
msgstr "Sohbeti &Dosyaya Kaydet"
msgstr "Sohbetleri bu türde kaydet:"
#. i18n: file: settings/chatloggingpage.ui:86
#. i18n: ectx: property (whatsThis), widget (QComboBox, fileFormatComboBox_)
@@ -5624,9 +5621,8 @@ msgstr ""
#. i18n: file: settings/chatloggingpage.ui:140
#. i18n: ectx: property (text), widget (QLabel, label)
#: rc.cpp:556
#, fuzzy
msgid "Separate logged chats by:"
msgstr "Sohbeti Kaydet"
msgstr "Kayıtlı sohbetleri buna göre grupla:"
#. i18n: file: settings/chatloggingpage.ui:156
#. i18n: ectx: property (toolTip), widget (QRadioButton, yearRadioButton_)
@@ -5731,7 +5727,7 @@ msgstr ""
#. i18n: ectx: property (text), widget (QRadioButton, singleDirectoryRadioButton_)
#: rc.cpp:603
msgid "Do not organize files"
msgstr ""
msgstr "Dosyaları gruplama"
#. i18n: file: settings/chatloggingpage.ui:273
#. i18n: ectx: property (toolTip), widget (QToolButton, chatSavePathButton_)
@@ -5756,7 +5752,6 @@ msgstr "Sohbet kayıtlarının duracağı dizini seçin."
#. i18n: file: settings/chatloggingpage.ui:308
#. i18n: ectx: property (text), widget (QLabel, chatSavePathLabel_)
#: rc.cpp:618
#, fuzzy
msgid "Save chat logs in the following directory:"
msgstr "Sohbetleri bu dizine kaydet:"
@@ -5901,9 +5896,8 @@ msgstr ""
#. i18n: file: settings/chatstylepage.ui:461
#. i18n: ectx: property (text), widget (QCheckBox, useContactFontCheckBox_)
#: rc.cpp:690
#, fuzzy
msgid "&Force messages from your contacts to use this font:"
msgstr "Kişinin iletilerinde bu yazı tipinin kullanmasını zorla:"
msgstr "Gelen iletilerde bu yazı tipinin kullanmasını &zorla:"
#. i18n: file: settings/chatstylepage.ui:536
#. i18n: ectx: property (title), widget (QGroupBox, groupBox_4)
@@ -5926,10 +5920,10 @@ msgstr ""
#. i18n: file: settings/chatstylepage.ui:545
#. i18n: ectx: property (text), widget (QCheckBox, useFontEffectsCheckBox_)
#: rc.cpp:699
#, fuzzy
msgid "Use font &effects in messages, like *bold*, /italic/, and _underline_"
msgstr ""
"Mesajlarda &yazıtipi efektleri kullan, ör: *koyu*, /italik/, ve _altı çizili_"
"İletilerde, *koyu*, /italik/, ve _altı çizili_ gibi &yazıtipi efektleri "
"kullan"
#. i18n: file: settings/chatstylepage.ui:555
#. i18n: ectx: property (whatsThis), widget (QCheckBox, enableChatFormattingCheckBox_)
@@ -6088,7 +6082,7 @@ msgstr "\"Messenger &Plus!\" biçimlendirmesini etkinleştir"
#. i18n: ectx: property (text), widget (QCheckBox, showContactEmailCheckBox_)
#: rc.cpp:778
msgid "Show the &email address of contacts instead of their friendly name"
msgstr ""
msgstr "Kişilerimin görünen adlarının yerine &e-posta adreslerini göster"
#. i18n: file: settings/emoticonspage.ui:24
#. i18n: ectx: attribute (title), widget (QWidget, tab)
@@ -6099,9 +6093,8 @@ msgstr "İfade &Temaları"
#. i18n: file: settings/emoticonspage.ui:36
#. i18n: ectx: property (text), widget (QLabel, textLabel1)
#: rc.cpp:784
#, fuzzy
msgid "Available emoticon themes:"
msgstr "Mümkün olan İfade stilleri:"
msgstr "Mümkün olan ifade temaları:"
#. i18n: file: settings/emoticonspage.ui:73
#. i18n: ectx: attribute (title), widget (QWidget, tab_2)
@@ -6149,9 +6142,8 @@ msgstr "&Sil"
#. i18n: file: settings/emoticonspage.ui:173
#. i18n: ectx: property (text), widget (QLabel, textLabel1_2)
#: rc.cpp:817
#, fuzzy
msgid "Available custom emoticons:"
msgstr "Mümkün olan İfade stilleri:"
msgstr "Mümkün olan özel ifadeler:"
#. i18n: file: settings/miscellaneouspage.ui:27
#. i18n: ectx: attribute (title), widget (QWidget, tab)
@@ -6169,7 +6161,7 @@ msgstr ""
#. i18n: ectx: property (text), widget (QRadioButton, useKDEBrowserRadio_)
#: rc.cpp:826
msgid "&Use the KDE default browser"
msgstr ""
msgstr "Ö&ntanımlı KDE tarayıcısını kullan"
#. i18n: file: settings/miscellaneouspage.ui:43
#. i18n: ectx: property (toolTip), widget (QRadioButton, useListedBrowserRadio_)
@@ -6183,7 +6175,7 @@ msgstr ""
#. i18n: ectx: property (text), widget (QRadioButton, useListedBrowserRadio_)
#: rc.cpp:832
msgid "&Use an installed browser:"
msgstr ""
msgstr "&Kurulu bir tarayıcıyı kullan:"
#. i18n: file: settings/miscellaneouspage.ui:80
#. i18n: ectx: property (toolTip), widget (QRadioButton, useCustomBrowserRadio_)
@@ -6198,9 +6190,8 @@ msgstr ""
#. i18n: file: settings/miscellaneouspage.ui:217
#. i18n: ectx: property (text), widget (QRadioButton, useCustomMailClientRadio_)
#: rc.cpp:838 rc.cpp:873
#, fuzzy
msgid "&Specify a custom command:"
msgstr "Uzakta durumu için ileti belirle"
msgstr "Ö&zel bir komut belirle:"
#. i18n: file: settings/miscellaneouspage.ui:113
#. i18n: ectx: property (whatsThis), widget (QLineEdit, customBrowserEdit_)
@@ -6218,7 +6209,7 @@ msgstr ""
#: rc.cpp:846
#, no-c-format
msgid "Use '%u' to insert the URL in the command line."
msgstr ""
msgstr "Komut satırına URL'yi eklemek için '%u' kullanın."
#. i18n: file: settings/miscellaneouspage.ui:151
#. i18n: ectx: attribute (title), widget (QWidget, tab_2)
@@ -6238,7 +6229,7 @@ msgstr ""
#. i18n: ectx: property (text), widget (QCheckBox, useLiveMailCheckbox_)
#: rc.cpp:855
msgid "Use &Live Mail if the account supports it"
msgstr ""
msgstr "Hesap destekliyorsa &Live Mail Kullan"
#. i18n: file: settings/miscellaneouspage.ui:167
#. i18n: ectx: property (toolTip), widget (QRadioButton, useKDEMailClientRadio_)
@@ -6250,33 +6241,32 @@ msgstr ""
#. i18n: ectx: property (text), widget (QRadioButton, useKDEMailClientRadio_)
#: rc.cpp:861
msgid "Use the &KDE default email client"
msgstr ""
msgstr "Öntanımlı &KDE e-posta istemcisini kullan"
#. i18n: file: settings/miscellaneouspage.ui:180
#. i18n: ectx: property (text), widget (QRadioButton, useListedMailClientRadio_)
#: rc.cpp:867
msgid "Use an &installed email client:"
msgstr ""
msgstr "K&urulu bir e-posta istemcisini kullan:"
#. i18n: file: settings/miscellaneouspage.ui:260
#. i18n: ectx: property (text), widget (QLabel, customMailClientInfo_)
#: rc.cpp:881
#, no-c-format
msgid "Use '%u' to insert the email address in the command line."
msgstr ""
msgstr "Komut satırına e-posta adresini eklemek için '%u' kullanın."
#. i18n: file: settings/miscellaneouspage.ui:294
#. i18n: ectx: property (text), widget (QCheckBox, useReceivedFilesDir_)
#: rc.cpp:887
#, fuzzy
msgid "&Save all received files in one directory:"
msgstr "Sohbetleri bu dizine kaydet:"
msgstr "Alınan tüm dosyaları bir dizinde &kaydet:"
#. i18n: file: settings/miscellaneouspage.ui:343
#. i18n: ectx: property (text), widget (QLabel, label_2)
#: rc.cpp:893
msgid "&Use ports between"
msgstr ""
msgstr "Dosya aktarımları için"
#. i18n: file: settings/miscellaneouspage.ui:369
#. i18n: ectx: property (text), widget (QLabel, label_3)
@@ -6288,7 +6278,7 @@ msgstr "ve"
#. i18n: ectx: property (text), widget (QLabel, label_4)
#: rc.cpp:899
msgid "for file transfers"
msgstr "dosya aktarımları için"
msgstr "aralığındaki portları kullan"
#. i18n: file: utils/inlineeditlabel.ui:14
#. i18n: ectx: property (windowTitle), widget (QWidget, InlineEditLabel)
+1 -1
View File
@@ -15,7 +15,7 @@ msgstr ""
"PO-Revision-Date: 2009-11-18 19:28+0100\n"
"Last-Translator: Panagiotis Papadopoulos <pano_90@gmx.net>\n"
"Language-Team: en_US <kde-i18n-doc@kde.org>\n"
"Language: \n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+1
View File
@@ -13,6 +13,7 @@ msgstr ""
"PO-Revision-Date: 2010-09-10 08:34+0800\n"
"Last-Translator: Yen-chou Chen <yenchou.mse90@nctu.edu.tw>\n"
"Language-Team: Chinese Traditional <zh-l10n@linux.org.tw>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+50 -46
View File
@@ -1,5 +1,5 @@
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} ${KDE4_INCLUDE_DIR} ${QT_INCLUDES} ${GCRYPT_INCLUDE_DIRS} )
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${GCRYPT_INCLUDE_DIRS})
########### next target ###############
@@ -30,6 +30,7 @@ SET(kmess_SOURCES
dialogs/awaymessagedialog.cpp
dialogs/chathistorydialog.cpp
dialogs/contactaddeduserdialog.cpp
dialogs/contactaddeduserwidget.cpp
dialogs/contactentry.cpp
dialogs/contactpropertiesdialog.cpp
dialogs/invitedialog.cpp
@@ -86,6 +87,7 @@ SET(kmess_SOURCES
settings/chatloggingpage.cpp
settings/chatstylepage.cpp
settings/emoticonspage.cpp
settings/filetransfersettingspage.cpp
settings/globalsettingsdialog.cpp
settings/miscellaneouspage.cpp
utils/crashhandler.cpp
@@ -101,6 +103,7 @@ SET(kmess_SOURCES
utils/xautolock.cpp
utils/xmlfunctions.cpp
utils/gradientelidelabel.cpp
utils/faderwidget.cpp
account.cpp
accountaction.cpp
accountsmanager.cpp
@@ -128,7 +131,7 @@ SET(kmess_UI_FILES
dialogs/addemoticondialog.ui
dialogs/awaymessagedialog.ui
dialogs/chathistorydialog.ui
dialogs/contactaddeduserdialog.ui
dialogs/contactaddeduserwidget.ui
dialogs/transferentry.ui
dialogs/transferwindow.ui
dialogs/contactentry.ui
@@ -142,23 +145,50 @@ SET(kmess_UI_FILES
settings/chatloggingpage.ui
settings/chatstylepage.ui
settings/emoticonspage.ui
settings/filetransfersettingspage.ui
settings/miscellaneouspage.ui
utils/inlineeditlabel.ui
)
SET(kmess_LIBS
${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS}
${KDE4_KIO_LIBS}
${KDE4_KHTML_LIBS}
${KDE4_KNOTIFYCONFIG_LIBS}
${KDE4_KNEWSTUFF2_LIBS}
${KDE4_PHONON_LIBS}
${KDE4_SOLID_LIBS}
Qt6::Core
Qt6::Core5Compat
Qt6::DBus
Qt6::Gui
Qt6::Multimedia
Qt6::Network
Qt6::Test
Qt6::WebEngineWidgets
Qt6::Widgets
Qt6::Xml
isf-qt
KF6::ConfigCore
KF6::ConfigGui
KF6::ConfigWidgets
KF6::Codecs
KF6::Completion
KF6::CoreAddons
KF6::Crash
KF6::DBusAddons
KF6::IdleTime
KF6::I18n
KF6::IconThemes
KF6::KIOCore
KF6::KIOWidgets
KF6::Notifications
KF6::NotifyConfig
KF6::Parts
KF6::Service
KF6::Solid
KF6::StatusNotifierItem
KF6::TextWidgets
KF6::WidgetsAddons
KF6::WindowSystem
KF6::Wallet
KF6::XmlGui
${LIBXML2_LIBRARIES}
${LIBXSLT_LIBRARIES}
${GCRYPT_LIBRARIES}
${QT_QTTEST_LIBRARY}
)
IF( ${GIF_FOUND} )
@@ -166,10 +196,7 @@ IF( ${GIF_FOUND} )
SET( kmess_LIBS ${kmess_LIBS} ${GIF_LIBRARIES} )
ENDIF( ${GIF_FOUND} )
IF( ISFQT_FOUND )
INCLUDE_DIRECTORIES( ${ISFQT_INCLUDE_DIR} )
SET( kmess_LIBS ${kmess_LIBS} ${ISFQT_LIBRARIES} )
ENDIF( ISFQT_FOUND )
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/contrib/isf-qt/include )
# If LikeBack is enabled, compile it
IF( NOT ${KMESS_DISABLE_LIKEBACK} EQUAL 1 )
@@ -188,16 +215,8 @@ if(APPLE)
set(kmess_SOURCES ${kmess_SOURCES} notification/macnotification.cpp)
endif(APPLE)
#new system tray spec - optional
IF( HAVE_NEW_TRAY )
SET( kmess_SOURCES ${kmess_SOURCES}
notification/newsystemtraywidget.cpp )
INCLUDE_DIRECTORIES( ${KNOTIFICATIONITEM_INCLUDE_DIR} )
SET( kmess_LIBS ${kmess_LIBS} ${KNOTIFICATIONITEM_LIBRARIES} )
ELSE()
SET( kmess_SOURCES ${kmess_SOURCES}
notification/systemtraywidget.cpp )
ENDIF()
SET( kmess_SOURCES ${kmess_SOURCES}
notification/newsystemtraywidget.cpp )
# If we're compiling in debug mode:
IF( ${KMESS_ENABLE_DEBUG_OUTPUT} EQUAL 1 )
@@ -214,33 +233,18 @@ IF( ${KMESS_ENABLE_DEBUG_OUTPUT} EQUAL 1 )
ENDIF( CMAKE_BUILD_TYPE STREQUAL debugfull )
ENDIF( ${KMESS_ENABLE_DEBUG_OUTPUT} EQUAL 1 )
# Add XScreensaver library for away-idle detection.
IF( X11_Xscreensaver_FOUND )
SET(kmess_LIBS ${kmess_LIBS} ${X11_Xscreensaver_LIB} ${X11_LIBRARIES} )
ENDIF( X11_Xscreensaver_FOUND )
IF( ${KDE_VERSION} VERSION_LESS 4.4.0 )
# Set our KDE debug number to be the default
add_definitions( -DKDE_DEFAULT_DEBUG_AREA=5130 )
ENDIF()
# Define the app icon for Windows / Mac OS
SET( kmess_SRCS )
KDE4_ADD_APP_ICON( kmess_SRCS ../data/icons/hi*-app-kmess.png )
SET( kmess_SOURCES ${kmess_SOURCES} ${kmess_SRCS} )
# Create a DBus adapter from XML file
QT4_ADD_DBUS_ADAPTOR( kmess_SOURCES utils/kmessdbus.xml utils/kmessdbus.h KMessDBus )
qt_add_dbus_adaptor( kmess_DBUS_SRCS utils/kmessdbus.xml utils/kmessdbus.h KMessDBus )
# Define all files
KDE4_ADD_UI_FILES( kmess_SOURCES ${kmess_UI_FILES} )
KDE4_ADD_EXECUTABLE( kmess ${kmess_SOURCES} )
qt_wrap_ui( kmess_UI_SRCS ${kmess_UI_FILES} )
add_executable( kmess ${kmess_SOURCES} ${kmess_UI_SRCS} ${kmess_DBUS_SRCS} )
target_include_directories( kmess PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} )
# Link to final executable
TARGET_LINK_LIBRARIES( kmess ${kmess_LIBS} )
INSTALL( TARGETS kmess DESTINATION ${BIN_INSTALL_DIR})
INSTALL( FILES chat/chatwindowui.rc DESTINATION ${DATA_INSTALL_DIR}/kmess )
INSTALL( FILES kmessinterfaceui.rc DESTINATION ${DATA_INSTALL_DIR}/kmess )
INSTALL( FILES chat/chatwindowui.rc DESTINATION ${KDE_INSTALL_KXMLGUIDIR}/kmess )
INSTALL( FILES kmessinterfaceui.rc DESTINATION ${KDE_INSTALL_KXMLGUIDIR}/kmess )
+27 -11
View File
@@ -19,17 +19,17 @@
#include "contact/msnobject.h"
#include "utils/kmessconfig.h"
#include "utils/kmessshared.h"
#include "accountsmanager.h"
#include "kmessdebug.h"
#include <QDir>
#include <QRegExp>
#include <QRegularExpression>
#include <KConfigGroup>
#include <KGlobal>
#include <KLocale>
#include <KStandardDirs>
#include <KLocalizedString>
#ifdef KMESSDEBUG_ACCOUNT
@@ -54,7 +54,7 @@ Account::Account()
friendlyName_( i18n("Your name"), false ), // Do not parse this name, CurrentAccount is not ready when initializing
guestAccount_(true),
groupFollowupMessages_(true),
handle_( i18n("you@hotmail.com") ),
handle_( i18n("you@escargot.chat") ),
hideNotificationsWhenBusy_(true),
idleTime_(5),
initialStatus_(STATUS_ONLINE),
@@ -649,7 +649,7 @@ int Account::getListPictureSize() const
// Return the path to the current display picture
const QString Account::getPicturePath( bool fallBack ) const
{
static QString defaultPicture( KGlobal::dirs()->findResource( "data", "kmess/pics/kmesspic.png" ) );
static QString defaultPicture( KMessShared::findResource( "data", "kmess/pics/kmesspic.png" ) );
// Return the picture path if the user has selected to show it; else return an empty string
if( ! showPicture_ )
@@ -726,7 +726,27 @@ bool Account::isGuestAccount() const
// Validate a contact email
bool Account::isValidEmail( QString email )
{
return email.contains( QRegExp( "^[A-Z0-9._%\\-]+@(?:[A-Z0-9\\-]+\\.)+[A-Z]{2,4}$", Qt::CaseInsensitive ) );
static const QRegularExpression emailPattern(
"^[A-Z0-9._%\\-]+@(?:[A-Z0-9\\-]+\\.)+[A-Z]{2,}$",
QRegularExpression::CaseInsensitiveOption );
return emailPattern.match( email ).hasMatch();
}
// Validate a Messenger handle
bool Account::isValidHandle( QString handle )
{
handle = handle.trimmed();
if( isValidEmail( handle ) )
{
return true;
}
static const QRegularExpression escargotNamePattern(
"^[A-Z0-9._%\\-]{1,64}$",
QRegularExpression::CaseInsensitiveOption );
return escargotNamePattern.match( handle ).hasMatch();
}
@@ -828,7 +848,7 @@ void Account::readProperties( const QString &handle )
// This default is "Fresh" as of 1.5 final, to improve the first impression a user gets.
// The previous "Default" theme has been renamed to "Classic".
// This code also makes the migration from 1.5-pre2 to 1.5 (and beyond) easier.
if( KGlobal::dirs()->findResource( "data", "kmess/styles/" + chatStyle_ + '/' + chatStyle_ + ".xsl" ).isEmpty() )
if( KMessShared::findResource( "data", "kmess/styles/" + chatStyle_ + '/' + chatStyle_ + ".xsl" ).isEmpty() )
{
#ifdef KMESSDEBUG_ACCOUNT_DIRTY
kmDebug() << "Auto-corrected chat & setting, setting 'dirty' to true.";
@@ -1787,7 +1807,3 @@ void Account::updateMsnObject()
emit changedMsnObject();
}
}
#include "account.moc"
+2
View File
@@ -285,6 +285,8 @@ class Account : public QObject
public: // Static public members
// Validate a contact email
static bool isValidEmail( QString email );
// Validate a Messenger handle. Escargot/NINA can also use plain usernames.
static bool isValidHandle( QString handle );
protected: // Protected methods
// Update the email-supported state (protected method)
+4 -9
View File
@@ -24,17 +24,14 @@
// The constructor
AccountAction::AccountAction(Account *account, QWidget *parent )
: KAction(parent),
: QAction(parent),
account_(account)
{
setObjectName( "AccountAction[" + account->getHandle() + ']' );
// The idea is to have an action that sends the account when its
// normal "activated" signal is sent.
// Then connect this action's regular "activated" signal to the action's
// slotActivated slot, which will then emit an "activated(account)"
// signal.
connect( this, SIGNAL( activated() ),
// QAction emits triggered(); this class keeps the old activated(account)
// signal for callers that want the associated Account object.
connect( this, SIGNAL( triggered() ),
this, SLOT ( slotActivated() ) );
// Initialize the text by calling update.
@@ -67,5 +64,3 @@ void AccountAction::updateText()
setText( account_->getHandle() );
}
#include "accountaction.moc"
+4 -3
View File
@@ -18,7 +18,8 @@
#ifndef ACCOUNTACTION_H
#define ACCOUNTACTION_H
#include <KAction>
#include <QAction>
#include <QWidget>
// Forward declarations
@@ -33,7 +34,7 @@ class Account;
* @author Mike K. Bennett
* @ingroup Root
*/
class AccountAction : public KAction
class AccountAction : public QAction
{
Q_OBJECT
@@ -48,7 +49,7 @@ class AccountAction : public KAction
void updateText();
protected slots:
//Inherit from KAction...
//Inherit from QAction...
void slotActivated();
private: // Private attributes
+8 -12
View File
@@ -26,7 +26,7 @@
#include <QDir>
#include <KConfig>
#include <KLocale>
#include <KLocalizedString>
#include <KMessageBox>
@@ -177,7 +177,7 @@ void AccountsManager::deleteAccount( Account *account )
emit accountDeleted( account );
QString handle( account->getHandle() );
KMessApplication *kmessApp = static_cast<KMessApplication*>( kapp );
KMessApplication *kmessApp = static_cast<KMessApplication *>(QApplication::instance());
if( kmessApp->getContactListWindow()->isConnected()
&& CurrentAccount::instance()->getHandle() == handle )
@@ -261,7 +261,7 @@ void AccountsManager::initializePasswordManager( bool block )
}
// Obtain the window ID of the main KMess window
KMessApplication *kmessApp = static_cast<KMessApplication*>( kapp );
KMessApplication *kmessApp = static_cast<KMessApplication *>(QApplication::instance());
WId wId = kmessApp->getContactListWindow()->window()->winId();
if( block )
@@ -555,7 +555,7 @@ void AccountsManager::setupPasswordManager()
{
kmWarning() << "Insecure account passwords found for accounts: " << validAccounts;
int res = KMessageBox::questionYesNoCancel( 0,
int res = KMessageBox::questionTwoActionsCancel( 0,
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 insecurely stored passwords, or delete "
@@ -577,7 +577,7 @@ void AccountsManager::setupPasswordManager()
"insecurePasswordsDetected" );
switch( res )
{
case KMessageBox::Yes:
case KMessageBox::PrimaryAction:
// Import passwords to the wallet, and remove the plaintext ones
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
@@ -597,7 +597,7 @@ void AccountsManager::setupPasswordManager()
}
break;
case KMessageBox::No:
case KMessageBox::SecondaryAction:
// Only delete the plain text passwords
#ifdef KMESSDEBUG_ACCOUNTSMANAGER_KWALLET
@@ -656,7 +656,7 @@ void AccountsManager::readProperties()
// Add each one of the saved accounts to the internal list
foreach( const QString &handle, accountList )
{
if( Account::isValidEmail( handle ) )
if( Account::isValidHandle( handle ) )
{
Account *account = new Account();
account->readProperties( handle );
@@ -692,7 +692,7 @@ void AccountsManager::showAccountSettings( Account *account, QWidget *parentWind
#endif
CurrentAccount *currentAccount = CurrentAccount::instance();
KMess *kmess = static_cast<KMessApplication*>( kapp )->getContactListWindow();
KMess *kmess = static_cast<KMessApplication *>(QApplication::instance())->getContactListWindow();
bool isCurrentAccount = ( account->getHandle() == currentAccount->getHandle() );
bool isConnectedCurrentAccount = isCurrentAccount && ( kmess->isConnected() );
@@ -716,7 +716,3 @@ void AccountsManager::showAccountSettings( Account *account, QWidget *parentWind
accountSettingsDialog->show();
accountSettingsDialog->raise();
}
#include "accountsmanager.moc"
+1 -1
View File
@@ -22,7 +22,7 @@
#include <QList>
#include <KWallet/Wallet>
#include <kwallet.h>
// Forward declarations
class Account;
+21 -23
View File
@@ -35,11 +35,13 @@
#include "contactswidget.h"
#include <QDir>
#include <QElapsedTimer>
#include <QFile>
#include <QRegExp>
#include <QUrl>
#include <KFileDialog>
#include <KIO/NetAccess>
#include <QFileDialog>
#include <KLocalizedString>
#include <KMessageBox>
@@ -111,7 +113,7 @@ const QString Chat::chooseContact()
default:
// 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",
KMessageBox::error( this, i18nc( "Error dialog box text",
"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();
@@ -241,7 +243,7 @@ void Chat::contactTyping( ContactBase *contact, bool forceExpiration )
// Do not add anything to the list if the friendly name is empty
if( ! handle.isEmpty() )
{
QTime startTime = QTime::currentTime();
QElapsedTimer startTime;
// If a contact is still typing, re-insert it in the list, so that the typing start time is updated
if( typingContactsNames_.contains( handle ) )
@@ -273,7 +275,7 @@ void Chat::contactTyping( ContactBase *contact, bool forceExpiration )
}
// Update the list to remove expired typing events
QMutableHashIterator<QString,QTime> it( typingContactsTimes_ );
QMutableHashIterator<QString,QElapsedTimer> it( typingContactsTimes_ );
while( it.hasNext() )
{
it.next();
@@ -398,14 +400,14 @@ const QStringList Chat::getParticipants() const
// Return the icon to use in the tab icon chat
KIcon Chat::getParticipantsTabIcon()
QIcon Chat::getParticipantsTabIcon()
{
const QStringList participants( getParticipants() );
// If there are more participants use group icon
if( participants.count() != 1 )
{
return KIcon( "system-users" );
return QIcon::fromTheme( "system-users" );
}
// Else use the status icon of the current contact
@@ -415,10 +417,10 @@ KIcon Chat::getParticipantsTabIcon()
const ContactBase *contact = currentAccount_->getContactByHandle( handle );
if( contact == 0 )
{
return KIcon( "view-media-artist" );
return QIcon::fromTheme( "view-media-artist" );
}
return KIcon( MsnStatus::getIcon( contact->getStatus() ) );
return QIcon( MsnStatus::getIcon( contact->getStatus() ) );
}
@@ -658,7 +660,7 @@ void Chat::receivedMessage(const ChatMessage &message)
if( currentAccount_ != 0
&& msnSwitchboardConnection_ != 0
&& currentAccount_->getAutoreply()
&& ( lastSentAutoMessage_.isNull() || lastSentAutoMessage_.elapsed() > 120000 ) )
&& ( ! lastSentAutoMessage_.isValid() || lastSentAutoMessage_.elapsed() > 120000 ) )
{
// Send an auto away message every two minutes (if the contact keeps writing)
@@ -734,7 +736,7 @@ void Chat::endChatLogging()
return;
}
KMessApplication *kmessApp = static_cast<KMessApplication*>( kapp );
KMessApplication *kmessApp = static_cast<KMessApplication *>(QApplication::instance());
bool canDoUserInteraction = ! kmessApp->quitSelected(); // Not if we're exiting
QDir dir;
@@ -811,7 +813,7 @@ void Chat::endChatLogging()
if( canDoUserInteraction )
{
KMessageBox::sorry( getChatWindow(),
KMessageBox::error( getChatWindow(),
i18n( "<html>KMess could not save the log for the chat with &quot;%1&quot;:<br />"
"The chat logs directory, &quot;%2&quot;, does not exist.</html>",
currentAccount_->getContactFriendlyNameByHandle( participants.first() ),
@@ -1510,7 +1512,7 @@ void Chat::slotSendingFailed( const QString &handle, const MimeMessage &message
}
else if( contentType.startsWith( "text/plain" ) && ! message.getBody().isEmpty() )
{
QString body( Qt::escape( message.getBody() ) );
QString body( message.getBody().toHtmlEscaped() );
// Cut down the message a bit if needed
if( body.length() > 16 )
@@ -1571,7 +1573,7 @@ void Chat::startFileTransfer( QList<QUrl> fileList )
#endif
// If no file names were given, ask for a filename
KUrl fileName( KFileDialog::getOpenUrl( KUrl( "kfiledialog:///:fileupload" ) ) );
QUrl fileName( QFileDialog::getOpenFileUrl( getChatWindow() ) );
// Stop if no file was selected
if( fileName.isEmpty() )
@@ -1584,7 +1586,7 @@ void Chat::startFileTransfer( QList<QUrl> fileList )
foreach( const QUrl &fileUrl, fileList )
{
KUrl localFileUrl( KIO::NetAccess::mostLocalUrl( fileUrl, this ) );
QUrl localFileUrl( fileUrl );
// If the url can't be translated to a local file, copy it to disk
if( ! localFileUrl.isLocalFile() )
@@ -1594,7 +1596,7 @@ void Chat::startFileTransfer( QList<QUrl> fileList )
#endif
// Download the remote file to a temporary folder
QString localFilePath;
if( ! KIO::NetAccess::download( fileUrl, localFilePath, this ) )
if( ! KMessShared::downloadToLocalFile( fileUrl, localFilePath ) )
{
#ifdef KMESSDEBUG_CHAT_FILETRANSFER
kmDebug() << "Copy failed.";
@@ -1605,13 +1607,13 @@ void Chat::startFileTransfer( QList<QUrl> fileList )
false,
i18n( "The file &quot;%1&quot; could not be found on "
"your computer, and the download failed.",
localFileUrl.prettyUrl() ),
localFileUrl.toDisplayString() ),
handle ) );
continue;
}
// TODO Remove the temporary file after the transfer
localFileUrl.setUrl( localFilePath );
localFileUrl = QUrl( QUrl::fromLocalFile( localFilePath ) );
}
#ifdef KMESSDEBUG_CHAT_FILETRANSFER
@@ -1654,7 +1656,7 @@ void Chat::slotSendNudge()
ChatMessage::CONTENT_NOTIFICATION_NUDGE,
false,
messageText,
QString::null );
QString() );
showMessage( message );
// Send nudge
@@ -1749,7 +1751,3 @@ void Chat::startChat()
scrollToBottom( true /* forced scrolling */ );
}
#include "chat.moc"
+8 -6
View File
@@ -23,8 +23,10 @@
#include "../network/msnswitchboardconnection.h"
#include <QHash>
#include <QElapsedTimer>
#include <QStringList>
#include <QTimer>
#include <QIcon>
// Forward declarations
@@ -79,7 +81,7 @@ class Chat : public ChatView
// Return the list of contacts in the chat
const QStringList getParticipants() const;
// Return the icon to use in the tab icon chat
KIcon getParticipantsTabIcon();
QIcon getParticipantsTabIcon();
// Return the list of previously sent messages
QStringList &getQuickRetypeList();
// Return the date and time the chat has started
@@ -91,7 +93,7 @@ class Chat : public ChatView
// Return the switchboard connection used by the chat window.
MsnSwitchboardConnection * getSwitchboardConnection() const;
// Invite a contact to the chat
void inviteContacts( const QStringList &contacts );
void inviteContacts( const QStringList &contacts ) override;
// Return whether or not the contact is in this chat. Check also if the chat is exclusive with the contact.
bool isContactInChat( const QString &handle, bool isExclusiveChatWithContact = false );
// Return whether or not the chat is at its first incoming message
@@ -118,7 +120,7 @@ class Chat : public ChatView
void showWink( const QString &handle, const QString &filename, const QString &animationName );
public slots:
void showMessage( const ChatMessage &message );
void showMessage( const ChatMessage &message ) override;
// A message was received from a contact.
void receivedMessage(const ChatMessage &message);
// Change the switchboard connection used by the chat window.
@@ -126,7 +128,7 @@ class Chat : public ChatView
// Send a nudge
void slotSendNudge();
// Send a file to a contact.
void startFileTransfer( QList<QUrl> fileList = QList<QUrl>() );
void startFileTransfer( QList<QUrl> fileList = QList<QUrl>() ) override;
private: // Private methods
// Choose the contact to start an invitation with.
@@ -158,7 +160,7 @@ class Chat : public ChatView
// The last contacts known to have been in the chat. Kept for emergency, when there's no switchboard
QStringList lastKnownContacts_;
// The last time an automessage has been sent
QTime lastSentAutoMessage_;
QElapsedTimer lastSentAutoMessage_;
// The xml chat log writer
ChatHistoryWriter* logWriter_;
// The object that connects to the switchboard server.
@@ -171,7 +173,7 @@ class Chat : public ChatView
// The list of names of contacts which are currently typing
QHash<QString,QString> typingContactsNames_;
// The list of times when the contacts have started typing
QHash<QString,QTime> typingContactsTimes_;
QHash<QString,QElapsedTimer> typingContactsTimes_;
// A timer to update the typing information
QTimer typingTimer_;
// Handle a command from ChatView (e.g. '/online')
+7 -9
View File
@@ -26,10 +26,10 @@
#include <QApplication>
#include <QDir>
#include <QLocale>
#include <QMutexLocker>
#include <KGlobal>
#include <KLocale>
#include <KLocalizedString>
#ifdef KMESSDEBUG_CHATHISTORYMANAGER
@@ -66,11 +66,11 @@ QString ChatHistoryManager::account()
*/
QString ChatHistoryManager::chatHeader( const quint64 timestamp )
{
const QDateTime date( QDateTime::fromTime_t( timestamp ) );
const QDateTime date( QDateTime::fromSecsSinceEpoch( timestamp ) );
return "<header>\n"
"<date>" + KGlobal::locale()->formatDate( date.date(), KLocale::ShortDate ) + "</date>\n"
"<time>" + KGlobal::locale()->formatTime( date.time(), KLocale::ShortDate ) + "</time>\n"
"<date>" + QLocale().toString( date.date(), QLocale::ShortFormat ) + "</date>\n"
"<time>" + QLocale().toString( date.time(), QLocale::ShortFormat ) + "</time>\n"
"</header>\n";
}
@@ -419,6 +419,8 @@ ChatHistoryWriter* ChatHistoryManager::getWriter( const QString& handle )
/**
* Add a new chat to the logs, or update an ongoing one.
*
* @param handle
* Handle of the main contact in conversation
* @param chatLogData
* The details of the chat log to be updated
*/
@@ -569,7 +571,6 @@ void ChatHistoryManager::setAccount( const QString newAccount )
handle_ = QString();
result_ = RESULT_OK;
timestamps_.clear();
timestamps_.setInsertInOrder( true );
// Refresh the list of contacts
contactsList();
@@ -639,7 +640,6 @@ ConversationList ChatHistoryManager::timestamps()
}
timestamps_.clear();
timestamps_.setInsertInOrder( true );
QDir logsDir( KMessConfig::instance()->getAccountDirectory( account_ ) + "/chatlogs" );
@@ -680,5 +680,3 @@ ConversationList ChatHistoryManager::timestamps()
return timestamps_;
}
+1 -1
View File
@@ -201,7 +201,7 @@ void ChatHistoryWriter::logMessage( const ChatMessage& message )
kmDebug() << "Adding conversation tag..";
#endif
quint64 timestamp = message.getDateTime().toTime_t();
quint64 timestamp = message.getDateTime().toSecsSinceEpoch();
isFirstMessage_ = false;
const QByteArray conversationHeader( "\n\n<conversation timestamp=\""
+ QString::number( timestamp ).toLatin1()
+31 -23
View File
@@ -42,11 +42,9 @@
#include <QTextDocument>
#include <QTest>
#include <KWindowSystem>
#ifdef Q_WS_X11
# include <QX11Info>
#endif
#include <KLocalizedString>
#include <kwindowsystem.h>
#include <kx11extras.h>
// Settings for debugging
#define CHATMASTER_SEND_FILES_MSNFTP 0
@@ -183,7 +181,7 @@ void ChatMaster::connected()
void ChatMaster::disconnected()
{
// Don't waste time disabling the chats when exiting.
KMessApplication *kmessApp = static_cast<KMessApplication*>( kapp );
KMessApplication *kmessApp = static_cast<KMessApplication *>(QApplication::instance());
if( kmessApp->quitSelected() )
{
return;
@@ -722,7 +720,10 @@ void ChatMaster::raiseChat( Chat *chat, bool force )
// 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() );
if( KWindowSystem::isPlatformX11() )
{
KX11Extras::setOnDesktop( chatWindow->winId(), KX11Extras::currentDesktop() );
}
}
// Making windows raise and get focus interrupts the user... it's better to make them appear minimized,
@@ -762,11 +763,6 @@ void ChatMaster::raiseChat( Chat *chat, bool force )
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 );
@@ -775,8 +771,8 @@ void ChatMaster::raiseChat( Chat *chat, bool force )
// Set the keyboard focus to the chat window
chatWindow->raise();
KWindowSystem::activateWindow( chatWindow->winId() );
KApplication::setActiveWindow( chatWindow );
KWindowSystem::activateWindow( chatWindow->windowHandle() );
chatWindow->activateWindow();
}
@@ -1055,7 +1051,7 @@ void ChatMaster::slotContactChangedMsnObject( Contact *contact )
kmDebug() << "Contact '" << handle << "' removed its MSN object";
#endif
contact->getExtension()->setContactPicturePath( QString::null );
contact->getExtension()->setContactPicturePath( QString() );
return;
}
@@ -1092,7 +1088,7 @@ void ChatMaster::slotContactChangedMsnObject( Contact *contact )
kmWarning() << "Corrupt picture was already set, "
<< "resetting contact picture." << endl;
#endif
contact->getExtension()->setContactPicturePath( QString::null );
contact->getExtension()->setContactPicturePath( QString() );
}
}
}
@@ -1385,7 +1381,7 @@ void ChatMaster::slotGotInkMessage( const QString &ink, const QString &contactHa
ChatMessage::CONTENT_MESSAGE_INK,
true,
"<img src=\"data:" + imageMimeType + ";"
"base64," + Qt::escape( inkEncodedData ) + "\">",
"base64," + QString::fromLatin1( inkEncodedData ).toHtmlEscaped() + "\">",
contactHandle,
friendlyName,
contactPicture ), switchboard );
@@ -1676,8 +1672,16 @@ Chat *ChatMaster::createChat( MsnSwitchboardConnection *switchboard, bool reques
Chat *newChat;
ChatWindow *newChatWindow;
// If the new chat is a group chat, find existing group chat windows; else find private chats
const QStringList partecipants( switchboard->getContactsInChat() );
// If the new chat is a group chat, find existing group chat windows; else find private chats.
// Escargot can briefly request a chat window while the switchboard has no resolved contact yet.
QStringList partecipants( switchboard->getContactsInChat() );
partecipants.removeAll( QString() );
if( partecipants.isEmpty() )
{
kmWarning() << "Ignoring chat window request without contacts.";
return 0;
}
newChat = getContactsChat( partecipants, true );
// If the chat was requested by a contact, check if we have a chat request
@@ -1732,11 +1736,18 @@ Chat *ChatMaster::createChat( MsnSwitchboardConnection *switchboard, bool reques
if( ! newChat->initialize( switchboard ) )
{
kmDebug() << "Couldn't initialize the chat tab.";
delete newChat;
return 0;
}
// Select the chat window where to open the new tab, or create a new one
newChatWindow = createChatWindow( newChat );
if( newChatWindow == 0 )
{
kmWarning() << "Couldn't create the chat window.";
delete newChat;
return 0;
}
// Create the first tab in the chat
newChat = newChatWindow->addChatTab( newChat, switchboard->getUserStartedChat() );
@@ -1808,6 +1819,7 @@ ChatWindow *ChatMaster::createChatWindow( Chat *chat )
if( ! window->initialize() )
{
kmWarning() << "Couldn't initialize the new chat window!";
delete window;
return 0;
}
@@ -2275,7 +2287,3 @@ ChatWindow *ChatMaster::findWindowForChat( Chat *chat )
}
return window;
}
#include "chatmaster.moc"
+31 -30
View File
@@ -28,12 +28,14 @@
#include <QDateTime>
#include <QFile>
#include <QList>
#include <QLocale>
#include <QRegExp>
#include <QRegularExpression>
#include <QTextDocument>
#include <KLocale>
#include <KStandardDirs>
#include <KUrl>
#include <KLocalizedString>
#include <QUrl>
#include <QFileInfo>
// 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
@@ -142,7 +144,7 @@ QString ChatMessageStyle::convertMessageList(const QList<ChatMessage*> &messageL
if( messageList.isEmpty() )
{
kmWarning() << "no messages given!";
return QString::null;
return QString();
}
else if( messageList.count() == 1 )
{
@@ -295,7 +297,7 @@ QString ChatMessageStyle::convertMessageRoot()
{
// Indicate the chat style doesn't define the whole header/footer,
// so KMess can use it's default instead.
return QString::null;
return QString();
}
return parsedMessage; // DONE!
}
@@ -307,7 +309,7 @@ QString ChatMessageStyle::convertMessageRoot()
}
}
return QString::null;
return QString();
}
@@ -350,7 +352,7 @@ QString ChatMessageStyle::createFallbackMessage(const ChatMessage &message)
if( ! message.hasHtmlBody() )
{
// Escape HTML, replace all emoticons, links and formatting
RichTextParser::parseMsnString( body, useEmoticons_, false, true, useFormatting_, allowEmoticonLinks_, handle, pendingEmoticonTags_ );
RichTextParser::parseMsnString( body, useEmoticons_, false, true, useFormatting_, allowEmoticonLinks_, handle, &pendingEmoticonTags_ );
// Replace font special effects, like *bold*
if( useFontEffects_ )
@@ -368,11 +370,12 @@ QString ChatMessageStyle::createFallbackMessage(const ChatMessage &message)
QDateTime messageTime = message.getDateTime();
if ( showDate_ )
{
time = KGlobal::locale()->formatDateTime( messageTime, KLocale::ShortDate, showSeconds_ );
time = QLocale().toString( messageTime, showSeconds_ ? QLocale::LongFormat : QLocale::ShortFormat );
}
else
{
time = KGlobal::locale()->formatTime( messageTime.time(), showSeconds_ );
time = showSeconds_ ? QLocale().toString( messageTime.time(), "HH:mm:ss" )
: QLocale().toString( messageTime.time(), QLocale::ShortFormat );
}
}
color = (type == ChatMessage::TYPE_INCOMING || type == ChatMessage::TYPE_OFFLINE_INCOMING)
@@ -447,7 +450,7 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
}
#endif
}
QString body = QString::fromUtf16( newutf16, j );
QString body = QString::fromUtf16( reinterpret_cast<const char16_t*>( newutf16 ), j );
// Get message info
int type = message.getType();
@@ -486,7 +489,7 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
!isPresence,
(isPresence ? false : useFormatting_),
(isPresence ? false : allowEmoticonLinks_),
(isPresence ? QString() : handle), pendingEmoticonTags_ );
(isPresence ? QString() : handle), &pendingEmoticonTags_ );
if( useFontEffects_ )
{
@@ -504,7 +507,7 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
{
// Get the time
const QDateTime &messageDate = message.getDateTime();
timestamp = messageDate.toTime_t();
timestamp = messageDate.toSecsSinceEpoch();
}
@@ -541,15 +544,16 @@ QString ChatMessageStyle::convertMessageToXml( const ChatMessage &message, bool
else
{
QString timeString;
const QDateTime &datetime = QDateTime::fromTime_t( timestamp );
const QDateTime &datetime = QDateTime::fromSecsSinceEpoch( timestamp );
if ( showDate_ )
{
timeString = KGlobal::locale()->formatDateTime( datetime, KLocale::ShortDate, showSeconds_ );
timeString = QLocale().toString( datetime, showSeconds_ ? QLocale::LongFormat : QLocale::ShortFormat );
}
else
{
timeString = KGlobal::locale()->formatTime( datetime.time(), showSeconds_ );
timeString = showSeconds_ ? QLocale().toString( datetime.time(), "HH:mm:ss" )
: QLocale().toString( datetime.time(), QLocale::ShortFormat );
}
xmlMessage = "<message"
@@ -644,7 +648,7 @@ QString ChatMessageStyle::getCssFile() const
QString cssFile( baseFolder_ + name_ + ".css" );
if( ! QFile::exists(cssFile) )
{
return QString::null;
return QString();
}
else
{
@@ -778,7 +782,7 @@ bool ChatMessageStyle::hasStyle() const
void ChatMessageStyle::parseBody(QString &body) const
{
// Replace any newline characters in the message with "<br>" so that carriage returns will show properly.
body = body.replace(QRegExp("\r?\n?$"), QString::null) // Remove last \n
body = body.replace(QRegularExpression("\r?\n?$"), QString()) // Remove last \n
.replace( "\r\n", "<br/>" )
.replace( '\r', "<br/>" )
.replace( '\n', "<br/>" );
@@ -988,8 +992,7 @@ bool ChatMessageStyle::setStyle(const QString &style)
return hasStyle();
}
KStandardDirs *dirs = KGlobal::dirs();
QString path( dirs->findResource( "data", "kmess/styles/" + style + "/" + style + ".xsl" ) );
QString path( KMessShared::findResource( "data", "kmess/styles/" + style + "/" + style + ".xsl" ) );
if(path.isNull())
{
@@ -1005,9 +1008,11 @@ bool ChatMessageStyle::setStyle(const QString &style)
if(styleSheetLoaded)
{
// Update the base folder
KUrl pathUrl;
pathUrl.setPath(path);
baseFolder_ = pathUrl.directory( KUrl::AppendTrailingSlash );
baseFolder_ = QFileInfo( path ).path();
if( ! baseFolder_.endsWith( '/' ) )
{
baseFolder_ += '/';
}
QMap<QString,QString> parameters;
parameters["basepath"] = baseFolder_;
@@ -1070,8 +1075,9 @@ QString ChatMessageStyle::stripDoctype( const QString &parsedMessage )
{
if( parsedMessage.startsWith( "<!DOCTYPE" ) )
{
QRegExp re(">\r?\n?");
int endPos = parsedMessage.indexOf( re );
QRegularExpression re(">\r?\n?");
QRegularExpressionMatch match = re.match( parsedMessage );
int endPos = match.hasMatch() ? match.capturedStart() : -1;
if( endPos == -1 )
{
kmWarning() << "Could not strip DOCTYPE tag: end position not found!";
@@ -1079,15 +1085,10 @@ QString ChatMessageStyle::stripDoctype( const QString &parsedMessage )
}
// Strip both end end possible \r\n character
return parsedMessage.mid( endPos + re.matchedLength() );
return parsedMessage.mid( endPos + match.capturedLength() );
}
else
{
return parsedMessage;
}
}
#include "chatmessagestyle.moc"
+251 -440
View File
@@ -27,53 +27,73 @@
#include <QStringList>
#include <QTimer>
#include <QClipboard>
#include <QLocale>
#include <QUrl>
#include <QWebEngineContextMenuRequest>
#include <QWebEnginePage>
#include <kdeversion.h>
#include <DOM/DOMString>
#include <DOM/Text>
#include <DOM/HTMLDocument>
#include <DOM/HTMLElement>
#include <KHTMLView>
#include <KApplication>
#include <KAction>
#include <QApplication>
#include <QAction>
#include <QIcon>
#include <KLocalizedString>
#include <KStandardAction>
#include <KMenu>
#include <QMenu>
#include <QUrl>
class ChatMessagePage : public QWebEnginePage
{
public:
explicit ChatMessagePage( ChatMessageView *messageView, QObject *parent = nullptr )
: QWebEnginePage( parent )
, messageView_( messageView )
{
}
protected:
bool acceptNavigationRequest( const QUrl &url, NavigationType type, bool isMainFrame ) override
{
Q_UNUSED( isMainFrame );
if( type == QWebEnginePage::NavigationTypeLinkClicked )
{
emit messageView_->openUrlRequest( QUrl( url ) );
return false;
}
return true;
}
private:
ChatMessageView *messageView_;
};
// The constructor
ChatMessageView::ChatMessageView( QWidget *parentWidget, QObject *parent )
: KHTMLPart( parentWidget, parent, DefaultGUI )
: QObject( parent )
, chatClearingMark_(0)
, isEmpty_(true)
, view_( new QWebEngineView( parentWidget ) )
, fontScaleFactor_(100)
, lastMessageId_(0)
{
// Disable features that might do harm or are not useful
setJScriptEnabled( false );
setJavaEnabled( false );
setMetaRefreshEnabled( false );
setOnlyLocalReferences( false );
setSuppressedPopupIndicator( false );
// Enable winks
setPluginsEnabled( true );
#if KDE_IS_VERSION( 4, 1, 0 )
// Add smooth scrolling when possible
view()->setSmoothScrollingMode( KHTMLView::SSMWhenEfficient );
#endif
// Connect signals for browsing
connect( browserExtension(), SIGNAL( openUrlRequestDelayed(const KUrl&,const KParts::OpenUrlArguments&,const KParts::BrowserArguments&) ),
this, SIGNAL( openUrlRequest(const KUrl&) ) );
connect( this, SIGNAL( completed() ),
this, SLOT ( scrollChatToBottom() ) );
view_->setPage( new ChatMessagePage( this, view_ ) );
view_->setContextMenuPolicy( Qt::CustomContextMenu );
connect( view_, &QWidget::customContextMenuRequested, this, [this]( const QPoint &point )
{
QString href;
const QWebEngineContextMenuRequest *request = view_->lastContextMenuRequest();
if( request )
{
href = request->linkUrl().toString();
}
emit popupMenu( href, view_->mapToGlobal( point ) );
} );
connect( view_->page(), &QWebEnginePage::selectionChanged, this, [this]()
{
selectedText_ = view_->page()->selectedText();
} );
// Make sure this widget can't get any focus.
view()->setFocusPolicy( Qt::NoFocus );
// Set a border to the view
view()->setFrameStyle( QFrame::Sunken | QFrame::StyledPanel );
// Initialize the chat style parser
chatStyle_ = new ChatMessageStyle();
@@ -116,72 +136,16 @@ void ChatMessageView::addedEmoticon( QString shortcut )
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Replacing add emoticon links with shortcut '" << shortcut << "'.";
#endif
// The shortcut in emoticon links is url-encoded, convert the original one to match it
shortcut = KUrl::toPercentEncoding( shortcut );
DOM::HTMLElement link, parent, image;
DOM::HTMLDocument document = htmlDocument();
// Find all the list's links which point to this emoticon
DOM::NodeList linksList = document.getElementsByName( "newEmoticon_" + shortcut );
if( linksList.isNull() )
{
return;
}
// Check all the links in the list. The search is done backwards, because when we delete one of the items
// of the list, the list itself shortens down reassigning the indices, and a regular loop would fail
for( long i = (linksList.length() - 1); i >= 0; i-- )
{
link = linksList.item( i );
if( link.isNull() || ! link.isHTMLElement() )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Link null, skipping.";
#endif
continue;
}
// Replace the link with its first child (the emoticon image)
parent = link.parentNode();
image = link.firstChild();
if( parent.isNull() )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Parent null, skipping.";
#endif
continue;
}
if( image.isNull() )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Image null, skipping.";
#endif
continue;
}
parent.replaceChild( image, link );
}
Q_UNUSED( shortcut );
setHtml( rebuildHistory( false ) );
}
void ChatMessageView::addXml( QString xmlString )
{
// Create new HTML node
DOM::HTMLElement newNode = document().createElement( "div" );
newNode.setInnerHTML( chatStyle_->convertXmlMessageList( xmlString ) );
DOM::HTMLElement messageRoot = htmlDocument().getElementById( "messageRoot" );
if( messageRoot.isNull() )
{
messageRoot = htmlDocument().body();
}
messageRoot.appendChild( document().createTextNode("\n") );
messageRoot.appendChild( newNode );
messageRoot.appendChild( document().createTextNode("\n") );
htmlBody_ += "\n<div class=\"messageContainer\">\n"
+ chatStyle_->convertXmlMessageList( xmlString )
+ "\n</div>\n";
renderHtml();
isEmpty_ = false;
}
@@ -192,20 +156,10 @@ void ChatMessageView::addHtmlMessage(const QString &text)
{
lastMessageId_++;
// Create new HTML node
DOM::HTMLElement newNode = document().createElement("div");
newNode.setAttribute( "id", "message" + QString::number(lastMessageId_) );
newNode.setAttribute( "class", "messageContainer" );
newNode.setInnerHTML( text );
DOM::HTMLElement messageRoot = htmlDocument().getElementById("messageRoot");
if( messageRoot.isNull() )
{
messageRoot = htmlDocument().body();
}
messageRoot.appendChild( document().createTextNode("\n") );
messageRoot.appendChild( newNode );
messageRoot.appendChild( document().createTextNode("\n") );
htmlBody_ += "\n<div id=\"message" + QString::number( lastMessageId_ ) + "\" class=\"messageContainer\">\n"
+ text
+ "\n</div>\n";
renderHtml();
isEmpty_ = false;
}
@@ -250,7 +204,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
QString chatHistory;
QString handle( chatMessages_.first()->getContactHandle() );
uint date ( chatMessages_.first()->getDateTime().toTime_t() );
qint64 date( chatMessages_.first()->getDateTime().toSecsSinceEpoch() );
bool oldAllowEmoticonLinks = chatStyle_->getAllowEmoticonLinks();
chatStyle_->setAllowEmoticonLinks( false );
@@ -270,7 +224,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
+ i18nc( "Header of a chat file saved in HTML: %1 is the contact, %2 the date and time",
"Chat with %1<br/>Started on: %2",
handle,
KGlobal::locale()->formatDateTime( QDateTime::fromTime_t( date ), KLocale::ShortDate ) )
QLocale().toString( QDateTime::fromSecsSinceEpoch( date ), QLocale::ShortFormat ) )
+ "\n</div>\n";
chatHistory += rebuildHistory( true );
@@ -283,26 +237,8 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
return chatHistory;
}
// Get a (deep) copy of the current page source
// TODO: document().cloneNode( true ) doesn't work, so this workaround is
// required. Test if it's been fixed, and add a #define to exclude the
// workaround on fixed KHTML versions.
DOM::Document copy( document().implementation().createHTMLDocument( "" ) );
copy.removeChild( copy.documentElement() );
copy.appendChild( copy.importNode( document().documentElement(), true ) );
// Replace the html body with the chat history to be saved
DOM::HTMLElement messageRoot( copy.getElementById( "messageRoot" ) );
if( messageRoot.isNull() )
{
kmWarning() << "Current style does not define the 'messageRoot' element!";
chatStyle_->setAllowEmoticonLinks( oldAllowEmoticonLinks );
return chatHistory;
}
messageRoot.setInnerHTML( "\n" + chatHistory + "\n" );
chatStyle_->setAllowEmoticonLinks( oldAllowEmoticonLinks );
return copy.toString().string();
return buildHtmlPage( chatHistory );
}
@@ -316,7 +252,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
chatHistory += "\n\n"
+ i18nc( "Header of a single chat saved as plain text chat log: %1 is the chat date and time",
"Chat started on: %1",
KGlobal::locale()->formatDateTime( QDateTime::fromTime_t( date ), KLocale::ShortDate ) )
QLocale().toString( QDateTime::fromSecsSinceEpoch( date ), QLocale::ShortFormat ) )
+ "\n------------------------------------------------------------\n";
QListIterator<ChatMessage*> it( chatMessages_ );
@@ -333,7 +269,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
}
else
{
chatHistory += "(" + KGlobal::locale()->formatTime( chatMessage->getTime() ) + ")"
chatHistory += "(" + QLocale().toString( chatMessage->getTime(), QLocale::ShortFormat ) + ")"
" " + chatMessage->getContactHandle() + ":\n"
" " + chatMessage->getBody().trimmed() + "\n";
}
@@ -342,7 +278,7 @@ QString ChatMessageView::getHistory( Account::ChatExportFormat format, bool appe
// Add system messages etc
else
{
chatHistory += "(" + KGlobal::locale()->formatTime( chatMessage->getTime() ) + ")"
chatHistory += "(" + QLocale().toString( chatMessage->getTime(), QLocale::ShortFormat ) + ")"
" " + chatMessage->getBody().trimmed() + "\n";
lastHandle = QString();
}
@@ -404,6 +340,14 @@ bool ChatMessageView::hasHistory() const
// Whether or not text is selected.
bool ChatMessageView::hasSelection() const
{
return ! selectedText_.isEmpty();
}
// Whether or not the message area is empty
bool ChatMessageView::isEmpty() const
{
@@ -412,6 +356,63 @@ bool ChatMessageView::isEmpty() const
// Return the widget used to display the chat.
QWebEngineView *ChatMessageView::view() const
{
return view_;
}
QWidget *ChatMessageView::widget() const
{
return view_;
}
// Return the current selection as plain text.
QString ChatMessageView::selectedText() const
{
return selectedText_;
}
// Return the font scale percentage.
int ChatMessageView::zoomFactor() const
{
return fontScaleFactor_;
}
// Select all chat text.
void ChatMessageView::selectAll()
{
view_->triggerPageAction( QWebEnginePage::SelectAll );
}
// Set the display font scale.
void ChatMessageView::setFontScaleFactor( int percentage )
{
fontScaleFactor_ = percentage;
view_->setZoomFactor( percentage / 100.0 );
}
// Find text in the chat view.
void ChatMessageView::findText()
{
if( ! selectedText_.isEmpty() )
{
view_->findText( selectedText_ );
}
}
// Generate a new HTML chat log
QString ChatMessageView::rebuildHistory( bool fullHistory )
{
@@ -506,73 +507,8 @@ void ChatMessageView::removeCustomEmoticon( const QString &shortcut )
#ifdef KMESSTEST
KMESS_ASSERT( ! shortcut.isEmpty() );
#endif
// Process all IMG tags
#if KDE_IS_VERSION( 4, 1, 0 )
DOM::NodeList emoticonTags( htmlDocument().getElementsByClassName( "customEmoticon" ) );
#else
// See below (within the loop) for the actual filtering by class name
DOM::NodeList emoticonTags( htmlDocument().getElementsByTagName( "img" ) );
#endif
// Get the original (non-HTML) shortcut
QString originalShortcut( KMessShared::htmlUnescape( shortcut ) );
// Proceed one by one: while removing elements, the list shortens too
for( unsigned long item = emoticonTags.length(); item > 0; --item )
{
DOM::HTMLElement img( emoticonTags.item( item - 1 ) );
#if KDE_IS_VERSION( 4, 1, 0 )
#else
// KDE4.0's KHTML DOM didn't have getElementsByClassName(). We therefore
// have to filter the class name here.
if( ! img.className().string().contains( "customEmoticon" ) )
{
continue;
}
#endif
// Check if the element is valid
if( img.isNull() )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Skipped null element.";
#endif
continue;
}
// Get the image's alternative text attribute; if it's not our custom emoticon, skip
// HACK: Search both by the html and plain version, to avoid skipping strange shortcuts
QString altAttribute( img.getAttribute("alt").string() );
if( altAttribute != shortcut && altAttribute != originalShortcut )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Skipped element:" << img.getAttribute("alt").string() << "while searching for" << originalShortcut;
#endif
continue;
}
// We've found one of the emoticons to delete
DOM::HTMLElement parent( img.parentNode() );
// If the emoticon is contained in a link, remove both.
if( parent.tagName().string() == "a" )
{
img = parent;
parent = parent.parentNode();
}
// The text should be that of the original shortcut, not the html-encoded one
DOM::Text textNode( htmlDocument().createTextNode( originalShortcut ) );
// Replace the link with the image inside with the simple text
parent.replaceChild( textNode, img );
// Force updating the view to instantly display the new image
view()->updateContents( img.getRect() );
}
Q_UNUSED( shortcut );
setHtml( rebuildHistory( false ) );
}
@@ -580,18 +516,9 @@ void ChatMessageView::removeCustomEmoticon( const QString &shortcut )
// Replace the last message with a new contents.
void ChatMessageView::replaceLastMessage(const QString &text)
{
// Fetch the HTML node
QString lastId( "message" + QString::number( lastMessageId_ ) );
DOM::HTMLElement lastNode( htmlDocument().getElementById( lastId ) );
if( lastNode.isNull() || ! lastNode.isHTMLElement() )
{
kmWarning() << "message block with id" + lastId + "not found, appending message instead.";
addHtmlMessage( text );
return;
}
// Replace contents
lastNode.setInnerHTML( text );
Q_UNUSED( text );
htmlBody_ = rebuildHistory( false );
renderHtml();
}
@@ -599,7 +526,10 @@ void ChatMessageView::replaceLastMessage(const QString &text)
// Scroll forward or backward within the chat browser
void ChatMessageView::scrollChat( bool forward, bool fast )
{
view()->scrollBy( 0, ( forward ? +1 : -1 ) * view()->visibleHeight() / ( fast ? 1 : 2 ) );
const QString script = QStringLiteral( "window.scrollBy(0, (%1) * window.innerHeight / %2);" )
.arg( forward ? 1 : -1 )
.arg( fast ? 1 : 2 );
view_->page()->runJavaScript( script );
}
@@ -607,8 +537,7 @@ void ChatMessageView::scrollChat( bool forward, bool fast )
// Force scrolling to the bottom of the chat browser
void ChatMessageView::scrollChatToBottom()
{
int contentsHeight = view()->contentsHeight();
view()->scrollBy( 0, contentsHeight );
view_->page()->runJavaScript( QStringLiteral( "window.scrollTo(0, document.body.scrollHeight);" ) );
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Scrolled view down.";
@@ -620,16 +549,10 @@ void ChatMessageView::scrollChatToBottom()
// Scroll to the bottom of the chat browser if needed
void ChatMessageView::scrollChatToBottomGently()
{
int contentsHeight = view()->contentsHeight();
int visibleHeight = view()->visibleHeight();
// If the user has scrolled up more than one viewport of height, don't move
if( contentsHeight - ( view()->contentsY() + visibleHeight ) > visibleHeight )
{
return;
}
view()->scrollBy( 0, contentsHeight );
view_->page()->runJavaScript( QStringLiteral(
"if ((document.body.scrollHeight - window.scrollY - window.innerHeight) <= window.innerHeight) {"
" window.scrollTo(0, document.body.scrollHeight);"
"}" ) );
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Scrolled view down.";
@@ -644,81 +567,85 @@ void ChatMessageView::setHtml( const QString &newHtmlBody )
// Reset state variables
lastMessageId_ = 0;
isEmpty_ = newHtmlBody.isEmpty();
htmlBody_ = newHtmlBody;
renderHtml();
}
// If the style is not working, prepare a standard HTML page
if( ! chatStyle_->canConvert() )
// Render the current HTML body in the browser widget.
void ChatMessageView::renderHtml()
{
view_->setHtml( buildHtmlPage( htmlBody_ ), QUrl::fromLocalFile( chatStyle_->getBaseFolder() + "/" ) );
}
// Wrap the current style around the body contents.
QString ChatMessageView::buildHtmlPage( const QString &body ) const
{
QString cssFile ( chatStyle_->getCssFile () );
QString baseFolder( chatStyle_->getBaseFolder() );
if( ! cssFile.isEmpty() )
{
QString cssFile ( chatStyle_->getCssFile () );
QString baseFolder( chatStyle_->getBaseFolder() );
if( ! cssFile.isEmpty() )
{
cssFile = " <link href=\"" + cssFile + "\" rel=\"stylesheet\" type=\"text/css\">\n";
}
if( ! baseFolder.isEmpty() )
{
baseFolder = " <base href=\"" + baseFolder + "\" id=\"baseHrefTag\">\n";
}
begin();
// Force standard colors, because chat messages will not work
// correctly with the (dark) color scheme anyway.
write( "<html id=\"ChatMessageView\">\n"
" <head>\n"
" <!-- " + getStyleTag() + " -->\n"
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + encoding() + "\">\n"
+ baseFolder +
" <style type=\"text/css\">\n"
" /* standard colors for compatibility with dark color schemes */\n"
" body { font-size: 10pt; margin: 0; padding: 5px; background-color: #fff; color: #000; }\n"
" a:link { color: blue; }\n"
" a:visited { color: purple; }\n"
" a:hover { color: red; }\n"
" a:active { color: red; }\n"
" </style>\n"
+ cssFile +
" </head>\n"
" <body>\n"
" <div id=\"messageRoot\">\n"
+ newHtmlBody +
" </div>\n"
" </body>\n"
"</html>\n" );
end();
return;
cssFile = " <link href=\"" + cssFile + "\" rel=\"stylesheet\" type=\"text/css\">\n";
}
if( ! baseFolder.isEmpty() )
{
baseFolder = " <base href=\"" + baseFolder + "\" id=\"baseHrefTag\">\n";
}
begin();
// Write the style's root elements
write( chatStyle_->convertMessageRoot() );
// Add the style tag
DOM::NodeList list( document().getElementsByTagName("head") );
if( ! list.isNull() )
// Prefer the style's root page when available, but fall back to a minimal
// compatible page.
QString page;
if( chatStyle_->canConvert() )
{
DOM::Node head = list.item( 0 );
head.insertBefore( document().createComment( getStyleTag() ), head.firstChild() );
}
// Insert under root the given HTML body, but do nothing if we're just clearing it up
// (the new page is empty already)
if( ! newHtmlBody.isEmpty() )
{
DOM::HTMLElement messageRoot = document().getElementById( "messageRoot" );
if( messageRoot.isNull() )
page = chatStyle_->convertMessageRoot();
int insertPos = page.indexOf( "</head>", 0, Qt::CaseInsensitive );
if( insertPos != -1 )
{
kmWarning() << "Chat style does not define the 'messageRoot' element!";
messageRoot = htmlDocument().body();
page.insert( insertPos, " <!-- " + getStyleTag() + " -->\n" );
}
messageRoot.setInnerHTML( "\n" + newHtmlBody + "\n" );
int rootStart = page.indexOf( "id=\"messageRoot\"" );
if( rootStart == -1 )
{
rootStart = page.indexOf( "id='messageRoot'" );
}
if( rootStart != -1 )
{
int divEnd = page.indexOf( '>', rootStart );
if( divEnd != -1 )
{
page.insert( divEnd + 1, "\n" + body + "\n" );
return page;
}
}
kmWarning() << "Chat style does not define the 'messageRoot' element!";
}
// Complete loading
end();
return "<html id=\"ChatMessageView\">\n"
" <head>\n"
" <!-- " + getStyleTag() + " -->\n"
" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"
+ baseFolder +
" <style type=\"text/css\">\n"
" body { font-size: 10pt; margin: 0; padding: 5px; background-color: #fff; color: #000; }\n"
" a:link { color: blue; }\n"
" a:visited { color: purple; }\n"
" a:hover { color: red; }\n"
" a:active { color: red; }\n"
" </style>\n"
+ cssFile +
" </head>\n"
" <body>\n"
" <div id=\"messageRoot\">\n"
+ body +
" </div>\n"
" </body>\n"
"</html>\n";
}
@@ -834,20 +761,25 @@ void ChatMessageView::showMessage( const ChatMessage &message )
// Replace an application's accept/reject/cancel links with another text
void ChatMessageView::updateApplicationMessage( const QString &messageId, const QString &newMessage )
{
DOM::HTMLDocument document( htmlDocument() );
DOM::HTMLElement linksSpan = document.getElementById( "app" + messageId + "-links-block" );
// This chat doesn't contain messages for this application, bail out
if( linksSpan.isNull() )
const QString marker = "id=\"app" + messageId + "-links-block\"";
int markerPos = htmlBody_.indexOf( marker );
if( markerPos == -1 )
{
return;
}
// Change the span's ID so it won't trigger changes anymore
linksSpan.setId( DOM::DOMString( "app" + messageId ) );
const int spanStart = htmlBody_.lastIndexOf( "<span", markerPos );
const int spanEnd = htmlBody_.indexOf( "</span>", markerPos );
if( spanStart == -1 || spanEnd == -1 )
{
return;
}
// Replace the links with the given text
linksSpan.setInnerText( DOM::DOMString( newMessage ) );
QString replacement = "<span id=\"app" + messageId + "\">";
replacement += newMessage.toHtmlEscaped();
replacement += "</span>";
htmlBody_.replace( spanStart, spanEnd + 7 - spanStart, replacement );
renderHtml();
}
@@ -934,133 +866,10 @@ void ChatMessageView::updateCustomEmoticon( const QString &code, const QString &
kmWarning() << "can't update custom emoticon, replacement not found (contact=" << handle << ").";
return;
}
// The pattern used to find if the new custom emoticon is already in our theme
QString customEmoticonsPattern( EmoticonManager::instance()->getHtmlPattern( true ).pattern() );
// Process all pending tags, avoid parsing all <img> tags
DOM::HTMLDocument document = htmlDocument();
foreach( const QString &tag, pendingEmoticonTags_ )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Checking DOM element '" << tag << "'";
#endif
// Check if the element is valid
DOM::HTMLElement img = document.getElementById( tag );
if( img.isNull() )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Skipped null element.";
#endif
continue;
}
// Get the image's alternative text attribute
QString imageAltText( img.getAttribute("alt").string() );
// Before converting the alt attribute, save it; we'll use it later
QString originalCode( imageAltText );
// KHTML's DOM converts all HTML entities to text; so we have to convert them back,
// to be able to compare the image's code to the emoticon's (which is already encoded)
KMessShared::htmlEscape( imageAltText );
// See if this element's ALT attribute matches the shortcut
if( img.isNull() || imageAltText != code )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Skipped invalid element (searched '" << code << "', found '" << imageAltText << "').";
#endif
continue;
}
// Also check whether the handle is also set, avoid replacing someone elses code.
if( img.getAttribute("contact") != handle )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Emoticon code found, but different handle: " << img.getAttribute("contact");
#endif
continue;
}
// Update image placeholder attributes (replacing childs is too much trouble).
// Create a regexp to parse the replacement attributes.
QRegExp attribRegExp(
"([a-z]+)=" // words followed by an =
"(?:" // start of options
"'([^']*)'|" // attrib separated by single quote, or..
"\"([^\"]*)\"|" // attrib separated by double quote, or..
"([^ \t\r\n>]+)" // attrib followed by space, newline, tab, endtag
")" // end of options
);
#ifdef KMESSTEST
KMESS_ASSERT( attribRegExp.isValid() );
#endif
int attribPos = 0;
while(true)
{
// Find next attribute
attribPos = attribRegExp.indexIn(replacement, attribPos);
if( attribPos == -1 )
{
break;
}
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Emoticon replacement has attribute: " << attribRegExp.cap(1) << "=" << attribRegExp.cap(2);
#endif
img.setAttribute( attribRegExp.cap(1), attribRegExp.cap(2) );
// Also change the image's class and reset its ID
img.setAttribute( "class", "customEmoticon" );
img.setAttribute( "id", "" );
attribPos += attribRegExp.matchedLength();
}
// Allow the user to "steal" this emoticon
if( handle != CurrentAccount::instance()->getHandle()
&& ! customEmoticonsPattern.contains( code ) )
{
#ifdef KMESSDEBUG_CHATMESSAGEVIEW
kmDebug() << "Inserting emoticon addition link";
#endif
// Copy the original image to a new one we'll modify
DOM::HTMLElement newImage = img.cloneNode( true );
// Remove any title in the emoticon image, as it would be displayed instead of the
// title from the link we're creating
newImage.setAttribute( "title", "" );
// URL-encode the shortcut, so the emoticon adding dialog will get a correct representation,
// even if it contains characters which would fool the link parser.
QString urlCode( KUrl::toPercentEncoding( code ) );
// Create a new 'link' element
// The name attribute is required as, if the user adds the emoticon, we'll want to make all links like this unclickable
DOM::HTMLElement newLink = document.createElement("a");
newLink.setAttribute( "name", "newEmoticon_" + urlCode );
newLink.setAttribute( "title", i18n( "Add this emoticon: %1", code ) ); // Not escaped for " or ', KHTML does it
newLink.setAttribute( "href", "kmess://emoticon/" + handle + "/" + urlCode + "/"
+ KUrl::toPercentEncoding( newImage.getAttribute("src").string() ) );
// Add the new image as child of the new link
newLink.appendChild( newImage );
// And put the link in place of the old image
img.parentNode().replaceChild( newLink, img );
}
}
// Force updating the view to display instantly the new image
view()->updateContents( QRect( view()->contentsX(),
view()->contentsY(),
view()->visibleWidth(),
view()->visibleHeight() ) );
Q_UNUSED( code );
Q_UNUSED( replacement );
Q_UNUSED( handle );
setHtml( rebuildHistory( false ) );
}
//
@@ -1068,26 +877,30 @@ void ChatMessageView::updateCustomEmoticon( const QString &code, const QString &
// Attaches them to slots on this class.
//
// Users of this class can add their own entries to the popup menu by getting
// the KMenu instance representing the popup using ChatMessageView::popupMenu().
// the QMenu instance representing the popup using ChatMessageView::popupMenu().
//
void ChatMessageView::createPopupMenuActions()
{
copyAction_ = KStandardAction::copy( this, SLOT(slotCopyChatText()), this );
selectAllAction_ = KStandardAction::selectAll( this, SLOT(slotSelectAllChatText()), this );
findAction_ = KStandardAction::find( this, SLOT(slotFindChatText()), this );
copyAction_ = new QAction( QIcon::fromTheme( "edit-copy" ), i18n("&Copy Text"), this );
selectAllAction_ = new QAction( QIcon::fromTheme( "edit-select-all" ), i18n("Select &All"), this );
findAction_ = new QAction( QIcon::fromTheme( "edit-find" ), i18n("Find &Text..." ), this );
connect( copyAction_, SIGNAL(triggered(bool)), this, SLOT(slotCopyChatText()) );
connect( selectAllAction_, SIGNAL(triggered(bool)), this, SLOT(slotSelectAllChatText()) );
connect( findAction_, SIGNAL(triggered(bool)), this, SLOT(slotFindChatText()) );
}
//
// Returns a KMenu containing the "basic" items for a popup menu for a chatmessageview
// Returns a QMenu containing the "basic" items for a popup menu for a chatmessageview
// These basic items are "Select All", "Copy Text" and "Find text".
//
// NOTE: It is the CALLER'S responsibility to delete the KMenu instance. It is also their
// responsibility to actually show the menu using KMenu::exec().
// NOTE: It is the CALLER'S responsibility to delete the QMenu instance. It is also their
// responsibility to actually show the menu using QMenu::exec().
//
KMenu *ChatMessageView::popupMenu()
QMenu *ChatMessageView::popupMenu()
{
// Add items to this context menu
KMenu *contextMenu = new KMenu( view() );
QMenu *contextMenu = new QMenu( view() );
// Update the labels a bit though
copyAction_ ->setText( i18n("&Copy Text") );
@@ -1108,7 +921,7 @@ KMenu *ChatMessageView::popupMenu()
void ChatMessageView::slotCopyChatText()
{
// For HTML use selectedTextAsHTML();
kapp->clipboard()->setText( selectedText() );
QApplication::clipboard()->setText( selectedText() );
}
// The user clicked the "find text" option in the context menu
@@ -1122,5 +935,3 @@ void ChatMessageView::slotSelectAllChatText()
{
selectAll();
}
#include "chatmessageview.moc"
+40 -13
View File
@@ -20,25 +20,23 @@
#include "account.h"
#include <KHTMLPart>
#include <KParts/BrowserExtension>
#include <KAction>
#include <QAction>
#include <QUrl>
#include <QWebEngineView>
class ChatMessage;
class ChatMessageStyle;
class CurrentAccount;
class QStringList;
/**
* This class is used to display chat messages.
* A KHTMLPart is used for this because unlike QTextBrowser, KHTML has support for CSS.
*
* @author Diederik van der Boor
* @ingroup Chat
*/
class ChatMessageView : public KHTMLPart
class ChatMessageView : public QObject
{
Q_OBJECT
@@ -58,6 +56,8 @@ class ChatMessageView : public KHTMLPart
QString getStyleTag() const;
// Whether or not there are any messages
bool hasHistory() const;
// Whether or not text is selected.
bool hasSelection() const;
// Whether or not the message area is empty
bool isEmpty() const;
// Delete an emoticon from the chat.
@@ -66,8 +66,16 @@ class ChatMessageView : public KHTMLPart
void updateCustomEmoticon( const QString &code, const QString &replacement, const QString &handle );
// Replace the entire contents with a new chat in XML
void setXml( const QString &newXmlBody );
// Retrieve the KMenu for the context menu.
KMenu* popupMenu();
// Return the widget used to display the chat.
QWebEngineView *view() const;
// Return the widget used to display the chat, for old KHTMLPart call sites.
QWidget *widget() const;
// Retrieve the QMenu for the context menu.
QMenu* popupMenu();
// Return the current selection as plain text.
QString selectedText() const;
// Return the font scale percentage.
int zoomFactor() const;
public slots:
// Finds the links to add a custom emoticon, and remove them because we've already added that emoticon
@@ -89,6 +97,12 @@ class ChatMessageView : public KHTMLPart
void scrollChatToBottom();
// Scroll to the bottom of the chat browser if needed
void scrollChatToBottomGently();
// Select all chat text.
void selectAll();
// Set the display font scale.
void setFontScaleFactor( int percentage );
// Find text in the chat view.
void findText();
// Add the given message to the message browser.
void showMessage( const ChatMessage &message );
// Replace an application's accept/reject/cancel links with another text
@@ -105,6 +119,10 @@ class ChatMessageView : public KHTMLPart
void replaceLastMessage( const QString &text );
// Replace the entire contents with new HTML code
void setHtml( const QString &newHtmlBody );
// Render the current HTML body in the browser widget.
void renderHtml();
// Wrap the current style around the body contents.
QString buildHtmlPage( const QString &body ) const;
// Create the context menu actions. Should only get called once.
void createPopupMenuActions();
@@ -124,6 +142,14 @@ class ChatMessageView : public KHTMLPart
CurrentAccount *currentAccount_;
// Whether or not the chat message area is empty
bool isEmpty_;
// WebEngine replacement for the old KHTMLPart widget.
QWebEngineView *view_;
// Current body contents inserted under the chat style root.
QString htmlBody_;
// Current font scale percentage.
int fontScaleFactor_;
// Last selected text as reported by WebEngine.
QString selectedText_;
// The last messages sent by the same contact. This is used to combine them
QList<ChatMessage*> lastContactMessages_;
// The last message id, for replaceLastMessage()
@@ -131,16 +157,17 @@ class ChatMessageView : public KHTMLPart
// The list of custom emoticons which haven't been received yet
QStringList pendingEmoticonTags_;
// The KActions associated with the context menu
KAction* copyAction_;
KAction* selectAllAction_;
KAction* findAction_;
QAction* copyAction_;
QAction* selectAllAction_;
QAction* findAction_;
signals:
// Signal that there's an application command
void appCommand(QString cookie, QString contact, QString method);
// Signal a click on an URL
void openUrlRequest( const KUrl &url );
void openUrlRequest( const QUrl &url );
// Signal a context-menu request.
void popupMenu( const QString &clickedUrl, const QPoint &point );
};
#endif
+2 -6
View File
@@ -21,7 +21,7 @@
#include <KColorScheme>
#include <KIconLoader>
#include <KLocale>
#include <KLocalizedString>
#include <QFontMetrics>
#include <QPainter>
@@ -102,7 +102,7 @@ void ChatStatusBar::setMessage( MessageType type, const QString& text )
break;
}
pixmap_ = ( iconName == 0 ) ? QPixmap() : SmallIcon( iconName );
pixmap_ = ( iconName == 0 ) ? QPixmap() : QIcon::fromTheme( iconName ).pixmap( 16, 16 );
QTimer::singleShot( GeometryTimeout, this, SLOT( assureVisibleText() ) );
update();
}
@@ -369,7 +369,3 @@ inline int ChatStatusBar::minimumTextHeight() const
{
return minTextHeight_;
}
#include "chatstatusbar.moc"
+2 -2
View File
@@ -64,9 +64,9 @@ class ChatStatusBar: public QWidget
protected:
// Paint the statusbar.
virtual void paintEvent ( QPaintEvent *event);
virtual void paintEvent ( QPaintEvent *event) override;
// Statusbar is resized, update it.
virtual void resizeEvent( QResizeEvent *event);
virtual void resizeEvent( QResizeEvent *event) override;
private slots:
// Update the background color.
+54 -54
View File
@@ -34,19 +34,22 @@
#include <QClipboard>
#include <QDropEvent>
#include <QEvent>
#include <QMimeData>
#include <QRegExp>
#include <QTemporaryFile>
#include <QTextCodec>
#include <QTextDocument>
#include <QTextStream>
#include <QTextOption>
#include <KAction>
#include <KFileDialog>
#include <KHTMLView>
#include <KLocale>
#include <KMenu>
#include <QAction>
#include <QFileDialog>
#include <QIcon>
#include <KLocalizedString>
#include <KLocalizedString>
#include <QMenu>
#include <KMessageBox>
#include <KRun>
#include <QDesktopServices>
#include <KStandardAction>
@@ -63,8 +66,8 @@ ChatView::ChatView( QWidget *parent )
chatMessageView_ = new ChatMessageView( this, this );
connect( chatMessageView_, SIGNAL( popupMenu(const QString&,const QPoint&) ),
this, SLOT ( slotShowContextMenu(const QString&,const QPoint&) ) );
connect( chatMessageView_, SIGNAL( openUrlRequest(const KUrl&) ),
this, SLOT( slotOpenURLRequest(const KUrl&) ) );
connect( chatMessageView_, SIGNAL( openUrlRequest(const QUrl&) ),
this, SLOT( slotOpenURLRequest(const QUrl&) ) );
connect( this, SIGNAL( updateApplicationMessage(const QString&,const QString&) ),
chatMessageView_, SLOT( updateApplicationMessage(const QString&,const QString&) ) );
@@ -119,7 +122,7 @@ void ChatView::editCopy()
return;
}
kapp->clipboard()->setText( chatMessageView_->selectedText() );
QApplication::clipboard()->setText( chatMessageView_->selectedText() );
// use selectedTextAsHTML() and setData() to copy HTML instead of text
}
@@ -249,7 +252,7 @@ bool ChatView::eventFilter( QObject *obj, QEvent *event )
foreach( const QString &handle, handles )
{
// Don't try to invite random strings, nonexistent handles
if( ! Account::isValidEmail( handle )
if( ! Account::isValidHandle( handle )
|| currentAccount_->getContactByHandle( handle ) == 0 )
{
handles.removeAll( handle );
@@ -398,7 +401,7 @@ bool ChatView::saveChatToFile( const QString &path, Account::ChatExportFormat fo
QFileInfo info( file );
kmWarning() << "File save failed! Could not open file" << path << ".";
KMessageBox::sorry( chatMessageView_->view(), i18n( "Could not save chat log in directory '%1'.\n"
KMessageBox::error( chatMessageView_->view(), i18n( "Could not save chat log in directory '%1'.\n"
"Make sure you have permission to write in "
"the folder where logs are being saved.",
info.absolutePath() ) );
@@ -478,12 +481,12 @@ bool ChatView::saveChatToFile( const QString &path, Account::ChatExportFormat fo
// For plain text logs we use the locale codec
if (format == Account::EXPORT_TEXT)
{
textStream.setCodec( QTextCodec::codecForLocale() );
textStream.setEncoding( QStringConverter::System );
}
// For HTML logs (which are created with the UTF-8 charset) we use UTF-8 encoding
else
{
textStream.setCodec( QTextCodec::codecForName("UTF-8") );
textStream.setEncoding( QStringConverter::Utf8 );
}
textStream << chatHistory;
@@ -557,10 +560,11 @@ void ChatView::showSaveChatDialog()
do
{
// Show a dialog to get a filename from the user.
path = KFileDialog::getSaveFileName( path,
path = QFileDialog::getSaveFileName( chatMessageView_->view(),
QString(),
path,
i18nc( "Chat log saving dialog, file type filter",
"*.html *.htm|Web Page (*.html)\n"
"*.txt|Plain Text Document (*.txt)\n" ) );
"Web Page (*.html *.htm);;Plain Text Document (*.txt)" ) );
// Verify if the user has canceled the command
if( path.isEmpty() )
@@ -605,7 +609,7 @@ void ChatView::showSaveChatDialog()
*/
void ChatView::slotAddContact()
{
QString email( chatViewClickedUrl_.url() );
QString email( chatViewClickedUrl_.toString() );
if( ! chatViewClickedUrl_.isValid() )
{
@@ -639,7 +643,7 @@ void ChatView::slotAddContact()
*/
void ChatView::slotAddNewEmoticon()
{
if( ! chatViewClickedUrl_.isValid() || chatViewClickedUrl_.protocol() != "kmess" || chatViewClickedUrl_.host() != "emoticon" )
if( ! chatViewClickedUrl_.isValid() || chatViewClickedUrl_.scheme() != "kmess" || chatViewClickedUrl_.host() != "emoticon" )
{
#ifdef KMESSDEBUG_CHATVIEW
kmDebug() << "Ignoring request for invalid URL: " << chatViewClickedUrl_;
@@ -677,8 +681,8 @@ void ChatView::slotAddNewEmoticon()
}
// URL-Decode the encoded strings
picture = KUrl::fromPercentEncoding( picture.toAscii() );
shortcut = KUrl::fromPercentEncoding( shortcut.toUtf8() );
picture = QUrl::fromPercentEncoding( picture.toLatin1() );
shortcut = QUrl::fromPercentEncoding( shortcut.toUtf8() );
#ifdef KMESSDEBUG_CHATVIEW
kmDebug() << "Showing Add Emoticon dialog - shortcut=" << shortcut << " picture=" << picture;
@@ -707,7 +711,7 @@ void ChatView::slotClearChat()
// The user clicked the "copy address" or "copy email" option in the context menu
void ChatView::slotCopyAddress()
{
QString url( chatViewClickedUrl_.url() );
QString url( chatViewClickedUrl_.toString() );
if( ! chatViewClickedUrl_.isValid() )
{
@@ -728,7 +732,7 @@ void ChatView::slotCopyAddress()
url = url.mid( 7 );
}
kapp->clipboard()->setText( url );
QApplication::clipboard()->setText( url );
// Reset the url
chatViewClickedUrl_.clear();
@@ -756,7 +760,7 @@ void ChatView::slotFindChatText()
*/
void ChatView::slotIgnoreEmoticon()
{
if( ! chatViewClickedUrl_.isValid() || chatViewClickedUrl_.protocol() != "kmess" || chatViewClickedUrl_.host() != "emoticon" )
if( ! chatViewClickedUrl_.isValid() || chatViewClickedUrl_.scheme() != "kmess" || chatViewClickedUrl_.host() != "emoticon" )
{
#ifdef KMESSDEBUG_CHATVIEW
kmDebug() << "Ignoring request for invalid URL: " << chatViewClickedUrl_;
@@ -793,7 +797,7 @@ void ChatView::slotIgnoreEmoticon()
}
// URL-Decode the encoded strings
shortcut = KUrl::fromPercentEncoding( shortcut.toUtf8() );
shortcut = QUrl::fromPercentEncoding( shortcut.toUtf8() );
// Add the emoticon to the contact's blacklist and update the chat
if( contact->manageEmoticonBlackList( true, shortcut ) )
@@ -805,13 +809,13 @@ void ChatView::slotIgnoreEmoticon()
// Open a new url clicked in the khtml widget
void ChatView::slotOpenURLRequest( const KUrl &url )
void ChatView::slotOpenURLRequest( const QUrl &url )
{
chatViewClickedUrl_ = url;
// Internal URLs form: kmess://call_type/parameters?more_parameters
if( url.protocol() == "kmess" )
if( url.scheme() == "kmess" )
{
// Application URLs form: kmess://application/responseType/contactHandle?cookieId
if( url.host() == "application" )
@@ -832,14 +836,15 @@ void ChatView::slotOpenURLRequest( const KUrl &url )
currentAccount_, window(), AccountSettingsDialog::PageChatStyle );
}
}
else if( url.protocol() == "file" )
else if( url.scheme() == "file" )
{
// Obtain the widget of the main KMess window, to correctly link it to the opened app
KMessApplication *kmessApp = static_cast<KMessApplication*>( kapp );
KMessApplication *kmessApp = static_cast<KMessApplication *>(QApplication::instance());
QWidget *mainWindow = kmessApp->getContactListWindow()->window();
// Execute the local file with the system's default association (KRun auto-deletes itself)
new KRun( url, mainWindow, 0, true );
// Execute the local file with the system's default association.
Q_UNUSED( mainWindow );
QDesktopServices::openUrl( url );
}
else
{
@@ -890,10 +895,10 @@ void ChatView::setInkDrawing( Isf::Drawing* newDrawing )
void ChatView::slotSendAppCommand()
{
// Ignore non-internal links and non-application internal links
if( ! chatViewClickedUrl_.isValid() || chatViewClickedUrl_.protocol() != "kmess" || chatViewClickedUrl_.host() != "application" )
if( ! chatViewClickedUrl_.isValid() || chatViewClickedUrl_.scheme() != "kmess" || chatViewClickedUrl_.host() != "application" )
{
#ifdef KMESSDEBUG_CHATVIEW
kmDebug() << "Not sending invalid application link: " << chatViewClickedUrl_.url();
kmDebug() << "Not sending invalid application link: " << chatViewClickedUrl_.toString();
#endif
return;
@@ -928,10 +933,10 @@ void ChatView::slotSendAppCommand()
// The user right clicked at the KHTMLPart to show a popup.
void ChatView::slotShowContextMenu( const QString &clickedUrl, const QPoint &point )
{
KAction *urlAction = 0;
QAction *urlAction = 0;
// Add items to this context menu
KMenu *contextMenu = chatMessageView_->popupMenu();
QMenu *contextMenu = chatMessageView_->popupMenu();
// separate the "copy/find/select all" actions from the chat-specific ones below.
contextMenu->addSeparator();
@@ -939,42 +944,42 @@ void ChatView::slotShowContextMenu( const QString &clickedUrl, const QPoint &poi
// Analyze incoming URL, if present
if( ! clickedUrl.isEmpty() )
{
KUrl url( clickedUrl );
QUrl url( clickedUrl );
#ifdef KMESSDEBUG_CHATVIEW
kmDebug() << "Clicked URL: " << url.prettyUrl();
kmDebug() << "Clicked URL: " << url.toDisplayString();
#endif
if( url.protocol() == "kmess" && url.host() == "emoticon" )
if( url.scheme() == "kmess" && url.host() == "emoticon" )
{
urlAction = new KAction( KIcon( "list-add" ), i18n("Add this &Emoticon..."), this );
urlAction = new QAction( QIcon::fromTheme( "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("Hide this &Emoticon"), this );
urlAction = new QAction( QIcon::fromTheme( "list-remove" ), i18n("Hide this &Emoticon"), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotIgnoreEmoticon()) );
contextMenu->addAction( urlAction );
}
else if( url.protocol().left( 6 ) == "mailto" )
else if( url.scheme().left( 6 ) == "mailto" )
{
urlAction = new KAction( KIcon( "mail" ), i18n("Send &Email"), this );
urlAction = new QAction( QIcon::fromTheme( "mail" ), i18n("Send &Email"), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotVisitAddress()) );
contextMenu->addAction( urlAction );
urlAction = new KAction( KIcon( "list-add-user" ), i18n("Add &Contact"), this );
urlAction = new QAction( QIcon::fromTheme( "list-add-user" ), i18n("Add &Contact"), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotAddContact()) );
contextMenu->addAction( urlAction );
urlAction = new KAction( KIcon( "copy" ), i18n("Copy E&mail Address"), this );
urlAction = new QAction( QIcon::fromTheme( "copy" ), i18n("Copy E&mail Address"), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotCopyAddress()) );
contextMenu->addAction( urlAction );
}
else
{
urlAction = new KAction( KIcon( "launch" ), i18n("Visit &Link"), this );
urlAction = new QAction( QIcon::fromTheme( "document-open-remote" ), i18n("Visit &Link"), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotVisitAddress()) );
contextMenu->addAction( urlAction );
urlAction = new KAction( KIcon( "edit-copy" ), i18n("Copy &Address"), this );
urlAction = new QAction( QIcon::fromTheme( "edit-copy" ), i18n("Copy &Address"), this );
connect( urlAction, SIGNAL(triggered(bool)), this, SLOT(slotCopyAddress()) );
contextMenu->addAction( urlAction );
}
@@ -987,8 +992,8 @@ void ChatView::slotShowContextMenu( const QString &clickedUrl, const QPoint &poi
#endif
// Create items
KAction *clearChatAction = KStandardAction::clear( this, SLOT(slotClearChat()), 0 );
KAction *saveToFileAction = KStandardAction::save( this, SLOT(showSaveChatDialog()), 0 );
QAction *clearChatAction = KStandardAction::clear( this, SLOT(slotClearChat()), 0 );
QAction *saveToFileAction = KStandardAction::save( this, SLOT(showSaveChatDialog()), 0 );
// Update the labels a bit though
clearChatAction ->setText( i18n("C&lear Chat") );
@@ -1043,9 +1048,9 @@ void ChatView::slotVisitAddress()
#endif
// Launch the browser for the given URL
if( chatViewClickedUrl_.protocol() == "mailto" )
if( chatViewClickedUrl_.scheme() == "mailto" )
{
currentAccount_->openMailAtCompose( chatViewClickedUrl_.url().mid( 7 ) );
currentAccount_->openMailAtCompose( chatViewClickedUrl_.toString().mid( 7 ) );
}
else
{
@@ -1080,8 +1085,3 @@ void ChatView::updateCustomEmoticon( const QString &handle, const QString &code
const QString &replacement = contact->getEmoticonReplacements()[code];
chatMessageView_->updateCustomEmoticon( code, replacement, handle );
}
#include "chatview.moc"
+3 -3
View File
@@ -99,7 +99,7 @@ class ChatView : public QWidget
private: // Private methods
// Event filter to detect special actions in the message editor.
bool eventFilter( QObject *obj, QEvent *event );
bool eventFilter( QObject *obj, QEvent *event ) override;
// Invite a contact to the chat
virtual void inviteContacts( const QStringList &contacts ) = 0;
// Send a file to a contact.
@@ -117,7 +117,7 @@ class ChatView : public QWidget
// Add an emoticon from the chat to the contact's emoticon blacklist
void slotIgnoreEmoticon();
// Open a new url clicked in the khtml widget
void slotOpenURLRequest( const KUrl &url );
void slotOpenURLRequest( const QUrl &url );
// The user right clicked at the KHTMLPart to show a popup.
void slotShowContextMenu(const QString &url, const QPoint &point);
// The user clicked the "visit address" or "send email" option in the context menu, or clicked a link in the ChatMessageView
@@ -133,7 +133,7 @@ class ChatView : public QWidget
// The embedded khtml part
ChatMessageView *chatMessageView_;
// URL address which has been right-clicked
KUrl chatViewClickedUrl_;
QUrl chatViewClickedUrl_;
// The current ink the user is drawing
Isf::Drawing *inkDrawing_;
// Whether or not the object was initialized
+165 -122
View File
@@ -44,26 +44,35 @@
#include <QBuffer>
#include <QDir>
#include <QDockWidget>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QKeyEvent>
#include <QLocale>
#include <QMimeData>
#include <QMouseEvent>
#include <QRegularExpression>
#include <QShortcut>
#include <QTabBar>
#include <QTabWidget>
#include <QTextDocumentFragment>
#include <QDesktopWidget>
#include <KAction>
#include <QAction>
#include <KActionMenu>
#include <KColorDialog>
#include <KConfigGroup>
#include <KFontDialog>
#include <KHelpMenu>
#include <KMenu>
#include <KMenuBar>
#include <KLocalizedString>
#include <QMenu>
#include <QMenuBar>
#include <KMessageBox>
#include <KStandardAction>
#include <KStatusBar>
#include <KTabBar>
#include <KStandardGuiItem>
#include <QStatusBar>
#include <KToolBar>
#include <KToolInvocation>
#include <KWindowSystem>
#include <kwindowsystem.h>
#include <KStandardShortcut>
#include <KIconLoader>
#include <QColorDialog>
#include <QFontDialog>
#ifdef KMESSDEBUG_CHATWINDOW
#define KMESSDEBUG_CHATWINDOW_TYPING_MESSAGES
@@ -159,20 +168,20 @@ ChatWindow::ChatWindow( QWidget *parent )
messageEdit_->viewport()->installEventFilter( this );
// Set the button icons
standardEmoticonButton_->setIcon( KIcon( "face-smile" ) );
customEmoticonButton_ ->setIcon( KIcon( "face-smile-gearhead-female" ) );
inkButton_ ->setIcon( KIcon( "draw-brush" ) );
winksButton_ ->setIcon( KIcon( "applications-toys" ) );
textButton_ ->setIcon( KIcon( "draw-text" ) );
fontButton_ ->setIcon( KIcon( "preferences-desktop-font" ) );
fontColorButton_ ->setIcon( KIcon( "format-stroke-color" ) );
standardEmoticonButton_->setIcon( QIcon::fromTheme( "face-smile" ) );
customEmoticonButton_ ->setIcon( QIcon::fromTheme( "face-smile-gearhead-female" ) );
inkButton_ ->setIcon( QIcon::fromTheme( "draw-brush" ) );
winksButton_ ->setIcon( QIcon::fromTheme( "applications-toys" ) );
textButton_ ->setIcon( QIcon::fromTheme( "draw-text" ) );
fontButton_ ->setIcon( QIcon::fromTheme( "preferences-desktop-font" ) );
fontColorButton_ ->setIcon( QIcon::fromTheme( "format-stroke-color" ) );
// Set up the buttons for setting ink colour/stroke size/etc.
inkCanvas_->setPenSize( inkPenSize_->value() );
inkColorButton_->setIcon( KIcon( "format-stroke-color" ) );
inkEraseButton_->setIcon( KIcon( "draw-eraser" ) );
inkClearButton_->setIcon( KIcon( "edit-clear" ) );
inkColorButton_->setIcon( QIcon::fromTheme( "format-stroke-color" ) );
inkEraseButton_->setIcon( QIcon::fromTheme( "draw-eraser" ) );
inkClearButton_->setIcon( QIcon::fromTheme( "edit-clear" ) );
connect( inkColorButton_, SIGNAL( clicked() ),
this, SLOT ( slotChangeInkColor() ) );
@@ -183,30 +192,21 @@ ChatWindow::ChatWindow( QWidget *parent )
connect( inkPenSize_, SIGNAL( valueChanged(int) ),
inkCanvas_, SLOT ( setPenSize(int) ) );
// Connect the message edit so that if its displayed color changes,
// it's checked to match the user's chosen color.
connect( messageEdit_, SIGNAL( currentColorChanged(const QColor&) ),
this, SLOT ( editorColorChanged(const QColor&) ) );
// Connect the docks signals
connect( standardEmoticonsDock_, SIGNAL( visibilityChanged(bool) ),
this, SLOT ( slotEmoticonDocksToggled() ) );
connect( customEmoticonsDock_, SIGNAL( visibilityChanged(bool) ),
this, SLOT ( slotEmoticonDocksToggled() ) );
// And the tab widget signals
connect( chatTabs_, SIGNAL( mouseMiddleClick(QWidget*) ),
this, SLOT ( slotTabRemoved(QWidget*) ) );
connect( chatTabs_, SIGNAL( closeRequest(QWidget*) ),
this, SLOT ( slotTabRemoved(QWidget*) ) );
chatTabs_->tabBar()->installEventFilter( this );
connect( chatTabs_, &QTabWidget::tabCloseRequested, this, [this]( int index )
{
slotTabRemoved( chatTabs_->widget( index ) );
} );
connect( chatTabs_, SIGNAL( currentChanged(int) ),
this, SLOT ( slotTabChanged(int) ) );
// Workaround for tab close buttons in KDE 4.0: Enable the buttons on hover
#if KDE_IS_VERSION( 4, 1, 0 )
chatTabs_->setCloseButtonEnabled( true );
#else
chatTabs_->setHoverCloseButton( true );
chatTabs_->setHoverCloseButtonDelayed( true );
#endif
chatTabs_->setTabsClosable( true );
// Create the status bar
statusLabel_ = new ChatStatusBar( this );
@@ -256,6 +256,10 @@ ChatWindow::~ChatWindow()
// Add a new chat tab
Chat *ChatWindow::addChatTab( Chat *newChat, bool foreground )
{
// QTabWidget emits currentChanged() from addTab(). Parent the contacts widget first
// so slotTabChanged() never sees a half-attached chat view.
newChat->getContactsWidget()->setParent( contactsDock_ );
// Connect its main signals
connect( newChat, SIGNAL( chatInfoChanged() ),
this, SLOT ( slotUpdateChatInfo() ) );
@@ -276,10 +280,6 @@ Chat *ChatWindow::addChatTab( Chat *newChat, bool foreground )
chatTabs_->setCurrentIndex( newTabIndex );
}
// Set the appropriate parent of the contactswidget.
// This is needed when a chat is moved to another window.
newChat->getContactsWidget()->setParent( contactsDock_ );
// Apply the window's settings to the tab
newChat->getContactsWidget()->setDockWidget( contactsDock_, dockWidgetArea( contactsDock_ ) );
newChat->setZoomFactor( zoomLevel_ );
@@ -296,7 +296,7 @@ Chat *ChatWindow::addChatTab( Chat *newChat, bool foreground )
nextTabAction_->setEnabled( hasMultipleTabs );
// Tab grouping is disabled, hide the bar
chatTabs_->setTabBarHidden( currentAccount_->getTabbedChatMode() == 2 );
chatTabs_->tabBar()->setVisible( currentAccount_->getTabbedChatMode() != 2 );
return newChat;
}
@@ -372,9 +372,9 @@ bool ChatWindow::closeAllTabs()
// Ask the user for confirmation
if( chatTabs_->count() > 1 // Do not ask if there only is one tab
&& sender() != closeAllAction_ // Do not ask if the user chose the "close all tabs" action
&& ! kapp->sessionSaving() ) // Do not ask if the KDE session is closing
&& ! static_cast<KMessApplication *>(QApplication::instance())->sessionSaving() ) // Do not ask if the KDE session is closing
{
int res = KMessageBox::questionYesNoCancel( this,
int res = KMessageBox::questionTwoActionsCancel( this,
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>" ),
@@ -386,8 +386,8 @@ bool ChatWindow::closeAllTabs()
"closeOneChatTabInfo" );
switch( res )
{
case KMessageBox::Yes : break;
case KMessageBox::No : return closeTab();
case KMessageBox::PrimaryAction : break;
case KMessageBox::SecondaryAction : return closeTab();
case KMessageBox::Cancel:
default : return false;
}
@@ -451,41 +451,40 @@ void ChatWindow::closeWidgetOrTab()
// Create the menus.
void ChatWindow::createMenus()
{
KAction *closeAction, *saveAction, *quitAction;
KAction *copy, *findAction, *zoomIn, *zoomOut, *clearChatAction;
QAction *closeAction, *saveAction, *clearChatAction;
QAction *contactsDockAction, *standardEmoticonsDockAction, *customEmoticonsDockAction;
// Create the actions for "Chat" menu
inviteButton_ = new KAction ( KIcon("list-add-user"), i18n("&Invite..."), this );
sendAction_ = new KAction ( KIcon("folder-remote"), i18n("Send a &File..."), this );
nudgeAction_ = new KAction ( KIcon("preferences-desktop-notification-bell"), i18n("Send a &Nudge!"), this );
historyMenuAction_ = new KActionMenu ( KIcon("chronometer"), i18n("Chat &History..."), this );
saveAction = new KAction ( KIcon("document-save"), i18n("Save Chat..."), this );
closeAllAction_ = new KAction ( KIcon("dialog-close"), i18n("Close &All Tabs"), this );
inviteButton_ = new QAction ( QIcon::fromTheme( "list-add-user" ), i18n("&Invite..."), this );
sendAction_ = new QAction ( QIcon::fromTheme( "folder-remote" ), i18n("Send a &File..."), this );
nudgeAction_ = new QAction ( QIcon::fromTheme( "preferences-desktop-notification-bell" ), i18n("Send a &Nudge!"), this );
historyMenuAction_ = new KActionMenu ( QIcon::fromTheme( "chronometer" ), i18n("Chat &History..."), this );
saveAction = new QAction ( QIcon::fromTheme( "document-save" ), i18n("Save Chat..."), this );
closeAllAction_ = new QAction ( QIcon::fromTheme( "dialog-close" ), i18n("Close &All Tabs"), this );
closeAction = KStandardAction::close ( this, SLOT( closeWidgetOrTab() ) , actionCollection_ );
quitAction = KStandardAction::quit ( kapp, SLOT( quit() ), actionCollection_ );
KStandardAction::quit ( QApplication::instance(), SLOT( quit() ), actionCollection_ );
// Create the actions for "Edit" menu
changeFontAction_ = new KAction ( KIcon("preferences-desktop-font"), i18n("Change &Font"), this );
changeFontColorAction_ = new KAction ( KIcon("format-stroke-color"), i18n("Change Font &Color"), this );
changeFontAction_ = new QAction ( QIcon::fromTheme( "preferences-desktop-font" ), i18n("Change &Font"), this );
changeFontColorAction_ = new QAction ( QIcon::fromTheme( "format-stroke-color" ), i18n("Change Font &Color"), this );
cutAction_ = KStandardAction::cut ( messageEdit_, SLOT( cut() ), actionCollection_ );
copy = KStandardAction::copy ( messageEdit_, SLOT( copy() ), actionCollection_ );
KStandardAction::copy ( messageEdit_, SLOT( copy() ), actionCollection_ );
pasteAction_ = KStandardAction::paste ( messageEdit_, SLOT( paste() ), actionCollection_ );
findAction = KStandardAction::find ( this, SLOT( editFind() ), actionCollection_ );
KStandardAction::find ( this, SLOT( editFind() ), actionCollection_ );
// Create the actions for "View" menu
emoticonAction_ = new KToggleAction( KIcon("face-smile-big"), i18n("Show &Emoticons"), this );
sessionInfoAction_ = new KToggleAction( KIcon("flag-green"), i18n("Show S&tatus Messages"), this );
zoomIn = KStandardAction::zoomIn ( this, SLOT( viewZoomIn() ), actionCollection_ );
zoomOut = KStandardAction::zoomOut( this, SLOT( viewZoomOut() ), actionCollection_ );
emoticonAction_ = new KToggleAction( QIcon::fromTheme( "face-smile-big" ), i18n("Show &Emoticons"), this );
sessionInfoAction_ = new KToggleAction( QIcon::fromTheme( "flag-green" ), i18n("Show S&tatus Messages"), this );
KStandardAction::zoomIn ( this, SLOT( viewZoomIn() ), actionCollection_ );
KStandardAction::zoomOut( this, SLOT( viewZoomOut() ), actionCollection_ );
prevTabAction_ = KStandardAction::back ( this, SLOT( slotSwitchToLeftTab() ), actionCollection_ );
nextTabAction_ = KStandardAction::forward( this, SLOT( slotSwitchToRightTab() ), actionCollection_ );
clearChatAction = KStandardAction::clear ( this, SLOT( viewClearChat() ), actionCollection_ );
panelsMenuAction_ = new KActionMenu ( KIcon("view-choose"), i18n("&Panels"), this );
panelsMenuAction_ = new KActionMenu ( QIcon::fromTheme( "view-choose" ), i18n("&Panels"), this );
// Create the actions for "Settings" menu
spellCheckAction_ = new KToggleAction( KIcon("tools-check-spelling"), i18n("Use &Spell Checking"), this );
spellCheckAction_ = new KToggleAction( QIcon::fromTheme( "tools-check-spelling" ), i18n("Use &Spell Checking"), this );
showMenuBar_ = KStandardAction::showMenubar( this, SLOT( showMenuBar() ), actionCollection_ );
// Add shorter texts for the toolbar items
@@ -498,35 +497,25 @@ void ChatWindow::createMenus()
nextTabAction_->setText ( i18n("Ne&xt Tab") );
nextTabAction_->setIconText( i18n("Ne&xt Tab") );
// Enable some default action shortcuts (preserve the original ones where needed)
nudgeAction_->setShortcut( QKeySequence( "Alt+Z" ) );
closeAction->setShortcuts( QList<QKeySequence>() << QKeySequence( "Ctrl+W" ) << closeAction->shortcut() );
closeAllAction_->setShortcuts( QList<QKeySequence>() << QKeySequence( "Ctrl+Q" ) << closeAllAction_->shortcut() );
prevTabAction_->setShortcuts( QList<QKeySequence>() << QKeySequence( QKeySequence::PreviousChild ) << prevTabAction_->shortcut() );
nextTabAction_->setShortcuts( QList<QKeySequence>() << QKeySequence( QKeySequence::NextChild ) << nextTabAction_->shortcut() );
// Set up the dock actions
contactsDockAction = contactsDock_ ->toggleViewAction();
standardEmoticonsDockAction = standardEmoticonsDock_->toggleViewAction();
customEmoticonsDockAction = customEmoticonsDock_ ->toggleViewAction();
contactsDockAction->setIcon( KIcon("meeting-attending") );
contactsDockAction->setIcon( QIcon::fromTheme( "meeting-attending" ) );
contactsDockAction->setToolTip( i18n("Enable or disable the contacts panel") );
contactsDockAction->setText( i18nc("Toolbar button","Contacts") );
contactsDockAction->setIconText( i18nc("Toolbar button","Contacts") );
contactsDockAction->setShortcut( QKeySequence( "Ctrl+D" ) );
standardEmoticonsDockAction->setIcon( KIcon("face-smile") );
standardEmoticonsDockAction->setIcon( QIcon::fromTheme( "face-smile" ) );
standardEmoticonsDockAction->setToolTip( i18n("Enable or disable the standard emoticons panel") );
standardEmoticonsDockAction->setText( i18nc("Toolbar button","Emoticons") );
standardEmoticonsDockAction->setIconText( i18nc("Toolbar button","Emoticons") );
standardEmoticonsDockAction->setShortcut( QKeySequence( "Ctrl+E" ) );
customEmoticonsDockAction->setIcon( KIcon("face-smile-gearhead-female") );
customEmoticonsDockAction->setIcon( QIcon::fromTheme( "face-smile-gearhead-female" ) );
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" ) );
// Add the dock toggling actions to the Panels menu
panelsMenuAction_->addAction( contactsDockAction );
@@ -598,6 +587,30 @@ void ChatWindow::createMenus()
// Add actions to actionCollection for "Settings" menu
actionCollection_->addAction( "spellCheck", spellCheckAction_ );
// Enable some default action shortcuts (preserve the original ones where needed)
auto defaultShortcuts = []( const QKeySequence &preferred, const QKeySequence &fallback )
{
QList<QKeySequence> shortcuts;
if( ! preferred.isEmpty() )
{
shortcuts << preferred;
}
if( ! fallback.isEmpty() && ! shortcuts.contains( fallback ) )
{
shortcuts << fallback;
}
return shortcuts;
};
actionCollection_->setDefaultShortcut( nudgeAction_, QKeySequence( "Alt+Z" ) );
actionCollection_->setDefaultShortcut( closeAction, QKeySequence( "Ctrl+W" ) );
actionCollection_->setDefaultShortcut( closeAllAction_, QKeySequence( "Ctrl+Q" ) );
actionCollection_->setDefaultShortcuts( prevTabAction_, defaultShortcuts( QKeySequence( QKeySequence::PreviousChild ), prevTabAction_->shortcut() ) );
actionCollection_->setDefaultShortcuts( nextTabAction_, defaultShortcuts( QKeySequence( QKeySequence::NextChild ), nextTabAction_->shortcut() ) );
actionCollection_->setDefaultShortcut( contactsDockAction, QKeySequence( "Ctrl+D" ) );
actionCollection_->setDefaultShortcut( standardEmoticonsDockAction, QKeySequence( "Ctrl+E" ) );
actionCollection_->setDefaultShortcut( customEmoticonsDockAction, QKeySequence( "Ctrl+Y" ) );
}
@@ -647,9 +660,10 @@ void ChatWindow::editFont()
{
QFont selection( currentAccount_->getFont() );
int result = KFontDialog::getFont( selection, KFontChooser::NoDisplayFlags, this );
bool accepted = false;
selection = QFontDialog::getFont( &accepted, selection, this );
if( result != KFontDialog::Accepted )
if( ! accepted )
{
return;
}
@@ -668,8 +682,8 @@ void ChatWindow::editFontColor()
QColor color( currentAccount_->getFontColor() );
// Show the color dialog
int result = KColorDialog::getColor( color, this );
if ( result == KColorDialog::Accepted )
color = QColorDialog::getColor( color, this );
if ( color.isValid() )
{
// Get the string version of the selected color
const QString fontColor( color.name() );
@@ -746,6 +760,19 @@ bool ChatWindow::eventFilter( QObject *obj, QEvent *event )
return false;
}
if( obj == chatTabs_->tabBar() && event->type() == QEvent::MouseButtonRelease )
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
if( mouseEvent->button() == Qt::MiddleButton )
{
const int tabIndex = chatTabs_->tabBar()->tabAt( mouseEvent->position().toPoint() );
if( tabIndex >= 0 )
{
return slotTabRemoved( chatTabs_->widget( tabIndex ) );
}
}
}
if ( event->type() == QEvent::KeyPress )
{
QKeyEvent *keyEvent = static_cast<QKeyEvent*>( event );
@@ -986,7 +1013,7 @@ bool ChatWindow::eventFilter( QObject *obj, QEvent *event )
#ifdef KMESSDEBUG_CHATWINDOW
kmDebug() << "Setting drawing to the Ink Canvas.";
#endif
QByteArray isfData( url.mid( marker.length() ).toAscii() );
QByteArray isfData( url.mid( marker.length() ).toLatin1() );
Isf::Drawing* drawing = &( Isf::Stream::readerPng( isfData, true ) );
// We need to both set it to the canvas and change the object stored by the chat tab,
@@ -1132,7 +1159,7 @@ bool ChatWindow::handleCommand( QString command )
}
// Parse arguments
QStringList arguments( command.split( " ", QString::SkipEmptyParts ) );
QStringList arguments( command.split( " ", Qt::SkipEmptyParts ) );
if( arguments.isEmpty() )
{
return true;
@@ -1144,7 +1171,7 @@ bool ChatWindow::handleCommand( QString command )
command = command.toLower();
// Get us a kmess handle to call setStatus upon
KMessApplication *kmessApp = static_cast<KMessApplication*>( kapp );
KMessApplication *kmessApp = static_cast<KMessApplication *>(QApplication::instance());
KMess *kmess = kmessApp->getContactListWindow();
bool isStatusCommand = ( command == "status" );
@@ -1152,7 +1179,7 @@ bool ChatWindow::handleCommand( QString command )
// Check syntax errors
if( isStatusCommand && arguments.isEmpty() )
{
KMessageBox::sorry( this,
KMessageBox::error( 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/>"
"You can also use shortcuts like <b>/online</b> or <b>/phone</b>.</html>" ),
@@ -1218,7 +1245,7 @@ bool ChatWindow::handleCommand( QString command )
{
if( participants.count() != 1 )
{
KMessageBox::sorry( this,
KMessageBox::error( this,
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" )
@@ -1231,7 +1258,7 @@ bool ChatWindow::handleCommand( QString command )
{
if( participants.count() != 1 )
{
KMessageBox::sorry( this,
KMessageBox::error( this,
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!" )
@@ -1263,7 +1290,7 @@ bool ChatWindow::handleCommand( QString command )
return false;
}
KMessageBox::sorry( this,
KMessageBox::error( this,
i18n( "<html>Unknown command <b>%1</b>. If you did not want this "
"message to be a command, prepend your message with another"
" /.</html>", command ),
@@ -1296,12 +1323,8 @@ bool ChatWindow::initialize()
}
// Autosave all GUI settings
#if KDE_IS_VERSION(4,0,70)
setAutoSaveSettings( KMessConfig::instance()->getAccountConfig( currentAccount_->getHandle(), "ChatWindow" ),
true /* save WindowSize */ );
#else
setAutoSaveSettings( "ChatWindow", true /* save WindowSize */ );
#endif
// Read the window properties
readProperties();
@@ -1423,6 +1446,15 @@ bool ChatWindow::queryExit()
// Restore the window properties (called by KMainWindow)
void ChatWindow::readProperties()
{
const KConfigGroup config( KMessConfig::instance()->getAccountConfig( currentAccount_->getHandle(), "ChatWindow" ) );
readProperties( config );
}
// Restore the window properties (called by KMainWindow)
void ChatWindow::readProperties(const KConfigGroup &config )
{
@@ -1454,7 +1486,7 @@ void ChatWindow::readProperties(const KConfigGroup &config )
// Swapping the calls around fixes the problem. But again, I'll be damned if I can figure out
// what's going on.
restoreWindowSize( group );
restoreGeometry( group.readEntry( "WindowGeometry", QByteArray() ) );
restoreState( state );
@@ -1488,6 +1520,15 @@ void ChatWindow::saveChat()
// Save the window properties (called by KMainWindow)
void ChatWindow::saveProperties()
{
KConfigGroup config( KMessConfig::instance()->getAccountConfig( currentAccount_->getHandle(), "ChatWindow" ) );
saveProperties( config );
}
// Save the window properties (called by KMainWindow)
void ChatWindow::saveProperties( KConfigGroup &config )
{
@@ -1506,7 +1547,7 @@ void ChatWindow::saveProperties( KConfigGroup &config )
group.writeEntry( "CurrentZoom", zoomLevel_ );
// Save window size
saveWindowSize( group );
group.writeEntry( "WindowGeometry", saveGeometry() );
group.config()->sync();
}
@@ -1629,6 +1670,7 @@ void ChatWindow::sendMessage()
// Don't send empty messages
if( text.trimmed().isEmpty() )
{
doSendTypingMessages_ = true;
return;
}
@@ -1651,6 +1693,8 @@ void ChatWindow::sendMessage()
// Handle command. If 'false' is returned, send it anyway.
if ( handleCommand( command ) )
{
doSendTypingMessages_ = true;
slotMessageChanged();
return;
}
}
@@ -1686,7 +1730,7 @@ void ChatWindow::sendMessage()
// Replace "\n" with "\r\n" (to follow the Windows linebreak style followed by the MSN servers)
// @TODO Move this server stuff to the network/protocol code
text = text.replace( QRegExp("\r?\n"), "\r\n" );
text = text.replace( QRegularExpression( "\r?\n" ), "\r\n" );
// Send the message to the contact(s)
getCurrentChat()->sendChatMessage( text );
@@ -1716,6 +1760,8 @@ void ChatWindow::sendMessage()
quickRetypeList.append( message.getBody() );
lastSentence_ = QString();
slotMessageChanged();
// Reset the last sentence counter.
// showMessage() updates chatMessages_
indexSentences_ = quickRetypeList.size();
@@ -1745,11 +1791,11 @@ void ChatWindow::setChatWindowIcon()
if ( chat->getParticipants().size() == 1 )
{
userIcon = KIcon( "user-identity" ).pixmap( 60, 60 );
userIcon = QIcon::fromTheme( "user-identity" ).pixmap( 60, 60 );
}
else
{
userIcon = KIcon( "system-users" ).pixmap( 60, 60 );
userIcon = QIcon::fromTheme( "system-users" ).pixmap( 60, 60 );
}
setWindowIcon( KMessShared::drawIconOverlay( userIcon, kmessIcon, kmessIcon.size().width(), kmessIcon.size().height(), .60, .90 ) );
@@ -1892,18 +1938,18 @@ void ChatWindow::showMenuBar()
// Ask the user if he/she really wants to hide the menubar, to avoid mistakes
// TODO: If the user disables the shortcut for the menu action, no shortcuts will be shown
int res = KMessageBox::questionYesNo( this,
int res = KMessageBox::questionTwoActions( this,
i18nc( "Question dialog box message",
"<html>Are you sure you want to hide the menu bar? "
"You will be able to show it again by using this "
"keyboard shortcut: <b>%1</b></html>",
showMenuBar_->shortcut().primary().toString( QKeySequence::NativeText ) ),
showMenuBar_->shortcut().toString( QKeySequence::NativeText ) ),
i18nc( "Dialog box caption: hiding the menu bar", "Hiding the Menu" ),
KStandardGuiItem::yes(),
KStandardGuiItem::no(),
KGuiItem( i18n( "Yes" ) ),
KGuiItem( i18n( "No" ) ),
"hideMenuBarQuestion" );
if( res == KMessageBox::Yes )
if( res == KMessageBox::PrimaryAction )
{
menuBar()->setVisible( showMenuBar_->isChecked() );
}
@@ -1969,7 +2015,8 @@ void ChatWindow::showStatusMessage( QString message, int duration )
void ChatWindow::slotChangeInkColor()
{
QColor color;
if ( KColorDialog::getColor( color ) == QDialog::Accepted )
color = QColorDialog::getColor( color, this );
if ( color.isValid() )
{
inkCanvas_->setPenColor( color );
}
@@ -1983,13 +2030,13 @@ void ChatWindow::slotChangeInkBrush()
if( inkCanvas_->penType() == Isf::InkCanvas::DrawingPen )
{
inkCanvas_->setPenType( Isf::InkCanvas::EraserPen );
inkEraseButton_->setIcon( KIcon( "draw-freehand" ) );
inkEraseButton_->setIcon( QIcon::fromTheme( "draw-freehand" ) );
inkEraseButton_->setToolTip( i18n( "Drawing brush" ) );
}
else
{
inkCanvas_->setPenType( Isf::InkCanvas::DrawingPen );
inkEraseButton_->setIcon( KIcon( "draw-eraser" ) );
inkEraseButton_->setIcon( QIcon::fromTheme( "draw-eraser" ) );
inkEraseButton_->setToolTip( i18n( "Erase brush" ) );
}
}
@@ -2044,7 +2091,7 @@ void ChatWindow::slotGotChatMessage( const ChatMessage &message, Chat *chat )
if( chat != getCurrentChat() )
{
// Paint the text red
chatTabs_->setTabTextColor( chatTabs_->indexOf( chat ), QColor( "red" ) );
chatTabs_->tabBar()->setTabTextColor( chatTabs_->indexOf( chat ), QColor( "red" ) );
// Highlight the window title with the chat with new messages
caption_ = chat->getCaption();
@@ -2072,17 +2119,17 @@ void ChatWindow::slotGotNudge()
// avoid shaking again in a short period.
if( lastShake_.secsTo( QTime::currentTime() ) < 15 )
if( lastShake_.isValid() && lastShake_.elapsed() < 15000 )
{
#ifdef KMESSDEBUG_CHATWINDOW
kmDebug() << "Not shaking the window until"
<< lastShake_.secsTo( QTime::currentTime() ) << "more seconds.";
<< ( 15000 - lastShake_.elapsed() ) / 1000 << "more seconds.";
#endif
return;
}
lastShake_ = QTime::currentTime();
lastShake_.restart();
QTime t;
QElapsedTimer t;
int xp = x();
int yp = y();
@@ -2093,7 +2140,7 @@ void ChatWindow::slotGotNudge()
// Shake the window.
for ( int i = 16; i > 0; )
{
kapp->processEvents();
QApplication::processEvents();
if ( t.elapsed() >= 50 )
{
@@ -2142,7 +2189,7 @@ void ChatWindow::slotGotTypingMessage( Chat *chat )
// Update the color of this chat's tab
// If the color is red, leave it
if( chatTabs_->tabTextColor( tabIndex ) != QColor( "red" ) )
if( chatTabs_->tabBar()->tabTextColor( tabIndex ) != QColor( "red" ) )
{
QColor color;
if( typingContacts.isEmpty() )
@@ -2154,7 +2201,7 @@ void ChatWindow::slotGotTypingMessage( Chat *chat )
color = palette.color( QPalette::Highlight );
}
chatTabs_->setTabTextColor( tabIndex, color );
chatTabs_->tabBar()->setTabTextColor( tabIndex, color );
}
// If the typing message was not intended for the currently active tab, skip
@@ -2271,7 +2318,7 @@ void ChatWindow::slotMessageChanged()
}
// If a command is being typed, don't send a typing message
if( messageEdit_->toPlainText().left( 1 ) == "/" and messageEdit_->toPlainText().left( 2 ) != "//" )
if( messageEdit_->toPlainText().left( 1 ) == "/" && messageEdit_->toPlainText().left( 2 ) != "//" )
{
return;
}
@@ -2322,7 +2369,7 @@ void ChatWindow::slotSendButtonClicked()
// Show the chat history for a contact
void ChatWindow::slotShowChatHistory()
{
const KAction* action = qobject_cast< const KAction* >( sender() );
const QAction* action = qobject_cast< const QAction* >( sender() );
if( ! action )
{
@@ -2344,7 +2391,7 @@ void ChatWindow::slotShowChatHistory()
return;
}
action = qobject_cast< const KAction* >( historyMenuAction_->children().first() );
action = qobject_cast< const QAction* >( historyMenuAction_->children().first() );
KMESS_ASSERT( action );
}
@@ -2588,7 +2635,7 @@ void ChatWindow::slotTabChanged( int currentIndex )
// Reset the color
const QPalette palette;
chatTabs_->setTabTextColor( currentIndex, palette.color( QPalette::WindowText ) );
chatTabs_->tabBar()->setTabTextColor( currentIndex, palette.color( QPalette::WindowText ) );
// Display the new chat contents in the UI. Block the signals to avoid the editors
// from firing the "message changed" signal, which sends a typing message.
@@ -2625,7 +2672,7 @@ void ChatWindow::slotTabChanged( int currentIndex )
contact = currentAccount_->addInvitedContact( handle );
}
action = new KAction( KIcon( MsnStatus::getIconName( contact->getStatus() ) ),
action = new QAction( QIcon::fromTheme( MsnStatus::getIconName( contact->getStatus() ) ),
contact->getFriendlyName( STRING_CLEANED ),
historyMenuAction_ );
action->setData( handle );
@@ -2771,7 +2818,7 @@ void ChatWindow::slotUpdateChatInfo( Chat *chat )
"<dt><b>Connected with account:</b></dt><dd>%3</dd>"
"</dl></html>",
participants.join( "</li><li>" ),
chat->getStartTime().toString( Qt::DefaultLocaleLongDate ),
QLocale().toString( chat->getStartTime(), QLocale::LongFormat ),
currentAccount_->getHandle() ) );
chatTabs_->setTabToolTip( index, toolTip );
@@ -2983,7 +3030,3 @@ void ChatWindow::viewZoomOut()
{
changeZoomFactor( false );
}
#include "chatwindow.moc"
+22 -20
View File
@@ -22,9 +22,10 @@
#include "chatstatusbar.h"
#include <QList>
#include <QElapsedTimer>
#include <QTimer>
#include <KAction>
#include <QAction>
#include <KActionCollection>
#include <KToggleAction>
#include <KXmlGuiWindow>
@@ -39,12 +40,11 @@ class EmoticonsWidget;
class MsnSwitchboardConnection;
class QLabel;
class QAction;
class KActionMenu;
class KConfigGroup;
class KHelpMenu;
class KMenu;
class KTabBar;
class KToolBarButton;
class KToolBarPopupAction;
@@ -85,7 +85,7 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
// Initialize the object
bool initialize();
// The chat window is closing, called by KMainWindow
bool queryClose();
bool queryClose() override;
// The application is exiting, called by KMainWindow
bool queryExit();
// Close a chat tab without user intervention
@@ -103,15 +103,17 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
// Set the zoom factor of the text
void changeZoomFactor( bool increase );
// Filter to catch window activation and keyboard shortcut events
bool eventFilter( QObject *obj, QEvent *event );
bool eventFilter( QObject *obj, QEvent *event ) override;
// Set up the preferences which depend on the current account
bool initializeCurrentAccount();
// Create the menus.
void createMenus();
// Restore the window properties (called by KMainWindow)
void readProperties( const KConfigGroup &config = *((const KConfigGroup *)0) );
void readProperties();
void readProperties( const KConfigGroup &config ) override;
// Save the window properties (called by KMainWindow)
void saveProperties( KConfigGroup &config = *((KConfigGroup *)0) );
void saveProperties();
void saveProperties( KConfigGroup &config ) override;
// Enable or disable the parts of the window which allow user interaction
void setEnabled( bool isEnabled );
// Set the window icon for this chat window
@@ -219,7 +221,7 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
// ActionCollection
KActionCollection *actionCollection_;
// The add emoticon action
KAction *addEmoticonAction_;
QAction *addEmoticonAction_;
// A timer used to make the caption blink on new messages.
QTimer blinkTimer_;
// Whether to blink to upper (true) or lower (false) case
@@ -227,11 +229,11 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
// The stored window caption
QString caption_;
// Action to change own text font
KAction *changeFontAction_;
QAction *changeFontAction_;
// Action to change own text color
KAction *changeFontColorAction_;
QAction *changeFontColorAction_;
// Action to close the window along with all of its tabs
KAction *closeAllAction_;
QAction *closeAllAction_;
// Contacts list Dock Widget
QDockWidget *contactsDock_;
// A pointer to the instance of the current account
@@ -239,11 +241,11 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
// Custom emoticons Dock Widget
QDockWidget *customEmoticonsDock_;
// Action to cut text to the clipboard
KAction *cutAction_;
QAction *cutAction_;
// Whether or not typing messages should be sent (true except the very moment a text message is sent)
bool doSendTypingMessages_;
// The emoticon display toggling action
KAction *emoticonAction_;
QAction *emoticonAction_;
// The first item in the Chat Menu (used to add the Invite menu before it)
QAction *firstChatMenuItem_;
// The menu containing contacts chat history actions
@@ -253,23 +255,23 @@ class ChatWindow : public KXmlGuiWindow, private Ui::ChatWindow
// Whether or not the object was initialized
bool initialized_;
// The contact invite action
KAction *inviteButton_;
QAction *inviteButton_;
// Last sentence in writing
QString lastSentence_;
// The last time the window was shaked
QTime lastShake_;
QElapsedTimer lastShake_;
// Action to switch to the next tab
KAction *nextTabAction_;
QAction *nextTabAction_;
// Action to send a nudge
KAction *nudgeAction_;
QAction *nudgeAction_;
// Action menu containing the panels shortcuts
KActionMenu *panelsMenuAction_;
// Action to paste the clipboard contents
KAction *pasteAction_;
QAction *pasteAction_;
// Action to switch to the previous tab
KAction *prevTabAction_;
QAction *prevTabAction_;
// Action to start a file transfer
KAction *sendAction_;
QAction *sendAction_;
// Toggle actions for showing and hiding the menu bar
KToggleAction *showMenuBar_;
// Toggle action to show/hide the join and part messages
+2 -15
View File
@@ -28,7 +28,7 @@
<property name="childrenCollapsible">
<bool>false</bool>
</property>
<widget class="KTabWidget" name="chatTabs_">
<widget class="QTabWidget" name="chatTabs_">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@@ -53,12 +53,6 @@
<property name="movable">
<bool>true</bool>
</property>
<property name="tabReorderingEnabled">
<bool>true</bool>
</property>
<property name="automaticResizeTabs">
<bool>true</bool>
</property>
</widget>
<widget class="QWidget" name="widgetBox_" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
@@ -501,18 +495,11 @@
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
<customwidgets>
<customwidget>
<class>KTabWidget</class>
<extends>QTabWidget</extends>
<header>ktabwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>KTextEdit</class>
<extends>QTextEdit</extends>
<header>ktextedit.h</header>
<header>KTextEdit</header>
</customwidget>
<customwidget>
<class>Isf::InkCanvas</class>
+43 -42
View File
@@ -37,14 +37,18 @@
#include <QClipboard>
#include <QFileInfo>
#include <QMimeData>
#include <QMouseEvent>
#include <KApplication>
#include <QApplication>
#include <QAction>
#include <KActionMenu>
#include <QIcon>
#include <KIconEffect>
#include <KIconLoader>
#include <KMenu>
#include <KStandardDirs>
#include <KLocalizedString>
#include <QMenu>
#include <QUrl>
// Time in milliseconds before the glowing done for a typing user fades away
@@ -61,7 +65,7 @@ ContactFrame::ContactFrame( QWidget *parent )
, contactPixmapLabelEnabled_(true)
, contactPropertiesDialog_(0)
, detailedContact_(0)
, handle_(QString::null)
, handle_(QString())
, currentMode_(ModeNormal)
, infoLabelEnabled_(true)
, locked_(true)
@@ -71,7 +75,7 @@ ContactFrame::ContactFrame( QWidget *parent )
layout()->setAlignment( Qt::AlignTop | Qt::AlignLeft );
// Just for show
const QPixmap pixmap( KGlobal::dirs()->findResource( "data", "kmess/pics/unknown.png" ) );
const QPixmap pixmap( KMessShared::findResource( "data", "kmess/pics/unknown.png" ) );
contactPixmapLabel_->setPixmap( pixmap );
installEventFilter( this );
@@ -218,29 +222,29 @@ void ContactFrame::contactDestroyed( QObject *object )
void ContactFrame::copyText()
{
// Get the signal sender to find out who called us
KAction *action = static_cast<KAction*>( const_cast<QObject*>( sender() ) );
QAction *action = static_cast<QAction*>( const_cast<QObject*>( sender() ) );
if(KMESS_NULL(action)) return;
if( action == popupCopyFriendlyName_ )
{
kapp->clipboard()->setText( contact_->getFriendlyName( STRING_CLEANED ) );
QApplication::clipboard()->setText( contact_->getFriendlyName( STRING_CLEANED ) );
}
else if( action == popupCopyHandle_ )
{
kapp->clipboard()->setText( handle_ );
QApplication::clipboard()->setText( handle_ );
}
else if( action == popupCopyPersonalMessage_ && detailedContact_ != 0 )
{
kapp->clipboard()->setText( detailedContact_->getPersonalMessage( STRING_CLEANED ) );
QApplication::clipboard()->setText( detailedContact_->getPersonalMessage( STRING_CLEANED ) );
}
else if( action == popupCopyMusic_ && detailedContact_ != 0 )
{
kapp->clipboard()->setText( detailedContact_->getCurrentMediaString() );
QApplication::clipboard()->setText( detailedContact_->getCurrentMediaString() );
}
else if( detailedContact_ != 0 )
{
// Copy the link from PM or Friendly Name
kapp->clipboard()->setText( action->toolTip() );
QApplication::clipboard()->setText( action->toolTip() );
}
}
@@ -328,7 +332,7 @@ bool ContactFrame::eventFilter( QObject *obj, QEvent *event )
const QMouseEvent *mouseEvent = static_cast<QMouseEvent*>( event );
// Show the menu regardlessly of where the mouse button has been pressed
showContactPopup( mouseEvent->globalPos() );
showContactPopup( mouseEvent->globalPosition().toPoint() );
return false; // don't stop processing.
}
@@ -353,28 +357,28 @@ bool ContactFrame::initContactPopup()
}
// Initialize context popup actions
popupStartPrivateChat_ = new KAction( KIcon("user-group-new"), i18n("&Start Private Chat"), this );
popupEmailContact_ = new KAction( KIcon("mail-message-new"), i18n("&Send Email"), this );
popupShowHistory_ = new KAction( KIcon("chronometer"), i18n("Chat &History"), this );
popupMsnProfile_ = new KAction( KIcon("preferences-desktop-user"), i18n("&View Profile"), this );
popupContactProperties_ = new KAction( KIcon("user-properties"), i18n("&Properties"), this );
popupStartPrivateChat_ = new QAction( QIcon::fromTheme( "user-group-new" ), i18n("&Start Private Chat"), this );
popupEmailContact_ = new QAction( QIcon::fromTheme( "mail-message-new" ), i18n("&Send Email"), this );
popupShowHistory_ = new QAction( QIcon::fromTheme( "chronometer" ), i18n("Chat &History"), this );
popupMsnProfile_ = new QAction( QIcon::fromTheme( "preferences-desktop-user" ), i18n("&View Profile"), this );
popupContactProperties_ = new QAction( QIcon::fromTheme( "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 );
popupRemoveContact_ = new KAction( KIcon("list-remove-user"), i18n("&Delete Contact"), this );
popupAddContact_ = new QAction( QIcon::fromTheme( "list-add" ), i18n("&Add Contact"), this );
popupAllowContact_ = new QAction( QIcon::fromTheme( "dialog-ok-apply" ), i18n("A&llow Contact"), this );
popupRemoveContact_ = new QAction( QIcon::fromTheme( "list-remove-user" ), i18n("&Delete Contact"), this );
popupBlockContact_ = new KAction( KIcon("dialog-cancel"), i18n("&Block Contact"), this );
popupUnblockContact_ = new KAction( KIcon("dialog-ok"), i18n("&Unblock Contact"), this );
popupBlockContact_ = new QAction( QIcon::fromTheme( "dialog-cancel" ), i18n("&Block Contact"), this );
popupUnblockContact_ = new QAction( QIcon::fromTheme( "dialog-ok" ), i18n("&Unblock Contact"), this );
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 );
popupCopyFriendlyName_ = new QAction( i18n("&Friendly Name"), this );
popupCopyPersonalMessage_ = new QAction( i18n("&Personal Message"), this );
popupCopyHandle_ = new QAction( i18n("&Email Address"), this );
popupCopyMusic_ = new QAction( 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 );
popupPropGeneral_ = new QAction( QIcon::fromTheme( "user-properties" ), i18n("&Information"), this );
popupPropImages_ = new QAction( QIcon::fromTheme( "draw-brush" ), i18n("Display Pictures"), this );
popupPropNotes_ = new QAction( QIcon::fromTheme( "document-edit" ), i18n("&Notes"), this );
popupPropEmoticons_ = new QAction( QIcon::fromTheme( "face-smile" ), i18n("&Emoticons"), this );
// Connect the actions
@@ -416,11 +420,12 @@ bool ContactFrame::initContactPopup()
popupPropMenu_ ->addAction( popupPropEmoticons_ );
// Initialize the popup popup
contactActionPopup_ = new KMenu( handle_, this );
contactActionPopup_ = new QMenu( handle_, this );
// Attach the actions to the menu
// Order is as consistent as possible with the menu in KMessView
contactActionPopup_->addTitle( contact_->getHandle() );
QAction *titleAction = contactActionPopup_->addAction( contact_->getHandle() );
titleAction->setEnabled( false );
contactActionPopup_->addAction( popupStartPrivateChat_ );
contactActionPopup_->addAction( popupEmailContact_ );
contactActionPopup_->addAction( popupShowHistory_ );
@@ -579,13 +584,13 @@ void ContactFrame::showContactPopup( const QPoint &point )
}
links.append( foundLink );
// Put the found link into KAction, replace & with && to avoid shortcut problem and use tooltip
// Put the found link into QAction, replace & with && to avoid shortcut problem and use tooltip
// for future grep of link ( to avoid shortcut problem too )
popupCopyLink_ = new KAction( foundLink.replace( "&", "&&" ), this );
popupCopyLink_ = new QAction( foundLink.replace( "&", "&&" ), this );
popupCopyLink_->setToolTip( foundLink );
connect( popupCopyLink_, SIGNAL( triggered( bool ) ), this, SLOT( copyText() ) );
// Append current KAction to the copy link list
// Append current QAction to the copy link list
copyLinkActionsList_.append( popupCopyLink_ );
// Add action to copy menu
@@ -642,7 +647,7 @@ void ContactFrame::showContactProperties()
// 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();
KMess *kmess = static_cast<KMessApplication *>(QApplication::instance())->getContactListWindow();
// HACK: MUST GO AFTER 2.0-final!!
connect( dialog, SIGNAL(addContactToGroup(QString, QString)),
@@ -668,7 +673,7 @@ void ContactFrame::showProfile()
}
// Create a URL to the msn profile page, localized with our system's locale.
const KUrl url( "http://members.msn.com/default.msnw?mem=" + handle_ + "&mkt=" + KGlobal::locale()->language() );
const QUrl url( "https://nina.chat/contacts/" );
// Launch the browser for the given URL
KMessShared::openBrowser( url );
@@ -847,7 +852,7 @@ void ContactFrame::updateStatusWidgets()
}
infoLabel_->setVisible( true );
infoLabel_->setText( mediaEmoticon + Qt::escape( mediaString ) );
infoLabel_->setText( mediaEmoticon + mediaString.toHtmlEscaped() );
infoLabel_->setToolTip( mediaString );
}
else if( ! messageString.isEmpty() )
@@ -868,7 +873,3 @@ void ContactFrame::updateStatusWidgets()
contactPixmapLabel_->setVisible( contactPixmapLabelEnabled_ );
}
#include "contactframe.moc"
+38 -38
View File
@@ -29,9 +29,9 @@ class Contact;
class ContactBase;
class ContactPropertiesDialog;
class CurrentAccount;
class KAction;
class QAction;
class KActionMenu;
class KMenu;
class QMenu;
@@ -80,7 +80,7 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
private: // Private methods
// The personal status message received an event.
bool eventFilter( QObject *obj, QEvent *event );
bool eventFilter( QObject *obj, QEvent *event ) override;
private slots: // Private slots
// Allow this contact to see our MSN status
@@ -118,7 +118,7 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
// The contact whom the frame represents
ContactBase *contact_;
// The menu of actions possible to perform on a given contact
KMenu *contactActionPopup_;
QMenu *contactActionPopup_;
// The contact's image
QPixmap contactPicture_;
// The contact picture date
@@ -132,7 +132,7 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
// The contact's image visible while the contact is typing
QPixmap contactTypingPicture_;
// List of actions with links to copy to the clipboard
QList<KAction*> copyLinkActionsList_;
QList<QAction*> copyLinkActionsList_;
// The detailed contact information, if available
Contact *detailedContact_;
// The contact's handle, saved for performance and for safety
@@ -143,44 +143,44 @@ class ContactFrame : public QWidget, private Ui::ContactFrame
bool infoLabelEnabled_;
// Whether or not is it possible to add or block the contact
bool locked_;
// Contact popup KAction to add the contact to the contact list
KAction *popupAddContact_;
// Contact popup KAction to allow the contact to see the user's status
KAction *popupAllowContact_;
// Contact popup KAction to block the contact
KAction *popupBlockContact_;
// Contact popup QAction to add the contact to the contact list
QAction *popupAddContact_;
// Contact popup QAction to allow the contact to see the user's status
QAction *popupAllowContact_;
// Contact popup QAction to block the contact
QAction *popupBlockContact_;
// Contact popup menu to show the contact's properties window
KAction *popupContactProperties_;
QAction *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_;
// Contact popup KAction to copy the contact's message to clipboard
KAction *popupCopyPersonalMessage_;
// Contact popup KAction to copy the contact's email address to clipboard
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 send an email to the contact
KAction *popupEmailContact_;
// Contact popup KAction to show the contact's profile
KAction *popupMsnProfile_;
// Contact popup KAction to remove a contact from the contact list
KAction *popupRemoveContact_;
// Contact popup KAction to show a contact's chat history (if any)
KAction *popupShowHistory_;
// Contact popup KAction to start a private chat with the contact while the user is in a multi-chat
KAction *popupStartPrivateChat_;
// Contact popup KAction to unblock the contact
KAction *popupUnblockContact_;
// Contact popup QAction to copy the contact's friendly name to clipboard
QAction *popupCopyFriendlyName_;
// Contact popup QAction to copy the contact's message to clipboard
QAction *popupCopyPersonalMessage_;
// Contact popup QAction to copy the contact's email address to clipboard
QAction *popupCopyHandle_;
// Contact popup QAction to copy links from pm and friendly name
QAction *popupCopyLink_;
// Contact popup QAction to copy contact's media message
QAction *popupCopyMusic_;
// Contact popup QAction to send an email to the contact
QAction *popupEmailContact_;
// Contact popup QAction to show the contact's profile
QAction *popupMsnProfile_;
// Contact popup QAction to remove a contact from the contact list
QAction *popupRemoveContact_;
// Contact popup QAction to show a contact's chat history (if any)
QAction *popupShowHistory_;
// Contact popup QAction to start a private chat with the contact while the user is in a multi-chat
QAction *popupStartPrivateChat_;
// Contact popup QAction to unblock the contact
QAction *popupUnblockContact_;
// popup actions for the properties menu
KActionMenu *popupPropMenu_;
KAction *popupPropGeneral_;
KAction *popupPropImages_;
KAction *popupPropNotes_;
KAction *popupPropEmoticons_;
QAction *popupPropGeneral_;
QAction *popupPropImages_;
QAction *popupPropNotes_;
QAction *popupPropEmoticons_;
// A timer to time the duration that the typing label is shown
QTimer typingTimer_;
-1
View File
@@ -209,7 +209,6 @@
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
<customwidgets>
<customwidget>
<class>GradientElideLabel</class>
+15 -30
View File
@@ -26,12 +26,15 @@
#include "../utils/kmessconfig.h"
#include <QDockWidget>
#include <QMouseEvent>
#include <QDir>
#include <QMimeData>
#include <QMouseEvent>
#include <QRegularExpression>
#include <KIconEffect>
#include <KIO/NetAccess>
#include <KLocalizedString>
#include <KMessageBox>
#include <QUrl>
// The constructor
ContactsWidget::ContactsWidget( QWidget *parent )
@@ -273,9 +276,9 @@ bool ContactsWidget::eventFilter( QObject *obj, QEvent *event )
return true;
}
KUrl mimeUrl = mimeData->urls().first();
bool isRemoteFile = false;
QUrl mimeUrl = mimeData->urls().first();
QString localFilePath;
QString temporaryFilePath;
QImage pictureData;
if( mimeUrl.isEmpty() )
@@ -284,34 +287,20 @@ bool ContactsWidget::eventFilter( QObject *obj, QEvent *event )
return true;
}
if( mimeUrl.isLocalFile() )
if( ! KMessShared::downloadToLocalFile( mimeUrl, localFilePath, &temporaryFilePath ) )
{
localFilePath = mimeUrl.path();
}
else
{
// File is remote, download it to a local folder
// first because QPixmap doesn't have KIO magic.
// KIO::NetAccess::download fills the localFilePath field.
if( ! KIO::NetAccess::download(mimeUrl, localFilePath, this ) )
{
KMessageBox::sorry( this, i18n( "Downloading of display picture failed" ), i18n("KMess") );
return true;
}
isRemoteFile = true;
KMessageBox::error( this, i18n( "Downloading of display picture failed" ), i18n("KMess") );
return true;
}
if( ! pictureData.load( localFilePath ) )
{
KMessShared::removeDownloadedTempFile( temporaryFilePath );
kmWarning() << "The file dropped is not an image or doesn't exist";
return true;
}
if( isRemoteFile )
{
KIO::NetAccess::removeTempFile( localFilePath );
}
KMessShared::removeDownloadedTempFile( temporaryFilePath );
pictureData = pictureData.scaled( 96, 96, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation ); // Makes smallest edge 96 pixels, preserving aspect ratio
@@ -328,14 +317,14 @@ bool ContactsWidget::eventFilter( QObject *obj, QEvent *event )
if( ! pictureData.save( tempPictureFile, "PNG" ) )
{
KMessageBox::sorry( this,
KMessageBox::error( this,
i18n( "An error occurred while trying to change the display picture.\n"
"Make sure that you have selected an existing image file." ),
i18n( "KMess" ) );
}
QString msnObjectHash( KMessShared::generateFileHash( tempPictureFile ).toBase64() );
const QString safeMsnObjectHash( msnObjectHash.replace( QRegExp("[^a-zA-Z0-9+=]"), "_" ) );
const QString safeMsnObjectHash( msnObjectHash.replace( QRegularExpression("[^a-zA-Z0-9+=]"), "_" ) );
// Save the new display picture with its hash as name, to ensure correct caching
QString pictureName = msnObjectHash + ".png";
@@ -432,7 +421,7 @@ ContactFrame* ContactsWidget::createContactFrame()
this, SIGNAL( contactBlocked( QString, bool ) ) );
// Add it to the viewBox so it appears in the widget
layout_->insertWidget( children().count() - 2, contactFrame );
layout_->insertWidget( layout_->count(), contactFrame );
// put it in the list of frames so we can find it again.
contactFrames_.append( contactFrame );
@@ -613,7 +602,3 @@ void ContactsWidget::slotUpdateDisplayPicture()
userPixmapLabel_->setPixmap( image );
userPixmapLabel_->setProperty( "PictureFileName", pictureFileName );
}
#include "contactswidget.moc"
+1 -1
View File
@@ -91,7 +91,7 @@ class ContactsWidget : public QWidget, private Ui::ContactsWidget
// Return one new contact frame
ContactFrame* createContactFrame();
// The user picture frame received an event
bool eventFilter( QObject *obj, QEvent *event );
bool eventFilter( QObject *obj, QEvent *event ) override;
// 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
+8 -8
View File
@@ -32,6 +32,9 @@
#include <QMouseEvent>
#include <QPoint>
#include <QIcon>
#include <KLocalizedString>
// The constructor
@@ -183,7 +186,7 @@ bool EmoticonListWidget::eventFilter( QObject */*obj*/, QEvent *e )
if( e->type() == QEvent::HoverMove )
{
// The cursor mouse is moving over the widget
QListWidgetItem *item = itemAt( static_cast<QHoverEvent*>(e)->pos() );
QListWidgetItem *item = itemAt( static_cast<QHoverEvent*>(e)->position().toPoint() );
// Check if the mouse is over the same emoticon or the selection is changed
if( item == previousItem_ )
@@ -436,10 +439,10 @@ void EmoticonsWidget::showContextMenu( const QListWidgetItem *item, const QPoint
// Create the popup menu for custom emoticon
QMenu menu;
QAction addAction( KIcon( "insert-image" ), i18n( "Add to Chat" ), this );
QAction insertAction( KIcon( "list-add" ), i18n( "Add New" ), this );
QAction editAction( KIcon( "draw-freehand" ), i18n( "Edit" ), this );
QAction removeAction( KIcon( "list-remove" ), i18n( "Remove" ), this );
QAction addAction( QIcon::fromTheme( "insert-image" ), i18n( "Add to Chat" ), this );
QAction insertAction( QIcon::fromTheme( "list-add" ), i18n( "Add New" ), this );
QAction editAction( QIcon::fromTheme( "draw-freehand" ), i18n( "Edit" ), this );
QAction removeAction( QIcon::fromTheme( "list-remove" ), i18n( "Remove" ), this );
menu.addAction( &addAction );
menu.addAction( &insertAction );
@@ -483,6 +486,3 @@ void EmoticonsWidget::showContextMenu( const QListWidgetItem *item, const QPoint
emoticonDialog_->show();
}
#include "emoticonswidget.moc"
+3 -3
View File
@@ -57,7 +57,7 @@ class EmoticonsWidget : public QWidget
protected:
// Event filter for the preview label
bool eventFilter( QObject *obj, QEvent *e );
bool eventFilter( QObject *obj, QEvent *e ) override;
private slots:
// One item was clicked
@@ -121,9 +121,9 @@ class EmoticonListWidget : public QListWidget
protected:
// Reimplement the mouse press event to grep left and right click
void mousePressEvent( QMouseEvent *e );
void mousePressEvent( QMouseEvent *e ) override;
// Reimplement the event filter
bool eventFilter( QObject *obj, QEvent *e );
bool eventFilter( QObject *obj, QEvent *e ) override;
private:
QListWidgetItem *previousItem_;
+12 -14
View File
@@ -19,6 +19,7 @@
#include "../contact/msnobject.h"
#include "../utils/kmessconfig.h"
#include "../utils/kmessshared.h"
#include "../currentaccount.h"
#include "../kmessdebug.h"
@@ -26,12 +27,12 @@
#include <QDomDocument>
#include <QLabel>
#include <QListWidgetItem>
#include <QRegularExpression>
#include <QTextDocument>
#include <KIcon>
#include <QIcon>
#include <KLocalizedString>
#include <KProcess>
#include <KStandardDirs>
WinksWidget::WinksWidget( QWidget *parent )
@@ -78,7 +79,7 @@ void WinksWidget::refresh()
const QDir directory( winksDir_, "*.cab" );
QDir winkDirectory ( winksDir_, "*.png" );
QFileInfo fileInfo;
KIcon icon;
QIcon icon;
QString iconPath;
const QStringList cabFiles( directory.entryList( QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks ) );
@@ -152,7 +153,7 @@ void WinksWidget::refresh()
}
// Add the item
QListWidgetItem *item = new QListWidgetItem( KIcon( iconPath ), "", list_ );
QListWidgetItem *item = new QListWidgetItem( QIcon( iconPath ), "", list_ );
item->setData( Qt::UserRole, file );
item->setToolTip( winkFriendly );
}
@@ -173,7 +174,7 @@ WinksWidget::CABEXTRACTOR WinksWidget::getHtmlFromWink( const QString &filename,
if( ! metaFile.exists() )
{
// Check if cabextract is installed
if( KStandardDirs::findExe( "cabextract" ).isEmpty() )
if( KMessShared::findExecutable( "cabextract" ).isEmpty() )
{
return NOTINSTALLED;
}
@@ -211,11 +212,12 @@ WinksWidget::CABEXTRACTOR WinksWidget::getHtmlFromWink( const QString &filename,
}
// Parse the XML
QString xmlErrorMessage;
QDomDocument xml;
if( ! xml.setContent( &metaFile, true, &xmlErrorMessage ) )
const QDomDocument::ParseResult parseResult =
xml.setContent( &metaFile, QDomDocument::ParseOption::UseNamespaceProcessing );
if( ! parseResult )
{
kmWarning() << "parsing of wink XML failed: " << xmlErrorMessage << "!";
kmWarning() << "parsing of wink XML failed: " << parseResult.errorMessage << "!";
return UNKNOW;
}
@@ -274,8 +276,8 @@ WinksWidget::CABEXTRACTOR WinksWidget::getHtmlFromWink( const QString &filename,
}
// Escape data for inclusion in HTML.
animation = Qt::escape(animation).replace("\"", "&quot;"); // quotes are not escaped by QStyleSheet::escape().
animationType = animationType.remove( QRegExp("[^a-zA-Z0-9\\-/]") );
animation = animation.toHtmlEscaped().replace("\"", "&quot;" );
animationType = animationType.remove( QRegularExpression( "[^a-zA-Z0-9\\-/]" ) );
const QString filePath( winksDir + "/" + animation );
@@ -347,7 +349,3 @@ const MsnObject WinksWidget::getMsnObjectWinkSelected()
// Finally, return the msn object
return MsnObject( handle, fileInfo.baseName(), winkFriendly, MsnObject::WINK, data, stamp );
}
#include "winkswidget.moc"
+27 -23
View File
@@ -23,17 +23,17 @@
#include <stdlib.h>
#include <string.h>
#include <libxml/globals.h>
#include <libxml/parser.h>
#include <libxslt/xsltconfig.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h> // After xsltconfig and xsltInternals or it breaks compiling on some libxslt versions.
#include <QFile>
#include <QRegExp>
#include <QFileInfo>
#include <QRegularExpression>
#include <KLocale>
#include <KUrl>
#include <KLocalizedString>
#include <QUrl>
/*
@@ -51,8 +51,7 @@ XslTransformation::XslTransformation()
, xslParamCount_(0)
{
// Init libxml
xmlLoadExtDtdDefaultValue = 0;
xmlSubstituteEntitiesDefault( 1 );
xmlInitParser();
}
@@ -83,7 +82,7 @@ XslTransformation::~XslTransformation()
QString XslTransformation::convertXmlString( const QString &xml ) const
{
// Asserts
if( KMESS_NULL(styleSheet_) ) return QString::null;
if( KMESS_NULL(styleSheet_) ) return QString();
// Intermediate variables
QString result;
@@ -98,11 +97,15 @@ QString XslTransformation::convertXmlString( const QString &xml ) const
QByteArray xmlCString = xml.toUtf8();
// Create XmlDoc
sourceXmlDoc = xmlParseMemory( xmlCString.data(), xmlCString.length() );
sourceXmlDoc = xmlReadMemory( xmlCString.constData(),
static_cast<int>( xmlCString.size() ),
0,
0,
XML_PARSE_NOENT | XML_PARSE_NONET );
if( sourceXmlDoc == 0 )
{
kmWarning() << "could not parse the XML data.";
return QString::null;
return QString();
}
// Apply XSL
@@ -119,8 +122,8 @@ QString XslTransformation::convertXmlString( const QString &xml ) const
// Load result in a QString, strip xml header and last \n from result string
result = QString::fromUtf8( reinterpret_cast<char*>( xmlData ), xmlDataSize );
result = result.replace( QRegExp("^<\\?xml [^?]+\\?>\n?"), QString::null )
.replace( QRegExp("\r?\n?$"), QString::null );
result = result.replace( QRegularExpression( "^<\\?xml [^?]+\\?>\n?" ), QString() )
.replace( QRegularExpression( "\r?\n?$" ), QString() );
// Reverse calls to free intermediate results too.
// You gotta love C-API's.. ;-)
@@ -137,7 +140,7 @@ cleanSource:
// when the parsing of user parameters failed.
if( result.isEmpty() )
{
return QString::null;
return QString();
}
else
{
@@ -193,10 +196,6 @@ void XslTransformation::setStylesheet(const QString &xslFileName)
xslDoc_ = 0;
}
// Get file path
KUrl fileUrl(xslFileName);
// QByteArray basePath = fileUrl.directory( KUrl::AppendTrailingSlash ).toUtf8();
// Open XSL file
QFile file(xslFileName);
if( ! file.open(QIODevice::ReadOnly) )
@@ -210,7 +209,12 @@ void XslTransformation::setStylesheet(const QString &xslFileName)
file.close();
// Parse file data as XML
xslDoc_ = xmlParseMemory( fileData.data(), fileData.size() );
const QByteArray baseUrl = QUrl::fromLocalFile( QFileInfo( xslFileName ).absoluteFilePath() ).toEncoded();
xslDoc_ = xmlReadMemory( fileData.constData(),
static_cast<int>( fileData.size() ),
baseUrl.constData(),
0,
XML_PARSE_NOENT | XML_PARSE_NONET );
if(xslDoc_ == 0)
{
kmWarning() << "could not parse XML from '" << xslFileName << "'!";
@@ -250,7 +254,7 @@ void XslTransformation::setStylesheet(const QString &xslFileName)
{
kmWarning() << "'xsl' and 'kmess' namespaces not found in '"
<< xslFileName << "' chat style, "
<< "chat style can't be translated." << endl;
<< "chat style can't be translated." << Qt::endl;
}
else
{
@@ -284,7 +288,7 @@ void XslTransformation::updateParametersList()
// Delete the previous parameter list
for( int i = 0; i < xslParamCount_; i++ )
{
delete xslParams_[i];
free( xslParams_[i] );
}
delete[] xslParams_;
@@ -327,7 +331,7 @@ void XslTransformation::updateXslTranslations( xmlNode *node, const xmlNs *xslNs
// <xsl:text kmess:translate="true">fdsfsd</xsl:text>
// the contents is trimmed to avoid translations are broken too easily.
QRegExp trimmer("^([ \t\r\n\f\v]+)(.+)([ \t\r\n\f\v]+)$");
const QRegularExpression trimmer( "^([ \t\r\n\f\v]+)(.+)([ \t\r\n\f\v]+)$" );
// Browse all child nodes
for( xmlNode *curNode = node; curNode != 0; curNode = curNode->next )
@@ -369,7 +373,8 @@ void XslTransformation::updateXslTranslations( xmlNode *node, const xmlNs *xslNs
// Trim and simplyfy spaces to avoid breaking translations too easily.
// Ignore <xsl:text> </xsl:text> nodes.
bool timmed = trimmer.indexIn( content ) != -1;
const QRegularExpressionMatch trimMatch = trimmer.match( content );
bool timmed = trimMatch.hasMatch();
content = content.simplified();
if( content.isEmpty() )
{
@@ -381,7 +386,7 @@ void XslTransformation::updateXslTranslations( xmlNode *node, const xmlNs *xslNs
content = i18nc( "chat-style-text", content.toLatin1() );
if( timmed )
{
content = trimmer.cap(1) + content + trimmer.cap(3);
content = trimMatch.captured( 1 ) + content + trimMatch.captured( 3 );
}
#ifdef KMESSDEBUG_XSLTRANSFORMATION
@@ -400,4 +405,3 @@ void XslTransformation::updateXslTranslations( xmlNode *node, const xmlNs *xslNs
updateXslTranslations( curNode->children, xslNs, kmessNs );
}
}
-2
View File
@@ -606,5 +606,3 @@ void Contact::setStatus( const Status newStatus, bool showBaloon )
emit contactOnline( this, showBaloon );
}
}
#include "contact.moc"
+4 -4
View File
@@ -87,7 +87,7 @@ class Contact : public ContactBase
// Return the contact's display picture, scaled to the right size for the contact list.
QPixmap & getScaledDisplayPicture();
// Return the path to the contact's picture
const QString getContactPicturePath() const;
const QString getContactPicturePath() const override;
// Return the current media type
const QString & getCurrentMediaType() const;
// Return the current media type
@@ -95,7 +95,7 @@ class Contact : public ContactBase
// Return a pointer to the extension class
ContactExtension *getExtension() const;
// Return the contact's friendly name
const QString& getFriendlyName( FormattingMode mode = STRING_CLEANED ) const;
const QString& getFriendlyName( FormattingMode mode = STRING_CLEANED ) const override;
// Return the group ID's the contact is added to
const QStringList& getGroupIds() const;
// Return the contact's globally unique identifier
@@ -107,7 +107,7 @@ class Contact : public ContactBase
// Return the contact's personal message
const QString & getPersonalMessage( FormattingMode mode = STRING_CLEANED ) const;
// Return the contact's status
Status getStatus() const;
Status getStatus() const override;
// Return the contact's true friendly name, regardless of extension
const QString& getTrueFriendlyName( FormattingMode mode = STRING_CLEANED ) const;
// Return an MSN Object
@@ -149,7 +149,7 @@ class Contact : public ContactBase
// Set wether or not the contact is on pending list
void setPending( bool isPending );
// Set the contacts Personal message
void setPersonalStatus(const QString &message, const QString &mediaType = QString::null, const QString &mediaString = QString::null);
void setPersonalStatus(const QString &message, const QString &mediaType = QString(), const QString &mediaString = QString());
// Set whether or not the contact is on the reverse list
void setReverse(bool reverse);
// Set the contact's status
+3 -9
View File
@@ -25,8 +25,7 @@
#include <QFile>
#include <QImage>
#include <KLocale>
#include <KStandardDirs>
#include <KLocalizedString>
@@ -258,7 +257,7 @@ void ContactBase::detectClientName( uint capabilities, const MsnObject *msnObjec
{
pictureClientName = "Mercury";
}
else if( pictureLocation == "kopete.tmp" or pictureLocation == "1.tmp" )
else if( pictureLocation == "kopete.tmp" || pictureLocation == "1.tmp" )
{
pictureClientName = "Kopete";
}
@@ -442,8 +441,7 @@ const QString & ContactBase::getClientFullName() const
// Return the default contact picture path
QString ContactBase::getContactDefaultPicturePath() const
{
KStandardDirs *dirs = KGlobal::dirs();
return dirs->findResource( "data", "kmess/pics/unknown.png" );
return KMessShared::findResource( "data", "kmess/pics/unknown.png" );
}
@@ -732,7 +730,3 @@ void ContactBase::slotApplicationListAborted()
applicationList_->deleteLater();
applicationList_ = 0;
}
#include "contactbase.moc"
+9 -12
View File
@@ -21,8 +21,9 @@
#include "../kmessdebug.h"
#include <QFile>
#include <QLocale>
#include <KLocale>
#include <KLocalizedString>
#include <KConfigGroup>
@@ -104,7 +105,7 @@ const QString ContactExtension::getContactPicturePath() const
return pictureFile_;
}
return QString::null;
return QString();
}
@@ -117,7 +118,7 @@ const QString ContactExtension::getContactSoundPath() const
return soundFile_;
}
return QString::null;
return QString();
}
@@ -179,8 +180,8 @@ void ContactExtension::readProperties( const KConfigGroup &config )
// in saveProperties() !
alternativeName_ = extensionGroup.readEntry("alternativeName", "" );
alternativePictureFile_ = extensionGroup.readEntry("alternativePictureFile", "" );
lastSeen_ = QDateTime::fromTime_t( extensionGroup.readEntry("lastSeen", 0 ) );
lastMessageDate_ = QDateTime::fromTime_t( extensionGroup.readEntry("lastMessageDate", 0 ) );
lastSeen_ = QDateTime::fromSecsSinceEpoch( extensionGroup.readEntry("lastSeen", 0 ) );
lastMessageDate_ = QDateTime::fromSecsSinceEpoch( extensionGroup.readEntry("lastMessageDate", 0 ) );
disableNotifications_ = extensionGroup.readEntry("disableNotifications", false );
notes_ = extensionGroup.readEntry("notes", "" );
pictureFile_ = extensionGroup.readEntry("pictureFile", "" );
@@ -238,12 +239,12 @@ void ContactExtension::saveProperties( KConfigGroup &config )
if( ! lastSeen_.isNull() && lastSeen_.isValid() )
{
extensionGroup.writeEntry( "lastSeen", lastSeen_.toTime_t() );
extensionGroup.writeEntry( "lastSeen", lastSeen_.toSecsSinceEpoch() );
}
if( ! lastMessageDate_.isNull() && lastMessageDate_.isValid() )
{
extensionGroup.writeEntry( "lastMessageDate", lastMessageDate_.toTime_t() );
extensionGroup.writeEntry( "lastMessageDate", lastMessageDate_.toSecsSinceEpoch() );
}
extensionGroup.writeEntry( "pictureFile", pictureFile_ );
@@ -305,7 +306,7 @@ void ContactExtension::setContactPicturePath( const QString & _newVal )
if ( fileDat.open( QIODevice::WriteOnly | QIODevice::Text ) )
{
QTextStream out( &fileDat );
out << QDate::currentDate ().toString( Qt::SystemLocaleDate );
out << QLocale().toString( QDate::currentDate(), QLocale::ShortFormat );
fileDat.close();
}
}
@@ -367,7 +368,3 @@ void ContactExtension::setUseAlternativeName( bool _newVal)
if ( needUpdate == true ) emit changedFriendlyName();
}
#include "contactextension.moc"
-4
View File
@@ -189,7 +189,3 @@ void Group::setExpanded(bool expanded)
{
isExpanded_ = expanded;
}
#include "group.moc"
-3
View File
@@ -53,6 +53,3 @@ Status InvitedContact::getStatus() const
// Since no status updates are returned for a contact not on the list, return "Invisible".
return STATUS_INVISIBLE;
}
#include "invitedcontact.moc"
+2 -2
View File
@@ -42,9 +42,9 @@ class InvitedContact : public ContactBase
// The destructor
virtual ~InvitedContact();
// Return the path to the contact's picture
const QString getContactPicturePath() const;
const QString getContactPicturePath() const override;
// Return the contact's status
Status getStatus() const;
Status getStatus() const override;
};
#endif
+27 -4
View File
@@ -59,12 +59,35 @@ MsnObject::MsnObject(const MsnObject &other)
, type_(other.type_)
, sha1d_(other.sha1d_)
, sha1c_(other.sha1c_)
, stamp_(other.stamp_)
{
}
MsnObject& MsnObject::operator=( const MsnObject &other )
{
if( this == &other )
{
return *this;
}
creator_ = other.creator_;
friendly_ = other.friendly_;
location_ = other.location_;
original_ = other.original_;
size_ = other.size_;
type_ = other.type_;
sha1d_ = other.sha1d_;
sha1c_ = other.sha1c_;
stamp_ = other.stamp_;
return *this;
}
MsnObject::MsnObject( const QString &creator, const QString &location,
const QString &friendly, MsnObjectType type,
const QByteArray &fileData, const QByteArray &stamp )
@@ -98,12 +121,12 @@ QString MsnObject::getAttribute( const QString& name, const QString& object )
int index = findAttribute.indexIn( object );
// Return if found
if( index >= 0 && findAttribute.numCaptures() > 0 )
if( index >= 0 && ! findAttribute.cap( 1 ).isEmpty() )
{
return findAttribute.cap( 1 );
}
return QString::null;
return QString();
}
@@ -194,7 +217,8 @@ void MsnObject::loadObject( const QString& object )
// Don't check for invalid characters in the encoded string, QByteArray does it
const QByteArray friendlyUcs2( QByteArray::fromBase64( friendlyEncoded.toUtf8() ) );
friendly_ = QString::fromUtf16( reinterpret_cast<const ushort*>( friendlyUcs2.data() ), friendlyUcs2.size() ).toUtf8();
friendly_ = QString::fromUtf16( reinterpret_cast<const char16_t*>( friendlyUcs2.constData() ),
friendlyUcs2.size() / int( sizeof( char16_t ) ) ).toUtf8();
}
@@ -311,4 +335,3 @@ bool MsnObject::hasChanged( const QString &newObj ) const
// The data hash is not available: use the full object hash
return ( sha1c_ != getAttribute( "SHA1C", newObj ).toUtf8() );
}
+5
View File
@@ -70,6 +70,11 @@ class MsnObject
*/
MsnObject(const MsnObject &other);
/**
* Assignment operator.
*/
MsnObject& operator=( const MsnObject &other );
/**
* Create an MsnObject based on the provided attributes.
* Hashes will be calculated automatically.
+13 -13
View File
@@ -19,15 +19,16 @@
#include "../kmessdebug.h"
#include <KAction>
#include <QAction>
#include <QIcon>
#include <KIconEffect>
#include <KIconLoader>
#include <KLocale>
#include <KMenu>
#include <KLocalizedString>
#include <QMenu>
// Initialize the status menu
KMenu* MsnStatus::statusMenu_( 0 );
QMenu* MsnStatus::statusMenu_( 0 );
MsnStatus::~MsnStatus()
{
@@ -214,21 +215,22 @@ QString MsnStatus::getName( const Status status )
* Be sure to actually attach the returned menu to some toolbar or the like,
* or it won't be properly deleted.
*
* @return KMenu with a QAction for each available Status
* @return QMenu with a QAction for each available Status
*/
KMenu *MsnStatus::getStatusMenu()
QMenu *MsnStatus::getStatusMenu()
{
if( statusMenu_ != 0 )
{
return statusMenu_;
}
statusMenu_ = new KMenu();
statusMenu_->addTitle( KIcon( "go-jump" ), i18n( "&My Status" ) );
statusMenu_->setIcon( KIcon( "go-jump" ) );
statusMenu_ = new QMenu();
QAction *titleAction = statusMenu_->addAction( QIcon::fromTheme( "go-jump" ), i18n( "&My Status" ) );
titleAction->setEnabled( false );
statusMenu_->setIcon( QIcon::fromTheme( "go-jump" ) );
statusMenu_->setTitle( i18n( "&My Status" ) );
Status status;
KAction *action;
QAction *action;
// This loop assumes that a) STATES_NUMBER is the last item of the Status enum, and
// b) STATUS_OFFLINE is the second last. Fun stuff happens if it is not the case.
@@ -237,7 +239,7 @@ KMenu *MsnStatus::getStatusMenu()
// Setting the action's data allows us to later retrieve the
// Status from a triggered QAction
status = (Status) index;
action = new KAction( KIcon( getIcon( status ) ), getName( status ), statusMenu_ );
action = new QAction( QIcon( getIcon( status ) ), getName( status ), statusMenu_ );
action->setData( status );
// The disconnection action is a bit special :)
@@ -289,5 +291,3 @@ Status MsnStatus::codeToStatus( const QString &status )
return STATUS_ONLINE;
}
}
+3 -3
View File
@@ -22,7 +22,7 @@
// Forward declarations
class KMenu;
class QMenu;
@@ -89,7 +89,7 @@ class MsnStatus
// Returns the localized name for a status
static QString getName( const Status status );
// Create and return a menu with all the states
static KMenu *getStatusMenu();
static QMenu *getStatusMenu();
// Convert a three-letter code to a status
static Status codeToStatus( const QString &status );
@@ -97,7 +97,7 @@ class MsnStatus
private: // Private static properties
// The status menu
static KMenu *statusMenu_;
static QMenu *statusMenu_;
};
-12
View File
@@ -179,14 +179,6 @@ QString CurrentAccount::getContactFriendlyNameByHandle( const QString &handle, F
// Return the contact last dragged
const ContactBase* CurrentAccount::getContactLastDragged() const
{
// currently a stub
return 0;
}
// Return the contact list as read-only
const ContactList * CurrentAccount::getContactList() const
{
@@ -503,7 +495,3 @@ void CurrentAccount::slotInvitedContactLeftAllChats( ContactBase *contact )
// Delete after all slots are processed.
contact->deleteLater();
}
#include "currentaccount.moc"
+1 -3
View File
@@ -58,7 +58,7 @@ class CurrentAccount : public Account
// Receive notice that some emails were deleted
void changeNoEmails( int change );
// Copy an account
virtual void copyAccount( const Account *account );
virtual void copyAccount( const Account *account ) override;
// Delete the instance of the contact list
static void destroy();
// Return whether or not to autoreply to messages
@@ -69,8 +69,6 @@ class CurrentAccount : public Account
QString getContactFriendlyNameByHandle(const QString &handle, FormattingMode mode = STRING_CLEANED ) const;
// Return the contact list as read-only
const ContactList * getContactList() const;
// Return the contact which was last dragged.
const ContactBase* getContactLastDragged() const;
// Return the email URL
const QString& getEmailUrl() const;
// Return the external IP, as seen from the MSN server.
+7 -8
View File
@@ -23,6 +23,9 @@
#include "../currentaccount.h"
#include "../kmessdebug.h"
#include <QIcon>
#include <KLocalizedString>
/**
@@ -35,7 +38,7 @@
* @param parent Parent widget
*/
AddContactDialog::AddContactDialog( QString &handle, QStringList &groupsId, QWidget *parent )
: KDialog( parent )
: KMessDialog( parent )
, Ui::AddContactDialog()
{
// Set up the interface and the dialog
@@ -57,7 +60,7 @@ AddContactDialog::AddContactDialog( QString &handle, QStringList &groupsId, QWid
// Lock the dialog height, it's ugly otherwise
restoreDialogSize( KMessConfig::instance()->getGlobalConfig( "AddContactDialog" ) );
icon_->setPixmap( KIcon( "list-add-user" ).pixmap( 48, 48 ) );
icon_->setPixmap( QIcon::fromTheme( "list-add-user" ).pixmap( 48, 48 ) );
// Fill up the groups list from the contactlist data
const QList< Group* >& groupList( CurrentAccount::instance()->getContactList()->getGroupList() );
@@ -125,7 +128,7 @@ void AddContactDialog::interfaceChanged()
* or "a@bc"), the MSN Servers disconnect you and send you a so called ".NET message" with the error details.
* This basic set of tests is more than enough to pass the server requirements.
*
* Other than the usual address validation (see the Account::isValidEmail() method), MSN will kick you out if
* Other than the usual handle validation (see the Account::isValidHandle() method), MSN will kick you out if
* you try adding an address having ".co" as top level domain. So we ensure it has not. This is probably due
* to people keeping mistyping ".com" when adding people to their list - all random 2-character domains are
* allowed, except ".co".
@@ -133,7 +136,7 @@ void AddContactDialog::interfaceChanged()
// If the mail address seems correct, accept it
if( ! emailAddress.isEmpty()
&& Account::isValidEmail( emailAddress )
&& Account::isValidHandle( emailAddress )
&& ! emailAddress.endsWith( ".co" ) )
{
enableButtonOk( true );
@@ -164,7 +167,3 @@ const QStringList AddContactDialog::getSelectedGroups() const
return selectedGroups;
}
#include "addcontactdialog.moc"
+2 -2
View File
@@ -20,7 +20,7 @@
#include "ui_addcontactdialog.h"
#include <KDialog>
#include "../utils/kmessdialog.h"
@@ -34,7 +34,7 @@
* @author Valerio Pilo <valerio@kmess.org>
* @ingroup Dialogs
*/
class AddContactDialog : public KDialog, private Ui::AddContactDialog
class AddContactDialog : public KMessDialog, private Ui::AddContactDialog
{
Q_OBJECT

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