summaryrefslogtreecommitdiffstats
path: root/scribus/plugins
diff options
context:
space:
mode:
authorcraig <craig@11d20701-8431-0410-a711-e3c959e3b870>2012-04-12 21:33:03 +0000
committercraig <craig@11d20701-8431-0410-a711-e3c959e3b870>2012-04-12 21:33:03 +0000
commitf3403971efbfd72c8a59eb1957292cf534f1233b (patch)
treee7f9c07edc09836a262befb69e7af168bc0b8563 /scribus/plugins
parentedaa5356a69507d02769dc9a69f32021e6e07ac3 (diff)
downloadscribus-f3403971efbfd72c8a59eb1957292cf534f1233b.tar.gz
scribus-f3403971efbfd72c8a59eb1957292cf534f1233b.tar.xz
scribus-f3403971efbfd72c8a59eb1957292cf534f1233b.zip
Add hunspell based spell checker - not enabled, backup only for now, not enabled in the build
git-svn-id: svn://scribus.net/branches/Version14x/Scribus@17437 11d20701-8431-0410-a711-e3c959e3b870
Diffstat (limited to 'scribus/plugins')
-rw-r--r--scribus/plugins/tools/CMakeLists.txt3
-rw-r--r--scribus/plugins/tools/hunspellcheck/CMakeLists.txt46
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp143
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspelldialog.h47
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspelldialogbase.ui205
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspellplugin.cpp95
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspellplugin.h40
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp251
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h48
-rw-r--r--scribus/plugins/tools/hunspellcheck/hunspellpluginstructs.h16
10 files changed, 894 insertions, 0 deletions
diff --git a/scribus/plugins/tools/CMakeLists.txt b/scribus/plugins/tools/CMakeLists.txt
index 16805ec..979354e 100644
--- a/scribus/plugins/tools/CMakeLists.txt
+++ b/scribus/plugins/tools/CMakeLists.txt
@@ -9,4 +9,7 @@ ADD_SUBDIRECTORY(subdivide)
if (HAVE_ASPELL)
ADD_SUBDIRECTORY(spellcheck)
endif (HAVE_ASPELL)
+if (HAVE_HUNSPELL)
+ ADD_SUBDIRECTORY(hunspellcheck)
+endif (HAVE_HUNSPELL)
ADD_SUBDIRECTORY(transform)
diff --git a/scribus/plugins/tools/hunspellcheck/CMakeLists.txt b/scribus/plugins/tools/hunspellcheck/CMakeLists.txt
new file mode 100644
index 0000000..4d1129c
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/CMakeLists.txt
@@ -0,0 +1,46 @@
+
+ INCLUDE_DIRECTORIES(
+ ${CMAKE_SOURCE_DIR}
+ ${CMAKE_SOURCE_DIR}/scribus
+ ${HUNSPELL_INCLUDE_DIR}
+ )
+
+ SET(HUNSPELL_PLUGIN_UI_SRC
+ hunspelldialogbase.ui
+ )
+
+ SET(HUNSPELL_PLUGIN_MOC_CLASSES
+ hunspelldialog.h
+ hunspellplugin.h
+ hunspellpluginimpl.h
+ )
+
+ SET(HUNSPELL_PLUGIN_SOURCES
+ hunspelldialog.cpp
+ hunspellplugin.cpp
+ hunspellpluginimpl.cpp
+ )
+
+ SET(SCRIBUS_HUNSPELL_PLUGIN "hunspellplugin")
+
+ QT4_WRAP_UI(HUNSPELL_PLUGIN_UI_SOURCES ${HUNSPELL_PLUGIN_UI_SRC} )
+ QT4_WRAP_CPP(HUNSPELL_PLUGIN_MOC_SOURCES ${HUNSPELL_PLUGIN_MOC_CLASSES})
+
+ ADD_LIBRARY(${SCRIBUS_HUNSPELL_PLUGIN} MODULE
+ ${HUNSPELL_PLUGIN_SOURCES}
+ ${HUNSPELL_PLUGIN_MOC_SOURCES}
+ ${HUNSPELL_PLUGIN_UI_SOURCES}
+ )
+
+ TARGET_LINK_LIBRARIES(${SCRIBUS_HUNSPELL_PLUGIN} ${HUNSPELL_LIBRARIES} ${PLUGIN_LIBRARIES})
+
+ INSTALL(TARGETS ${SCRIBUS_HUNSPELL_PLUGIN}
+ LIBRARY
+ DESTINATION ${PLUGINDIR}
+ PERMISSIONS ${PLUGIN_PERMISSIONS}
+ )
+
+ ADD_DEPENDENCIES(${SCRIBUS_HUNSPELL_PLUGIN} ${EXE_NAME})
+
+# SET_TARGET_PROPERTIES(${SCRIBUS_ASPELL_PLUGIN} PROPERTIES VERSION "0.0.1")
+
diff --git a/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp b/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp
new file mode 100644
index 0000000..4d589e3
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp
@@ -0,0 +1,143 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+
+#include <QComboBox>
+#include <QListWidget>
+#include <QTextEdit>
+#include "hunspelldialog.h"
+
+
+HunspellDialog::HunspellDialog(QWidget *parent, ScribusDoc *doc, PageItem *frameToCheck)
+{
+ setupUi( this );
+ setModal( true );
+
+ connect (ignoreOncePushButton, SIGNAL(clicked()), this, SLOT(goToNextWord()));
+ connect (ignoreAllPushButton, SIGNAL(clicked()), this, SLOT(ignoreAllWords()));
+ connect (changePushButton, SIGNAL(clicked()), this, SLOT(changeWord()));
+ connect (changeAllPushButton, SIGNAL(clicked()), this, SLOT(changeAllWords()));
+
+ m_doc=doc;
+ m_docChanged=false;
+ fTC=frameToCheck;
+ changeOffset=0;
+}
+
+void HunspellDialog::set(QStringList *dictEntries, Hunspell **hspellers, QList<WordsFound> *wfList)
+{
+ m_dictEntries=dictEntries;
+ m_hspellers=hspellers;
+ m_wfList=wfList;
+
+ languagesComboBox->addItems(*dictEntries);
+
+ wfListIndex=0;
+ goToNextWord(0);
+}
+
+void HunspellDialog::goToNextWord(int i)
+{
+ if (i>=0)
+ wfListIndex=i;
+ else
+ ++wfListIndex;
+ if (wfListIndex>=m_wfList->count())
+ {
+ statusLabel->setText(tr("Spelling check complete"));
+ suggestionsListWidget->clear();
+ sentenceTextEdit->clear();
+ changePushButton->setEnabled(false);
+ changeAllPushButton->setEnabled(false);
+ return;
+ }
+ else
+ statusLabel->setText("");
+ currWF=m_wfList->at(wfListIndex);
+ suggestionsListWidget->clear();
+ suggestionsListWidget->addItems(currWF.replacements);
+ suggestionsListWidget->setCurrentRow(0);
+ StoryText *iText=&fTC->itemText;
+ int sentencePos=qMax(0,iText->prevSentence(currWF.start));
+ sentencePos=qMax(sentencePos, iText->nextWord(sentencePos));
+ int nextSentencePos=qMin(iText->length(), iText->nextSentence(currWF.end));
+ QString sentence=iText->text(sentencePos, nextSentencePos-sentencePos);
+ sentence.insert(currWF.end-sentencePos+changeOffset,"</b></font>");
+ sentence.insert(currWF.start-sentencePos+changeOffset,"<font color=red><b>");
+ sentenceTextEdit->setText(sentence);
+
+}
+
+void HunspellDialog::ignoreAllWords()
+{
+ QString wordToIgnore=m_wfList->at(wfListIndex).w;
+ //Do we start from 0 or from the instance of the word where we are... 0 for now
+ for(int i=0;i<m_wfList->count();++i)
+ if(m_wfList->at(i).w==wordToIgnore)
+ m_wfList->value(i).ignore=true;
+ goToNextWord();
+}
+
+void HunspellDialog::changeWord()
+{
+ //If we have ignored a word, skip to the next.
+ if(m_wfList->at(wfListIndex).ignore && !m_wfList->at(wfListIndex).changed)
+ goToNextWord();
+ replaceWord(wfListIndex);
+ m_docChanged=true;
+ goToNextWord();
+}
+
+void HunspellDialog::changeAllWords()
+{
+ if(m_wfList->at(wfListIndex).ignore && !m_wfList->at(wfListIndex).changed)
+ return;
+ QString wordToChange=m_wfList->at(wfListIndex).w;
+ //Do we start from 0 or from the instance of the word where we are... 0 for now
+ for(int i=0;i<m_wfList->count();++i)
+ if(m_wfList->at(i).w==wordToChange)
+ {
+ m_wfList->value(i).changed=true;
+ }
+ m_docChanged=true;
+ goToNextWord();
+}
+
+void HunspellDialog::replaceWord(int i)
+{
+ StoryText *iText=&fTC->itemText;
+ currWF=m_wfList->at(i);
+ m_wfList->value(i).changed=true;
+ QString newText(suggestionsListWidget->currentItem()->text());
+ if (newText.length()==currWF.w.length())
+ {
+ for (int i = 0; i < currWF.w.length(); ++i)
+ iText->replaceChar(currWF.start+i+changeOffset, newText[i]);
+ }
+ else
+ {
+ if (newText.length()>currWF.w.length())
+ {
+ for (int i = 0; i < currWF.w.length(); ++i)
+ iText->replaceChar(currWF.start+i+changeOffset, newText[i]);
+ for (int i = currWF.w.length(); i < newText.length(); ++i)
+ iText->insertChars(currWF.start+i+changeOffset, newText.mid(i,1), true);
+ int lengthDiff=newText.length()-currWF.w.length();
+ changeOffset+=lengthDiff;
+ qDebug()<<"Change Offset is:"<<changeOffset;
+ }
+ else
+ {
+ for (int i = 0; i < newText.length(); ++i)
+ iText->replaceChar(currWF.start+i+changeOffset, newText[i]);
+ int lengthDiff=currWF.w.length() - newText.length();
+ iText->removeChars(currWF.start+changeOffset+newText.length(), lengthDiff);
+ changeOffset-=lengthDiff;
+ qDebug()<<"Change Offset is:"<<changeOffset;
+ }
+ }
+ m_docChanged=true;
+}
diff --git a/scribus/plugins/tools/hunspellcheck/hunspelldialog.h b/scribus/plugins/tools/hunspellcheck/hunspelldialog.h
new file mode 100644
index 0000000..b3e5a0f
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspelldialog.h
@@ -0,0 +1,47 @@
+#ifndef HUNSPELLDIALOG_H
+#define HUNSPELLDIALOG_H
+
+#include <QDialog>
+#include <QList>
+#include <QStringList>
+#include <QWidget>
+
+#include <hunspell/hunspell.hxx>
+
+#include "pluginapi.h"
+#include "hunspellpluginstructs.h"
+#include "scribusdoc.h"
+#include "pageitem.h"
+
+#include "ui_hunspelldialogbase.h"
+
+class PLUGIN_API HunspellDialog : public QDialog, private Ui::HunspellDialogBase
+{
+ Q_OBJECT
+
+ public:
+ HunspellDialog(QWidget* parent, ScribusDoc *doc, PageItem* frameToCheck);
+ ~HunspellDialog() {};
+ void set(QStringList* dictEntries, Hunspell **hspellers, QList<WordsFound>* wfList);
+ bool docChanged() {return m_docChanged;}
+
+ public slots:
+ void goToNextWord(int i=-1);
+ void ignoreAllWords();
+ void changeWord();
+ void changeAllWords();
+ void replaceWord(int i);
+
+ private:
+ ScribusDoc* m_doc;
+ PageItem* fTC;
+ QStringList* m_dictEntries;
+ Hunspell **m_hspellers;
+ QList<WordsFound>* m_wfList;
+ WordsFound currWF;
+ int wfListIndex;
+ bool m_docChanged;
+ int changeOffset;
+};
+
+#endif // HUNSPELLDIALOG_H
diff --git a/scribus/plugins/tools/hunspellcheck/hunspelldialogbase.ui b/scribus/plugins/tools/hunspellcheck/hunspelldialogbase.ui
new file mode 100644
index 0000000..96f1631
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspelldialogbase.ui
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>HunspellDialogBase</class>
+ <widget class="QDialog" name="HunspellDialogBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>687</width>
+ <height>406</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Check Spelling</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Text Language:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="languagesComboBox"/>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Not in dictionary</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QTextEdit" name="sentenceTextEdit"/>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QPushButton" name="ignoreOncePushButton">
+ <property name="text">
+ <string>Ignore Once</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="ignoreAllPushButton">
+ <property name="text">
+ <string>Ignore All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Suggestions</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QListWidget" name="suggestionsListWidget"/>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPushButton" name="changePushButton">
+ <property name="text">
+ <string>Change</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="changeAllPushButton">
+ <property name="text">
+ <string>Change All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="statusLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>HunspellDialogBase</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>HunspellDialogBase</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/scribus/plugins/tools/hunspellcheck/hunspellplugin.cpp b/scribus/plugins/tools/hunspellcheck/hunspellplugin.cpp
new file mode 100644
index 0000000..5b089a7
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspellplugin.cpp
@@ -0,0 +1,95 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+#include "hunspellplugin.h"
+#include "hunspellpluginimpl.h"
+#include "scribuscore.h"
+
+// See scplugin.h and pluginmanager.{cpp,h} for detail on what these methods
+// do. That documentatation is not duplicated here.
+// Please don't implement the functionality of your plugin here; do that
+// in mypluginimpl.h and mypluginimpl.cpp .
+
+HunspellPlugin::HunspellPlugin() : ScActionPlugin()
+{
+ // Set action info in languageChange, so we only have to do
+ // it in one place.
+ languageChange();
+}
+
+HunspellPlugin::~HunspellPlugin() {};
+
+void HunspellPlugin::languageChange()
+{
+ // Note that we leave the unused members unset. They'll be initialised
+ // with their default ctors during construction.
+ // Action name
+ m_actionInfo.name = "HunspellPlugin";
+ // Action text for menu, including &accel
+ m_actionInfo.text = tr("Hunspell &Plugin");
+ // Menu
+ m_actionInfo.menu = "Item";
+ // If needed, what item to add the menu item after
+ //m_actionInfo.menuAfterName = "ColorWheel"
+ // If needed, the keyboard shortcut for the plugin
+ m_actionInfo.keySequence = "SHIFT+F7";
+ // Should the menu item be enabled when the app starts
+ // (even without a document open) ?
+ m_actionInfo.enabledOnStartup = false;
+ m_actionInfo.notSuitableFor.append(PageItem::Line);
+ m_actionInfo.notSuitableFor.append(PageItem::Polygon);
+ m_actionInfo.notSuitableFor.append(PageItem::ImageFrame);
+ m_actionInfo.notSuitableFor.append(PageItem::PathText);
+ m_actionInfo.notSuitableFor.append(PageItem::LatexFrame);
+ m_actionInfo.needsNumObjects = 1;
+}
+
+const QString HunspellPlugin::fullTrName() const
+{
+ return QObject::tr("Hunspell Plugin");
+}
+
+const ScActionPlugin::AboutData* HunspellPlugin::getAboutData() const
+{
+ AboutData* about = new AboutData;
+ Q_CHECK_PTR(about);
+ return about;
+}
+
+void HunspellPlugin::deleteAboutData(const AboutData* about) const
+{
+ Q_ASSERT(about);
+ delete about;
+}
+
+bool HunspellPlugin::run(ScribusDoc* doc, QString target)
+{
+ HunspellPluginImpl *hunspellPluginImpl = new HunspellPluginImpl();
+ Q_CHECK_PTR(hunspellPluginImpl);
+ bool result = hunspellPluginImpl->run(target, doc);
+ delete hunspellPluginImpl;
+ return result;
+}
+
+// Low level plugin API
+int hunspellplugin_getPluginAPIVersion()
+{
+ return PLUGIN_API_VERSION;
+}
+
+ScPlugin* hunspellplugin_getPlugin()
+{
+ HunspellPlugin* plug = new HunspellPlugin();
+ Q_CHECK_PTR(plug);
+ return plug;
+}
+
+void hunspellplugin_freePlugin(ScPlugin* plugin)
+{
+ HunspellPlugin* plug = dynamic_cast<HunspellPlugin*>(plugin);
+ Q_ASSERT(plug);
+ delete plug;
+}
diff --git a/scribus/plugins/tools/hunspellcheck/hunspellplugin.h b/scribus/plugins/tools/hunspellcheck/hunspellplugin.h
new file mode 100644
index 0000000..0b89101
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspellplugin.h
@@ -0,0 +1,40 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+#ifndef HUNSPELLPLUGIN_H
+#define HUNSPELLPLUGIN_H
+
+#include "pluginapi.h"
+#include "scplugin.h"
+
+/*! \brief See scplugin.h and pluginmanager.{cpp,h} for detail on what these methods do.
+That documentatation is not duplicated here.
+Please don't implement the functionality of your plugin here; do that
+in mypluginimpl.h and mypluginimpl.cpp. */
+class PLUGIN_API HunspellPlugin : public ScActionPlugin
+{
+ Q_OBJECT
+
+ public:
+ //! \brief Standard plugin implementation
+ HunspellPlugin();
+ virtual ~HunspellPlugin();
+ //! \brief main method to run the plug
+ virtual bool run(ScribusDoc* doc, QString target = QString::null);
+ virtual const QString fullTrName() const;
+ virtual const AboutData* getAboutData() const;
+ virtual void deleteAboutData(const AboutData* about) const;
+ virtual void languageChange();
+ virtual void addToMainWindowMenu(ScribusMainWindow *) {};
+
+ // Special features (none)
+};
+
+extern "C" PLUGIN_API int hunspellplugin_getPluginAPIVersion();
+extern "C" PLUGIN_API ScPlugin* hunspellplugin_getPlugin();
+extern "C" PLUGIN_API void hunspellplugin_freePlugin(ScPlugin* plugin);
+
+#endif
diff --git a/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp b/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp
new file mode 100644
index 0000000..7d3c7da
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp
@@ -0,0 +1,251 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+#include "hunspellpluginimpl.h"
+#include "hunspelldialog.h"
+#include "pageitem.h"
+#include "pageitem_textframe.h"
+#include "selection.h"
+#include "scribusdoc.h"
+#include "scribus.h"
+#include "text/specialchars.h"
+#include "util.h"
+
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+#include <QMessageBox>
+
+#ifdef Q_OS_WIN32
+#include <windows.h>
+#include <shlobj.h>
+#endif
+
+
+// Initialize members here, if any
+HunspellPluginImpl::HunspellPluginImpl() : QObject(0)
+{
+ hspellers=NULL;
+ numDicts=0;
+}
+
+HunspellPluginImpl::~HunspellPluginImpl()
+{
+ if (hspellers)
+ {
+ for (int i = 0; i < numDicts; ++i)
+ {
+ delete hspellers[i];
+ hspellers[i] = NULL;
+ }
+ delete[] hspellers;
+ }
+ hspellers = NULL;
+ numDicts = 0;
+}
+
+bool HunspellPluginImpl::run(const QString & target, ScribusDoc* doc)
+{
+ m_doc=doc;
+ bool initOk=initHunspell();
+ qDebug()<<"Hunspell Init Ok:"<<initOk;
+ if (!initOk)
+ return false;
+ bool spellCheckOk=checkWithHunspell();
+ if (!spellCheckOk)
+ return false;
+ return true;
+}
+
+bool HunspellPluginImpl::findDictionaries()
+{
+ //dictionaryPaths
+ QString macPortsPath("/opt/local/share/hunspell/");
+ QString finkPath("/sw/share/hunspell/");
+ QString osxLibreOfficePath("/Applications/LibreOffice.app/Contents/share/extensions");
+ QString osxUserLibreOfficePath(QDir::homePath()+"/Applications/LibreOffice.app/Contents/share/extensions");
+ QString linuxLocalPath("/usr/local/share/hunspell/");
+ QString linuxPath("/usr/share/hunspell/");
+ QString windowsLOPath("LibreOffice 3.5/share/extensions");
+ QDir d;
+
+#ifdef Q_OS_MAC
+ d.setPath(macPortsPath);
+ if (d.exists())
+ {
+ dictPath=macPortsPath;
+ return true;
+ }
+ d.setPath(finkPath);
+ if (d.exists())
+ {
+ dictPath=finkPath;
+ return true;
+ }
+ d.setPath(osxLibreOfficePath);
+ if (d.exists())
+ {
+ dictPath=osxLibreOfficePath;
+ return true;
+ }
+ d.setPath(osxUserLibreOfficePath);
+ if (d.exists())
+ {
+ dictPath=osxUserLibreOfficePath;
+ return true;
+ }
+ return false;
+#elif defined(Q_WS_X11)
+ d.setPath(linuxPath);
+ if (d.exists())
+ {
+ dictPath=linuxPath;
+ return true;
+ }
+ d.setPath(linuxLocalPath);
+ if (d.exists())
+ {
+ dictPath=linuxLocalPath;
+ return true;
+ }
+#elif defined(Q_OS_WIN32)
+ QString progFiles = getSpecialDir(CSIDL_PROGRAM_FILES);
+ d.setPath(progFiles+windowsLOPath);
+ if (d.exists())
+ {
+ dictPath=progFiles+windowsLOPath;
+ return true;
+ }
+#endif
+ return false;
+}
+
+bool HunspellPluginImpl::initHunspell()
+{
+ int errorCount=0;
+ bool dictPathFound=findDictionaries();
+ if (!dictPathFound)
+ qDebug()<<"No preinstalled dictonary paths found";
+ else
+ qDebug()<<"Preinstalled dictionary path selected"<<dictPath;
+ //TODO: Find this somehow
+// QString startPath;
+// startPath="/Applications/LibreOffice.app/Contents/share/extensions/dict-en/";
+// dictPath=startPath;
+
+ // Find the dic and aff files in the location
+ QDir dictLocation(dictPath);
+ QStringList dictFilters, affFilters;
+ dictFilters << "*.dic";
+ affFilters << "*.aff";
+ QStringList dictList(dictLocation.entryList(dictFilters, QDir::Files, QDir::Name));
+ dictList.replaceInStrings(".dic","");
+ QStringList affList;
+
+ //Ensure we have aff+dic file pairs, remove any hyphenation dictionaries from the list
+ QString dictName;
+ QStringListIterator dictListIterator(dictList);
+ while (dictListIterator.hasNext())
+ {
+ dictName=dictListIterator.next();
+ if (!QFile::exists(dictPath+dictName+".aff"))
+ dictList.removeAll(dictName);
+ }
+ numDicts=dictList.count();
+ qDebug()<<"Number of dictionaries/AFFs found:"<<numDicts<<numAFFs;
+ if (numDicts==0)
+ ++errorCount;
+ qDebug()<<dictList;
+
+ //Initialise one hunspeller for each dictionary found
+ //Maybe we only need the text language related one later on
+ dictEntries=dictList;
+ affEntries=affList;
+ hspellers = new Hunspell* [numDicts];
+ for (int i=0; i<numDicts; ++i)
+ hspellers[i] = new Hunspell((dictPath+dictList.at(i)+".aff").toLocal8Bit().constData(),
+ (dictPath+dictList.at(i)+".dic").toLocal8Bit().constData());
+
+ return errorCount==0;
+}
+
+bool HunspellPluginImpl::checkWithHunspell()
+{
+ PageItem *frameToCheck;
+
+ for( int i = 0; i < m_doc->m_Selection->count(); ++i )
+ {
+ frameToCheck = m_doc->m_Selection->itemAt(i);
+ parseTextFrame(frameToCheck);
+ openGUIForTextFrame(frameToCheck);
+ m_doc->view()->DrawNew();
+ }
+ return true;
+}
+
+bool HunspellPluginImpl::parseTextFrame(PageItem *frameToCheck)
+{
+ static QString wordBoundaries(" .,:;\"'!?\n");
+
+ StoryText *iText=&frameToCheck->itemText;
+ int len=iText->length();
+ QString text=iText->text(0,len);
+// qDebug()<<text;
+ int wordCount=0,wordNo=0,errorCount=0;
+ int currPos=0;
+ while (currPos<len)
+ {
+ int wordPos=iText->nextWord(currPos);
+ currPos=wordPos;
+ int eoWord=wordPos;
+ while(eoWord < len)
+ {
+ if (iText->text(eoWord).isLetterOrNumber())
+ ++eoWord;
+ else
+ break;
+ }
+ QString word=iText->text(wordPos,eoWord-wordPos);
+ ++wordCount;
+ ++wordNo;
+ QStringList replacements;
+ if (hspellers[0]->spell(word.toLocal8Bit().constData())==0)
+ {
+// qDebug()<<word;
+ ++errorCount;
+ char **sugglist = NULL;
+ int suggCount=hspellers[0]->suggest(&sugglist, word.toLocal8Bit().constData());
+ for (int j=0; j < suggCount; ++j)
+ {
+// qDebug()<<"Suggestion "<<j<<":"<<sugglist[j];
+ replacements<<sugglist[j];
+ }
+ hspellers[0]->free_list(&sugglist, suggCount);
+
+ struct WordsFound wf;
+ wf.start=currPos;
+ wf.end=eoWord;
+ wf.w=word;
+ wf.replacements=replacements;
+ wf.changed=false;
+ wf.ignore=false;
+ wordsToCorrect.append(wf);
+ }
+ }
+// qDebug()<<"Errors found:"<<errorCount;
+ return true;
+}
+
+bool HunspellPluginImpl::openGUIForTextFrame(PageItem *frameToCheck)
+{
+ HunspellDialog hsDialog(m_doc->scMW(), m_doc, frameToCheck);
+ hsDialog.set(&dictEntries, hspellers, &wordsToCorrect);
+ hsDialog.exec();
+ if (hsDialog.docChanged())
+ m_doc->changed();
+ return true;
+}
+
diff --git a/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h b/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h
new file mode 100644
index 0000000..d664682
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h
@@ -0,0 +1,48 @@
+/*
+For general Scribus (>=1.3.2) copyright and licensing information please refer
+to the COPYING file provided with the program. Following this notice may exist
+a copyright and/or license notice that predates the release of Scribus 1.3.2
+for which a new license (GPL+exception) is in place.
+*/
+#ifndef HUNSPELLPLUGINIMPL_H
+#define HUNSPELLPLUGINIMPL_H
+
+#include <hunspell/hunspell.hxx>
+#include "hunspellpluginstructs.h"
+
+#include <QObject>
+#include <QString>
+#include <QStringList>
+
+class QString;
+class ScribusDoc;
+class PageItem;
+
+
+
+class HunspellPluginImpl : public QObject
+{
+ Q_OBJECT
+ public:
+ HunspellPluginImpl();
+ ~HunspellPluginImpl();
+ bool run(const QString & target, ScribusDoc* doc=0);
+ bool findDictionaries();
+ bool initHunspell();
+ bool checkWithHunspell();
+ bool parseTextFrame(PageItem *frameToCheck);
+ bool openGUIForTextFrame(PageItem *frameToCheck);
+ QList<WordsFound> wordsToCorrect;
+
+ protected:
+ QStringList dictionaryPaths;
+ QString dictPath, affPath;
+ int numDicts, numAFFs;
+ Hunspell **hspellers;
+ QStringList dictEntries;
+ QStringList affEntries;
+ ScribusDoc* m_doc;
+};
+
+#endif
+
diff --git a/scribus/plugins/tools/hunspellcheck/hunspellpluginstructs.h b/scribus/plugins/tools/hunspellcheck/hunspellpluginstructs.h
new file mode 100644
index 0000000..0515cbb
--- /dev/null
+++ b/scribus/plugins/tools/hunspellcheck/hunspellpluginstructs.h
@@ -0,0 +1,16 @@
+#ifndef HUNSPELLPLUGINSTRUCTS_H
+#define HUNSPELLPLUGINSTRUCTS_H
+
+#include <QString>
+#include <QStringList>
+
+struct WordsFound {
+ int start;
+ int end;
+ QString w;
+ QStringList replacements;
+ bool changed;
+ bool ignore;
+};
+
+#endif // HUNSPELLPLUGINSTRUCTS_H