Hello community,

here is the log from the commit of package sonnet for openSUSE:Factory checked 
in at 2015-09-02 07:49:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sonnet (Old)
 and      /work/SRC/openSUSE:Factory/.sonnet.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "sonnet"

Changes:
--------
--- /work/SRC/openSUSE:Factory/sonnet/sonnet.changes    2015-07-14 
17:30:18.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.sonnet.new/sonnet.changes       2015-09-02 
07:49:29.000000000 +0200
@@ -1,0 +2,14 @@
+Tue Aug  4 19:20:54 UTC 2015 - [email protected]
+
+- Update to 5.13.0
+  * The Qt version requirement has been bumped from 5.2 to 5.3
+  * Debug output has been ported to categorized output, for less
+    noise by default
+  * Docbook documentation has been reviewed and updated
+  * Add in CMake bits to enable building of Voikko plugin.
+  * Implement Sonnet::Client factory for Voikko spell chekers.
+  * Implement Voikko based spell checker (Sonnet::SpellerPlugin)
+  * For more details please see:
+    https://www.kde.org/announcements/kde-frameworks-5.13.0.php
+
+-------------------------------------------------------------------

Old:
----
  sonnet-5.12.0.tar.xz

New:
----
  sonnet-5.13.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ sonnet.spec ++++++
--- /var/tmp/diff_new_pack.NjkbBP/_old  2015-09-02 07:49:30.000000000 +0200
+++ /var/tmp/diff_new_pack.NjkbBP/_new  2015-09-02 07:49:30.000000000 +0200
@@ -18,9 +18,9 @@
 
 %bcond_without lang
 %define sonum   5
-%define _tar_path 5.12
+%define _tar_path 5.13
 Name:           sonnet
-Version:        5.12.0
+Version:        5.13.0
 Release:        0
 #BuildRequires:  aspell-devel
 BuildRequires:  cmake >= 2.8.12
@@ -30,11 +30,11 @@
 BuildRequires:  fdupes
 BuildRequires:  kf5-filesystem
 %if %{with lang}
-BuildRequires:  libqt5-linguist-devel >= 5.2.0
+BuildRequires:  cmake(Qt5LinguistTools) >= 5.3.0
 %endif
-BuildRequires:  pkgconfig(Qt5Core) >= 5.2.0
-BuildRequires:  pkgconfig(Qt5Test) >= 5.2.0
-BuildRequires:  pkgconfig(Qt5Widgets) >= 5.2.0
+BuildRequires:  cmake(Qt5Core) >= 5.3.0
+BuildRequires:  cmake(Qt5Test) >= 5.3.0
+BuildRequires:  cmake(Qt5Widgets) >= 5.3.0
 BuildRequires:  pkgconfig(hunspell)
 Summary:        KDE spell checking library
 License:        LGPL-2.1+
@@ -83,7 +83,7 @@
 Requires:       extra-cmake-modules
 Requires:       libKF5SonnetCore%sonum = %{version}
 Requires:       libKF5SonnetUi%sonum = %{version}
-Requires:       pkgconfig(Qt5Core) >= 5.2.0
+Requires:       cmake(Qt5Core) >= 5.3.0
 
 %description devel
 Sonnet is a plugin-based spell checking library for Qt-based

++++++ sonnet-5.12.0.tar.xz -> sonnet-5.13.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/CMakeLists.txt 
new/sonnet-5.13.0/CMakeLists.txt
--- old/sonnet-5.12.0/CMakeLists.txt    2015-07-05 11:18:26.000000000 +0200
+++ new/sonnet-5.13.0/CMakeLists.txt    2015-08-04 13:47:13.000000000 +0200
@@ -4,7 +4,7 @@
 project(Sonnet)
 
 include(FeatureSummary)
-find_package(ECM 5.12.0  NO_MODULE)
+find_package(ECM 5.13.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL 
"https://projects.kde.org/projects/kdesupport/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
@@ -15,7 +15,7 @@
 include(KDEFrameworkCompilerSettings)
 include(KDECMakeSettings)
 
-set(REQUIRED_QT_VERSION 5.2.0)
+set(REQUIRED_QT_VERSION 5.3.0)
 find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Widgets)
 
 
@@ -26,7 +26,7 @@
 
 include(ECMPoQmTools)
 
-set(KF5_VERSION "5.12.0") # handled by release scripts
+set(KF5_VERSION "5.13.0") # handled by release scripts
 
 ecm_setup_version(${KF5_VERSION} VARIABLE_PREFIX SONNET
                         VERSION_HEADER 
"${CMAKE_CURRENT_BINARY_DIR}/sonnet_version.h"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/autotests/CMakeLists.txt 
new/sonnet-5.13.0/autotests/CMakeLists.txt
--- old/sonnet-5.12.0/autotests/CMakeLists.txt  2015-07-05 11:18:26.000000000 
+0200
+++ new/sonnet-5.13.0/autotests/CMakeLists.txt  2015-08-04 13:47:13.000000000 
+0200
@@ -3,7 +3,7 @@
 include(ECMMarkAsTest)
 include(ECMAddTests)
 
-find_package(Qt5Test 5.2.0 REQUIRED NO_MODULE)
+find_package(Qt5Test ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
 
 ########### unittests ###############
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/cmake/FindVOIKKO.cmake 
new/sonnet-5.13.0/cmake/FindVOIKKO.cmake
--- old/sonnet-5.12.0/cmake/FindVOIKKO.cmake    1970-01-01 01:00:00.000000000 
+0100
+++ new/sonnet-5.13.0/cmake/FindVOIKKO.cmake    2015-08-04 13:47:13.000000000 
+0200
@@ -0,0 +1,23 @@
+# - Try to find voikko
+# Once done this will define
+#
+#  VOIKKO_FOUND - system has VOIKKO
+#  VOIKKO_INCLUDE_DIR - the VOIKKO include directory
+#  VOIKKO_LIBRARIES - The libraries needed to use VOIKKO
+#  VOIKKO_DEFINITIONS - Compiler switches required for using VOIKKO
+
+
+IF (VOIKKO_INCLUDE_DIR AND VOIKKO_LIBRARIES)
+  # Already in cache, be silent
+  SET(VOIKKO_FIND_QUIETLY TRUE)
+ENDIF (VOIKKO_INCLUDE_DIR AND VOIKKO_LIBRARIES)
+
+FIND_PATH(VOIKKO_INCLUDE_DIR libvoikko/voikko.h)
+FIND_LIBRARY(VOIKKO_LIBRARIES NAMES voikko)
+
+# handle the QUIETLY and REQUIRED arguments and set VOIKKO_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(VOIKKO DEFAULT_MSG VOIKKO_LIBRARIES 
VOIKKO_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(VOIKKO_INCLUDE_DIR VOIKKO_LIBRARIES)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/po/ast/sonnet5_qt.po 
new/sonnet-5.13.0/po/ast/sonnet5_qt.po
--- old/sonnet-5.12.0/po/ast/sonnet5_qt.po      2015-07-05 11:18:26.000000000 
+0200
+++ new/sonnet-5.13.0/po/ast/sonnet5_qt.po      2015-08-04 13:47:13.000000000 
+0200
@@ -7,8 +7,8 @@
 "Project-Id-Version: kdelibs4-1\n"
 "Report-Msgid-Bugs-To: http://bugs.kde.org\n";
 "POT-Creation-Date: 2014-03-23 01:50+0000\n"
-"PO-Revision-Date: 2015-06-30 19:40+0100\n"
-"Last-Translator: Enol P. <[email protected]>\n"
+"PO-Revision-Date: 2015-07-11 16:22+0100\n"
+"Last-Translator: enolp <[email protected]>\n"
 "Language-Team: Asturian <[email protected]>\n"
 "Language: ast\n"
 "MIME-Version: 1.0\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/po/fr/sonnet5_qt.po 
new/sonnet-5.13.0/po/fr/sonnet5_qt.po
--- old/sonnet-5.12.0/po/fr/sonnet5_qt.po       2015-07-05 11:18:26.000000000 
+0200
+++ new/sonnet-5.13.0/po/fr/sonnet5_qt.po       2015-08-04 13:47:13.000000000 
+0200
@@ -24,10 +24,10 @@
 "PO-Revision-Date: 2014-06-29 22:06+0200\n"
 "Last-Translator: Sebastien Renard <[email protected]>\n"
 "Language-Team: French <[email protected]>\n"
-"Language: fr\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
+"Language: fr\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 "X-Generator: Lokalize 1.5\n"
 "X-Environment: kde\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/CMakeLists.txt 
new/sonnet-5.13.0/src/plugins/CMakeLists.txt
--- old/sonnet-5.12.0/src/plugins/CMakeLists.txt        2015-07-05 
11:18:26.000000000 +0200
+++ new/sonnet-5.13.0/src/plugins/CMakeLists.txt        2015-08-04 
13:47:13.000000000 +0200
@@ -45,3 +45,14 @@
    add_subdirectory( hunspell )
 endif ()
 
+
+find_package(VOIKKO)
+set_package_properties(VOIKKO PROPERTIES
+    URL "http://voikko.puimula.org/";
+    DESCRIPTION "Spell checking support via Voikko"
+    TYPE OPTIONAL
+)
+if (VOIKKO_FOUND)
+   add_subdirectory( voikko )
+endif ()
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/hunspell/hunspelldebug.cpp 
new/sonnet-5.13.0/src/plugins/hunspell/hunspelldebug.cpp
--- old/sonnet-5.12.0/src/plugins/hunspell/hunspelldebug.cpp    2015-07-05 
11:18:26.000000000 +0200
+++ new/sonnet-5.13.0/src/plugins/hunspell/hunspelldebug.cpp    2015-08-04 
13:47:13.000000000 +0200
@@ -15,4 +15,9 @@
 
 #include "hunspelldebug.h"
 
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+// logging category for this framework, default: log stuff >= warning
+Q_LOGGING_CATEGORY(SONNET_HUNSPELL, "sonnet.plugins.hunspell", QtWarningMsg)
+#else
 Q_LOGGING_CATEGORY(SONNET_HUNSPELL, "sonnet.plugins.hunspell")
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/voikko/CMakeLists.txt 
new/sonnet-5.13.0/src/plugins/voikko/CMakeLists.txt
--- old/sonnet-5.12.0/src/plugins/voikko/CMakeLists.txt 1970-01-01 
01:00:00.000000000 +0100
+++ new/sonnet-5.13.0/src/plugins/voikko/CMakeLists.txt 2015-08-04 
13:47:13.000000000 +0200
@@ -0,0 +1,13 @@
+include_directories(${VOIKKO_INCLUDE_DIR})
+
+
+########### next target ###############
+
+set(sonnet_voikko_PART_SRCS voikkoclient.cpp voikkodict.cpp voikkodebug.cpp)
+
+add_library(sonnet_voikko MODULE ${sonnet_voikko_PART_SRCS})
+
+target_link_libraries(sonnet_voikko PRIVATE KF5::SonnetCore 
${VOIKKO_LIBRARIES})
+
+set_target_properties(sonnet_voikko PROPERTIES OUTPUT_NAME "voikko")
+install(TARGETS sonnet_voikko  DESTINATION 
${KDE_INSTALL_PLUGINDIR}/kf5/sonnet/)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/voikko/voikkoclient.cpp 
new/sonnet-5.13.0/src/plugins/voikko/voikkoclient.cpp
--- old/sonnet-5.12.0/src/plugins/voikko/voikkoclient.cpp       1970-01-01 
01:00:00.000000000 +0100
+++ new/sonnet-5.13.0/src/plugins/voikko/voikkoclient.cpp       2015-08-04 
13:47:13.000000000 +0200
@@ -0,0 +1,72 @@
+/**
+ * voikkoclient.cpp
+ *
+ * Copyright (C)  2015  Jesse Jaara <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#include "voikkoclient.h"
+#include "voikkodict.h"
+#include "voikkodebug.h"
+
+VoikkoClient::VoikkoClient(QObject* parent) : Sonnet::Client(parent)
+{
+    qCDebug(SONNET_VOIKKO) << "Initializing Voikko spell checker plugin.";
+
+    char **dictionaries = voikkoListSupportedSpellingLanguages(Q_NULLPTR);
+
+    if (!dictionaries) {
+        return;
+    }
+
+    for (int i = 0; dictionaries[i] != Q_NULLPTR; ++i) {
+        QString language = QString::fromUtf8(dictionaries[i]);
+        m_supportedLanguages.append(language);
+        qCDebug(SONNET_VOIKKO) << "Found dictionary for langauge:" << language;
+    }
+
+    voikkoFreeCstrArray(dictionaries);
+}
+
+VoikkoClient::~VoikkoClient()
+{}
+
+int VoikkoClient::reliability() const
+{
+    return 50;
+}
+
+Sonnet::SpellerPlugin* VoikkoClient::createSpeller(const QString &language)
+{
+    VoikkoDict *speller = new VoikkoDict(language);
+    if (speller->initFailed()) {
+        delete speller;
+        return Q_NULLPTR;
+    }
+
+    return speller;
+}
+
+QStringList VoikkoClient::languages() const
+{
+    return m_supportedLanguages;
+}
+
+QString VoikkoClient::name() const
+{
+    return QStringLiteral("Voikko");
+}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/voikko/voikkoclient.h 
new/sonnet-5.13.0/src/plugins/voikko/voikkoclient.h
--- old/sonnet-5.12.0/src/plugins/voikko/voikkoclient.h 1970-01-01 
01:00:00.000000000 +0100
+++ new/sonnet-5.13.0/src/plugins/voikko/voikkoclient.h 2015-08-04 
13:47:13.000000000 +0200
@@ -0,0 +1,49 @@
+/**
+ * voikkoclient.h
+ *
+ * Copyright (C)  2015  Jesse Jaara <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#ifndef SONNET_VOIKKOCLIENT_H
+#define SONNET_VOIKKOCLIENT_H
+
+#include "client_p.h"
+
+class VoikkoClient : public Sonnet::Client
+{
+    Q_OBJECT
+    Q_INTERFACES(Sonnet::Client)
+    Q_PLUGIN_METADATA(IID "org.kde.Sonnet.VoikkoClient")
+
+public:
+    explicit VoikkoClient(QObject *parent = Q_NULLPTR);
+    ~VoikkoClient();
+
+    int reliability() const Q_DECL_OVERRIDE;
+
+    Sonnet::SpellerPlugin *createSpeller(const QString &language) 
Q_DECL_OVERRIDE;
+
+    QStringList languages() const Q_DECL_OVERRIDE;
+
+    QString name() const Q_DECL_OVERRIDE;
+
+private:
+    QStringList m_supportedLanguages;
+};
+
+#endif //SONNET_VOIKKOCLIENT_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/voikko/voikkodebug.cpp 
new/sonnet-5.13.0/src/plugins/voikko/voikkodebug.cpp
--- old/sonnet-5.12.0/src/plugins/voikko/voikkodebug.cpp        1970-01-01 
01:00:00.000000000 +0100
+++ new/sonnet-5.13.0/src/plugins/voikko/voikkodebug.cpp        2015-08-04 
13:47:13.000000000 +0200
@@ -0,0 +1,29 @@
+/**
+ * voikkodebug.cpp
+ *
+ * Copyright (C)  2015  Jesse Jaara <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#include "voikkodebug.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
+// logging category for this framework, default: log stuff >= warning
+Q_LOGGING_CATEGORY(SONNET_VOIKKO, "sonnet.plugins.voikko", QtWarningMsg)
+#else
+Q_LOGGING_CATEGORY(SONNET_VOIKKO, "sonnet.plugins.voikko")
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/voikko/voikkodebug.h 
new/sonnet-5.13.0/src/plugins/voikko/voikkodebug.h
--- old/sonnet-5.12.0/src/plugins/voikko/voikkodebug.h  1970-01-01 
01:00:00.000000000 +0100
+++ new/sonnet-5.13.0/src/plugins/voikko/voikkodebug.h  2015-08-04 
13:47:13.000000000 +0200
@@ -0,0 +1,28 @@
+/**
+ * voikkodebug.h
+ *
+ * Copyright (C)  2015  Jesse Jaara <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#ifndef SONNET_VOIKKODEBUG_H
+#define SONNET_VOIKKODEBUG_H
+
+#include <QLoggingCategory>
+Q_DECLARE_LOGGING_CATEGORY(SONNET_VOIKKO)
+
+#endif //SONNET_VOIKKODEBUG_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/voikko/voikkodict.cpp 
new/sonnet-5.13.0/src/plugins/voikko/voikkodict.cpp
--- old/sonnet-5.12.0/src/plugins/voikko/voikkodict.cpp 1970-01-01 
01:00:00.000000000 +0100
+++ new/sonnet-5.13.0/src/plugins/voikko/voikkodict.cpp 2015-08-04 
13:47:13.000000000 +0200
@@ -0,0 +1,344 @@
+/**
+ * voikkodict.cpp
+ *
+ * Copyright (C)  2015  Jesse Jaara <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#include "voikkodict.h"
+#include "voikkodebug.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QStandardPaths>
+#include <QtCore/QVector>
+#ifdef Q_IS_WIN
+    #include <QtCore/QSysInfo>
+#endif
+
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+
+namespace
+{
+    // QString literals used in loading and storing user dictionary
+    inline const QString replacement_bad_str() Q_DECL_NOEXCEPT
+    {
+        return QStringLiteral("bad");
+    }
+
+    inline const QString replacement_good_str() Q_DECL_NOEXCEPT
+    {
+        return QStringLiteral("good");
+    }
+
+    inline const QString personal_words_str() Q_DECL_NOEXCEPT
+    {
+        return QStringLiteral("PersonalWords");
+    }
+
+    inline const QString replacements_str() Q_DECL_NOEXCEPT
+    {
+        return QStringLiteral("Replacements");
+    }
+
+    // Set path to: 
QStandardPaths::GenericDataLocation/Sonnet/Voikko-user-dictionary.json
+    QString getUserDictionaryPath() Q_DECL_NOEXCEPT
+    {
+        QString directory = 
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
+
+        #ifdef Q_OS_WIN
+        // Resolve the windows' Roaming directory manually
+        directory = 
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
+        if (QSysInfo::windowsVersion() == WV_XP || QSysInfo::windowsVersion() 
== WV_2003) {
+            // In Xp Roaming is "<user>/Application Data"
+            // DataLocation: "<user>/Local Settings/Application Data"
+            directory += QStringLiteral("/../../Application Data");
+        }
+        else {
+            directory += QStringLiteral("/../Roaming");
+        }
+        #endif
+
+        directory += QStringLiteral("/Sonnet");
+        QDir path(directory);
+        path.mkpath(path.absolutePath());
+
+        return 
path.absoluteFilePath(QStringLiteral("Voikko-user-dictionary.json"));
+    }
+
+    void addReplacementToNode(QJsonObject &languageNode,
+                                     const QString &bad, const QString &good) 
Q_DECL_NOEXCEPT
+    {
+        QJsonObject pair;
+        pair[replacement_bad_str()] = good;
+        pair[replacement_good_str()] = bad;
+
+        auto replaceList = languageNode[replacements_str()].toArray();
+        replaceList.append(pair);
+        languageNode[replacements_str()] = replaceList;
+    }
+
+    void addPersonalWordToNode(QJsonObject &languageNode,
+                                      const QString &word) Q_DECL_NOEXCEPT
+    {
+        auto arr = languageNode[personal_words_str()].toArray();
+        arr.append(word);
+        languageNode[personal_words_str()] = arr;
+    }
+
+    /**
+     * Read and return the root json object from fileName.
+     *
+     * Returns an empty node in case of an IO error or the file is empty.
+     */
+    QJsonObject readJsonRootObject(const QString &fileName) Q_DECL_NOEXCEPT
+    {
+        QFile userDictFile(fileName);
+
+        if (!userDictFile.exists()) {
+            return QJsonObject(); // Nothing has been saved so far.
+        }
+
+        if (!userDictFile.open(QIODevice::ReadOnly)) {
+            qCWarning(SONNET_VOIKKO) << "Could not open personal dictionary. 
Failed to open file"
+                                     << fileName;
+            qCWarning(SONNET_VOIKKO) << "Reason:" << 
userDictFile.errorString();
+            return QJsonObject();
+        }
+
+        QJsonDocument dictDoc = 
QJsonDocument::fromJson(userDictFile.readAll());
+        userDictFile.close();
+
+        return dictDoc.object();
+    }
+}
+
+class VoikkoDictPrivate
+{
+public:
+    VoikkoHandle *m_handle;
+    const VoikkoDict *q;
+
+    QSet<QString> m_sessionWords;
+    QSet<QString> m_personalWords;
+    QHash<QString, QString> m_replacements;
+
+    QString m_userDictionaryFilepath;
+
+    // Used when converting Qstring to wchar_t strings
+    QVector<wchar_t> m_conversionBuffer;
+
+
+    VoikkoDictPrivate(const QString &language, const VoikkoDict *publicPart) 
Q_DECL_NOEXCEPT
+            : q(publicPart),
+              m_userDictionaryFilepath(getUserDictionaryPath()),
+              m_conversionBuffer(256)
+    {
+        const char *error;
+        m_handle = voikkoInit(&error, language.toUtf8().data(), 0);
+
+        if (error != Q_NULLPTR) {
+            qCWarning(SONNET_VOIKKO) << "Failed to initialize Voikko spelling 
backend. Reason:"
+                                     << error;
+        } else { // Continue to load user's own words
+            loadUserDictionary();
+        }
+    };
+
+
+    /**
+     * Store a new ignored/personal word or replacement pair in the user's
+     * dictionary m_userDictionaryFilepath.
+     *
+     * returns true on success else false
+     */
+    bool storePersonal(const QString &personalWord,
+                       const QString &bad = QString(),
+                       const QString &good = QString()) const Q_DECL_NOEXCEPT
+    {
+        QFile userDictFile(m_userDictionaryFilepath);
+
+        if (!userDictFile.open(QIODevice::ReadWrite)) {
+            qCWarning(SONNET_VOIKKO) << "Could not save personal dictionary. 
Failed to open file:"
+                                     << m_userDictionaryFilepath;
+            qCWarning(SONNET_VOIKKO) << "Reason:" << 
userDictFile.errorString();
+            return false;
+        }
+
+        QJsonDocument dictDoc = 
QJsonDocument::fromJson(userDictFile.readAll());
+        auto root = readJsonRootObject(m_userDictionaryFilepath);
+        auto languageNode = root[q->language()].toObject();
+
+        // Empty value means we are storing a bad:good pair
+        if (personalWord.isEmpty()) {
+            addReplacementToNode(languageNode, bad, good);
+        } else {
+            addPersonalWordToNode(languageNode, personalWord);
+        }
+
+        root[q->language()] = languageNode;
+        dictDoc.setObject(root);
+
+        userDictFile.reset();
+        userDictFile.write(dictDoc.toJson());
+        userDictFile.close();
+        qCDebug(SONNET_VOIKKO) << "Changes to user dictionary saved to file: "
+                               << m_userDictionaryFilepath;
+
+        return true;
+    };
+
+    /**
+     * Load user's own personal words and replacement pairs from
+     * m_userDictionaryFilepath.
+     */
+    void loadUserDictionary() Q_DECL_NOEXCEPT
+    {
+        // If root is empty we will fail later on when checking if
+        // languageNode is empty.
+        auto root = readJsonRootObject(m_userDictionaryFilepath);
+        auto languageNode = root[q->language()].toObject();
+
+        if (languageNode.isEmpty()) {
+            return; // Nothing to load
+        }
+
+        loadUserWords(languageNode);
+        loadUserReplacements(languageNode);
+    };
+
+    /**
+     * Convert the given QString to a \0 terminated wchar_t string.
+     * Uses QVector as a buffer and return it's internal data pointer.
+     */
+    inline const wchar_t *QStringToWchar(const QString &str) Q_DECL_NOEXCEPT
+    {
+        m_conversionBuffer.resize(str.length() + 1);
+        int size = str.toWCharArray(m_conversionBuffer.data());
+        m_conversionBuffer[size] = '\0';
+
+        return m_conversionBuffer.constData();
+    }
+
+private:
+    /**
+     * Extract and append user defined words from the languageNode.
+     */
+    inline void loadUserWords(const QJsonObject &languageNode) Q_DECL_NOEXCEPT
+    {
+        auto words = languageNode[personal_words_str()].toArray();
+        Q_FOREACH(auto word, words) {
+            m_personalWords.insert(word.toString());
+        }
+        qCDebug(SONNET_VOIKKO)
+            << QStringLiteral("Loaded %1 words from the user 
dictionary.").arg(words.size());
+    }
+
+    /**
+     * Extract and append user defined replacement pairs from the languageNode.
+     */
+    inline void loadUserReplacements(const QJsonObject &languageNode) 
Q_DECL_NOEXCEPT
+    {
+        auto words = languageNode[replacements_str()].toArray();
+        Q_FOREACH(auto pair, words) {
+                
m_replacements[pair.toObject()[replacement_bad_str()].toString()] =
+                               
pair.toObject()[replacement_good_str()].toString();
+            }
+        qCDebug(SONNET_VOIKKO)
+            << QStringLiteral("Loaded %1 replacements from the user 
dictionary.").arg(words.size());
+    }
+};
+
+
+VoikkoDict::VoikkoDict(const QString &language) Q_DECL_NOEXCEPT
+        : SpellerPlugin(language),
+          d(new VoikkoDictPrivate(language, this))
+{
+    qCDebug(SONNET_VOIKKO) << "Loading dictionary for langauge:" << language;
+}
+
+VoikkoDict::~VoikkoDict()
+{}
+
+
+bool VoikkoDict::isCorrect(const QString &word) const
+{
+    // Check the session word list and personal word list first
+    if (d->m_sessionWords.contains(word) || d->m_personalWords.contains(word)) 
{
+        return true;
+    }
+
+    return (voikkoSpellUcs4(d->m_handle, d->QStringToWchar(word)) == 
VOIKKO_SPELL_OK);
+}
+
+QStringList VoikkoDict::suggest(const QString &word) const
+{
+    QStringList suggestions;
+
+    auto userDictPos = d->m_replacements.constFind(word);
+    if (userDictPos != d->m_replacements.constEnd()) {
+        suggestions.append(*userDictPos);
+    }
+
+    auto voikkoSuggestions = voikkoSuggestUcs4(d->m_handle, 
d->QStringToWchar(word));
+
+    if (!voikkoSuggestions) {
+        return suggestions;
+    }
+
+    for (int i = 0; voikkoSuggestions[i] != Q_NULLPTR; ++i) {
+        QString suggestion = QString::fromWCharArray(voikkoSuggestions[i]);
+        suggestions.append(suggestion);
+    }
+    qCDebug(SONNET_VOIKKO) << "Misspelled:" << word
+                           << "|Suggestons:" << 
suggestions.join(QStringLiteral(", "));
+
+
+    voikko_free_suggest_ucs4(voikkoSuggestions);
+
+    return suggestions;
+}
+
+
+bool VoikkoDict::storeReplacement(const QString &bad, const QString &good)
+{
+    qCDebug(SONNET_VOIKKO) << "Adding new replacement pair to user dictionary:"
+                           << bad << "->" << good;
+    d->m_replacements[bad] = good;
+    return d->storePersonal(QString(), bad, good);
+}
+
+bool VoikkoDict::addToPersonal(const QString &word)
+{
+    qCDebug(SONNET_VOIKKO()) << "Adding new word to user dictionary" << word;
+    d->m_personalWords.insert(word);
+    return d->storePersonal(word);
+}
+
+bool VoikkoDict::addToSession(const QString &word)
+{
+    qCDebug(SONNET_VOIKKO()) << "Adding new word to session dictionary" << 
word;
+    d->m_sessionWords.insert(word);
+    return true;
+}
+
+
+bool VoikkoDict::initFailed() const Q_DECL_NOEXCEPT
+{
+    return (!d->m_handle);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/plugins/voikko/voikkodict.h 
new/sonnet-5.13.0/src/plugins/voikko/voikkodict.h
--- old/sonnet-5.12.0/src/plugins/voikko/voikkodict.h   1970-01-01 
01:00:00.000000000 +0100
+++ new/sonnet-5.13.0/src/plugins/voikko/voikkodict.h   2015-08-04 
13:47:13.000000000 +0200
@@ -0,0 +1,68 @@
+/**
+ * voikkodict.h
+ *
+ * Copyright (C)  2015  Jesse Jaara <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#ifndef SONNET_VOIKKODICT_H
+#define SONNET_VOIKKODICT_H
+
+#include "spellerplugin_p.h"
+#include <libvoikko/voikko.h>
+
+#include <QtCore/QHash>
+#include <QtCore/QSet>
+
+class VoikkoClient;
+class VoikkoDictPrivate;
+
+class VoikkoDict : public Sonnet::SpellerPlugin
+{
+public:
+    /**
+     * Declare VoikkoClient as friend so we can use the protected constructor.
+     */
+    friend class VoikkoClient;
+
+    ~VoikkoDict();
+
+    bool isCorrect(const QString &word) const Q_DECL_OVERRIDE;
+    QStringList suggest(const QString &word) const Q_DECL_OVERRIDE;
+
+    bool storeReplacement(const QString &bad,
+                          const QString &good) Q_DECL_OVERRIDE;
+    bool addToPersonal(const QString &word) Q_DECL_OVERRIDE;
+    bool addToSession(const QString &word) Q_DECL_OVERRIDE;
+
+    /**
+     * @returns true if initializing Voikko backend failed.
+     */
+    bool initFailed() const Q_DECL_NOEXCEPT;
+
+protected:
+    /**
+     * Constructor is protected so that only spellers created
+     * and validated through VoikkoClient can be used.
+     */
+    explicit VoikkoDict(const QString &language) Q_DECL_NOEXCEPT;
+
+private:
+    QScopedPointer<VoikkoDictPrivate> d;
+};
+
+#endif //SONNET_VOIKKODICT_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/sonnet-5.12.0/src/ui/spellcheckdecorator.cpp 
new/sonnet-5.13.0/src/ui/spellcheckdecorator.cpp
--- old/sonnet-5.12.0/src/ui/spellcheckdecorator.cpp    2015-07-05 
11:18:26.000000000 +0200
+++ new/sonnet-5.13.0/src/ui/spellcheckdecorator.cpp    2015-08-04 
13:47:13.000000000 +0200
@@ -265,7 +265,11 @@
 bool SpellCheckDecorator::isSpellCheckingEnabledForBlock(const QString 
&textBlock) const
 {
     Q_UNUSED(textBlock);
-    return true;
+    if (d->m_textEdit) {
+        return d->m_textEdit->isEnabled();
+    } else {
+        return d->m_plainTextEdit->isEnabled();
+    }
 }
 
 } // namespace


Reply via email to