r24041 by jghali - #14892 related: add undo support for hunspell checker plugin

scribus-commit scribus-commit at lists.scribus.net
Sat Sep 26 18:46:45 UTC 2020


Author: jghali
Date: Sat Sep 26 18:46:45 2020
New Revision: 24041

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=24041
Log:
#14892 related: add undo support for hunspell checker plugin

Modified:
    trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp
    trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.h
    trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp
    trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h
    trunk/Scribus/scribus/text/storytext.cpp
    trunk/Scribus/scribus/text/storytext.h

Modified: trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24041&path=/trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp	(original)
+++ trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.cpp	Sat Sep 26 18:46:45 2020
@@ -11,8 +11,10 @@
 
 #include "hunspelldialog.h"
 #include "langmgr.h"
-
-HunspellDialog::HunspellDialog(QWidget *parent, ScribusDoc *doc, StoryText *iText)
+#include "undomanager.h"
+#include "undotransaction.h"
+
+HunspellDialog::HunspellDialog(QWidget *parent, ScribusDoc *doc, PageItem *item)
 {
 	setupUi( this );
 	setModal( true );
@@ -25,14 +27,25 @@
 
 	m_doc = doc;
 	m_docChanged = false;
-	m_iText = iText;
-	m_returnToDefaultLang = false;
-	m_primaryLangIndex = 0;
-
-	m_dictionaryMap = nullptr;
-	m_hspellerMap = nullptr;
-	m_wfList = nullptr;
-	m_wfListIndex = 0;
+	m_item  = item;
+	m_iText = &m_item->itemText;
+}
+
+HunspellDialog::HunspellDialog(QWidget *parent, ScribusDoc *doc, StoryText *item)
+{
+	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()));
+	connect (languagesComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(languageComboChanged(const QString &)));
+
+	m_doc = doc;
+	m_docChanged = false;
+	m_item  = nullptr;
+	m_iText = &m_item->itemText;
 }
 
 void HunspellDialog::set(QMap<QString, QString>* dictionaryMap, QMap<QString, HunspellDict*> *hspellerMap, QList<WordsFound> *wfList)
@@ -132,24 +145,71 @@
 {
 	if (m_wfList->at(m_wfListIndex).ignore && !m_wfList->at(m_wfListIndex).changed)
 		return;
+
+	UndoTransaction transaction;
+	if ((m_item != nullptr) && UndoManager::undoEnabled())
+		transaction = UndoManager::instance()->beginTransaction(m_item->getUName(), m_item->getUPixmap());
+
 	QString wordToChange = m_wfList->at(m_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)
+	for (int i = 0; i < m_wfList->count(); ++i)
 		if (m_wfList->at(i).w == wordToChange)
 			replaceWord(i);
+
+	if (transaction)
+		transaction.commit();
+
 	goToNextWord();
 }
 
 void HunspellDialog::replaceWord(int i)
 {
 	//TODO: rehyphenate after the replacement
+	int replaceStart = m_wfList->at(i).start + m_wfList->at(i).changeOffset;
+	QString oldText(m_iText->word(replaceStart));
 	QString newText(suggestionsListWidget->currentItem()->text());
+
+	UndoTransaction transaction;
+	if ((m_item != nullptr) && UndoManager::undoEnabled())
+	{
+		UndoObject* undoTarget = m_item->isNoteFrame() ? dynamic_cast<UndoObject*>(m_item->doc()) : dynamic_cast<UndoObject*>(m_item);
+		transaction = UndoManager::instance()->beginTransaction(m_item->getUName(), m_item->getUPixmap());
+		if (oldText.length() > 0)
+		{
+			auto is = new ScItemState<CharStyle>(Um::DeleteText, "", Um::IDelete);
+			is->set("DELETE_FRAMETEXT");
+			is->set("ETEA",  QString("delete_frametext"));
+			is->set("TEXT_STR", oldText);
+			is->set("START", replaceStart);
+			is->setItem(m_item->itemText.charStyle(replaceStart));
+			if (m_item->isNoteFrame())
+				is->set("noteframeName", m_item->getUName());
+			UndoManager::instance()->action(undoTarget, is);
+		}
+		if (newText.length() > 0)
+		{
+			auto ss = new SimpleState(Um::InsertText, "", Um::ICreate);
+			ss->set("INSERT_FRAMETEXT");
+			ss->set("ETEA", QString("insert_frametext"));
+			ss->set("TEXT_STR", newText);
+			ss->set("START", replaceStart);
+			UndoObject * undoTarget = m_item;
+			if (m_item->isNoteFrame())
+				ss->set("noteframeName", m_item->getUName());
+			UndoManager::instance()->action(undoTarget, ss);
+		}
+	}
+
 	int lengthDiff = m_iText->replaceWord(m_wfList->at(i).start + m_wfList->at(i).changeOffset, newText);
 	if (lengthDiff != 0)
 	{
-		for (int k = i; k<m_wfList->count(); ++k)
+		for (int k = i; k < m_wfList->count(); ++k)
 			(*m_wfList)[k].changeOffset += lengthDiff;
 	}
+
+	if (transaction)
+		transaction.commit();
+
 	(*m_wfList)[i].changed = true;
 	m_docChanged = true;
 }

Modified: trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24041&path=/trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.h
==============================================================================
--- trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.h	(original)
+++ trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspelldialog.h	Sat Sep 26 18:46:45 2020
@@ -19,8 +19,10 @@
 	Q_OBJECT
 
 	public:
+		HunspellDialog(QWidget* parent, ScribusDoc *doc, PageItem* item);
 		HunspellDialog(QWidget* parent, ScribusDoc *doc, StoryText* iText);
 		~HunspellDialog() {};
+
 		void set(QMap<QString, QString>* dictionaryMap, QMap<QString, HunspellDict*> *hspellerMap, QList<WordsFound>* wfList);
 		bool docChanged() {return m_docChanged;}
 		void updateSuggestions(QStringList& newSuggestions);
@@ -35,16 +37,17 @@
 		void setLanguageCombo(const QString &newLangAbbrev);
 
 	private:
-		ScribusDoc* m_doc;
-		StoryText* m_iText;
-		QMap<QString, QString>* m_dictionaryMap;
-		QMap<QString, HunspellDict*> *m_hspellerMap;
-		QList<WordsFound>* m_wfList;
+		ScribusDoc* m_doc { nullptr };
+		PageItem*  m_item { nullptr };
+		StoryText* m_iText { nullptr };
+		QMap<QString, QString>* m_dictionaryMap { nullptr };
+		QMap<QString, HunspellDict*> *m_hspellerMap { nullptr };
+		QList<WordsFound>* m_wfList { nullptr };
 		WordsFound currWF;
-		int  m_wfListIndex;
-		bool m_docChanged;
-		bool m_returnToDefaultLang;
-		int m_primaryLangIndex;
+		int  m_wfListIndex { 0 };
+		bool m_docChanged { false };
+		bool m_returnToDefaultLang { false };
+		int m_primaryLangIndex { 0 };
 };
 
 #endif // HUNSPELLDIALOG_H

Modified: trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24041&path=/trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp	(original)
+++ trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.cpp	Sat Sep 26 18:46:45 2020
@@ -33,10 +33,9 @@
 // Initialize members here, if any
 HunspellPluginImpl::HunspellPluginImpl() : QObject(nullptr)
 {
-//	numDicts=0;
-	m_doc=nullptr;
-	m_runningForSE=false;
-	m_SE=nullptr;
+	m_doc = nullptr;
+	m_runningForSE = false;
+	m_SE = nullptr;
 }
 
 HunspellPluginImpl::~HunspellPluginImpl()
@@ -47,26 +46,25 @@
 		h = nullptr;
 	}
 	hspellerMap.clear();
-//	numDicts = 0;
 }
 
 bool HunspellPluginImpl::run(const QString & target, ScribusDoc* doc)
 {
-	m_doc=doc;
-	bool initOk=initHunspell();
+	m_doc = doc;
+	bool initOk = initHunspell();
 	if (!initOk)
 		return false;
-	bool spellCheckOk=false;
+	bool spellCheckOk = false;
 	if (m_runningForSE)
-		spellCheckOk=checkWithHunspellSE();
+		spellCheckOk = checkWithHunspellSE();
 	else
-		spellCheckOk=checkWithHunspell();
+		spellCheckOk = checkWithHunspell();
 	return spellCheckOk;
 }
 
 bool HunspellPluginImpl::initHunspell()
 {
-	bool dictPathFound=LanguageManager::instance()->findSpellingDictionaries(dictionaryPaths);
+	bool dictPathFound = LanguageManager::instance()->findSpellingDictionaries(dictionaryPaths);
 	if (!dictPathFound)
 	{
 		qDebug()<<"No preinstalled dictonary paths found";
@@ -74,16 +72,15 @@
 	}
 	dictionaryMap.clear();
 	LanguageManager::instance()->findSpellingDictionarySets(dictionaryPaths, dictionaryMap);
-//	numDicts=dictionaryMap.count();
-	if (dictionaryMap.count()==0)
+	if (dictionaryMap.count() == 0)
 		return false;
 
 	//Initialise one hunspeller for each dictionary found
 	auto it = dictionaryMap.cbegin();
 	while (it != dictionaryMap.cend())
 	{
-		//qDebug()<<"hunspell init:"<<it.key()<<it.value();
-		hspellerMap.insert(it.key(), new HunspellDict(it.value()+".aff", it.value()+".dic"));
+		//qDebug() << "hunspell init:" << it.key() << it.value();
+		hspellerMap.insert(it.key(), new HunspellDict(it.value() + ".aff", it.value() + ".dic"));
 		++it;
 	}
 	return true;
@@ -96,9 +93,9 @@
 	for (int i = 0; i < m_doc->m_Selection->count(); ++i)
 	{
 		frameToCheck = m_doc->m_Selection->itemAt(i);
-		StoryText *iText=&frameToCheck->itemText;
+		StoryText *iText = &frameToCheck->itemText;
 		parseTextFrame(iText);
-		openGUIForTextFrame(iText);
+		openGUIForTextFrame(frameToCheck);
 		m_doc->view()->DrawNew();
 	}
 	return true;
@@ -141,24 +138,24 @@
 				wordLang = defaultStyle->language();
 		}
 		//we now use the abbreviation
-		//wordLang=LanguageManager::instance()->getAbbrevFromLang(wordLang, true, false);
+		//wordLang = LanguageManager::instance()->getAbbrevFromLang(wordLang, true, false);
 		//A little hack as for some reason our en dictionary from the aspell plugin was not called en_GB or en_US but en, content was en_GB though. Meh.
 		if (wordLang == "en")
 			wordLang = "en_GB";
-		//qDebug()<<"Word:"<<word<<wordLang;
+		//qDebug() << "Word:" << word << wordLang;
 		if (!dictionaryMap.contains(wordLang))
 		{
-			//qDebug()<<"Spelling language to match style language NOT installed ("<<wordLang<<")";
+			//qDebug() << "Spelling language to match style language NOT installed (" << wordLang << ")";
 			QString altLang = LanguageManager::instance()->getAlternativeAbbrevfromAbbrev(wordLang);
 			if (!altLang.isEmpty())
 			{
-				//qDebug()<<"altLang"<<altLang<<dictionaryMap.contains(altLang);
+				//qDebug() << "altLang" << altLang << dictionaryMap.contains(altLang);
 				wordLang = altLang;
 			}
 		}
 		else
 		{
-			//qDebug()<<"Spelling language to match style language IS installed ("<<wordLang<<")";
+			//qDebug() << "Spelling language to match style language IS installed (" << wordLang << ")";
 			int i = 0;
 			auto it = dictionaryMap.cbegin();
 			while (it != dictionaryMap.cend())
@@ -172,14 +169,14 @@
 
 		if (hspellerMap.contains(wordLang) && hspellerMap[wordLang]->spell(word)==0)
 		{
-			//qDebug()<<"hspellerMap.contains(wordLang)"<<hspellerMap.contains(wordLang)<< "hspellerMap[wordLang]->spell(word)"<<hspellerMap[wordLang]->spell(word);
+			//qDebug() << "hspellerMap.contains(wordLang)" << hspellerMap.contains(wordLang) << "hspellerMap[wordLang]->spell(word)" << hspellerMap[wordLang]->spell(word);
 			struct WordsFound wf;
-			wf.start=wordStart;
-			wf.end=wordEnd;
-			wf.w=word;
-			wf.changed=false;
-			wf.ignore=false;
-			wf.changeOffset=0;
+			wf.start = wordStart;
+			wf.end = wordEnd;
+			wf.w = word;
+			wf.changed = false;
+			wf.ignore = false;
+			wf.changeOffset = 0;
 			wf.lang = wordLang;
 			wf.replacements = hspellerMap[wordLang]->suggest(word);
 			wordsToCorrect.append(wf);
@@ -189,9 +186,9 @@
 	return true;
 }
 
-bool HunspellPluginImpl::openGUIForTextFrame(StoryText *iText)
-{
-	HunspellDialog hsDialog(m_doc->scMW(), m_doc, iText);
+bool HunspellPluginImpl::openGUIForTextFrame(PageItem *item)
+{
+	HunspellDialog hsDialog(m_doc->scMW(), m_doc, item);
 	hsDialog.set(&dictionaryMap, &hspellerMap, &wordsToCorrect);
 	hsDialog.exec();
 	if (hsDialog.docChanged())
@@ -211,7 +208,7 @@
 
 void HunspellPluginImpl::setRunningForSE(bool rfSE, StoryEditor *sE)
 {
-	m_runningForSE=rfSE;
-	m_SE=sE;
-}
-
+	m_runningForSE = rfSE;
+	m_SE = sE;
+}
+

Modified: trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24041&path=/trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h
==============================================================================
--- trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h	(original)
+++ trunk/Scribus/scribus/plugins/tools/hunspellcheck/hunspellpluginimpl.h	Sat Sep 26 18:46:45 2020
@@ -21,20 +21,19 @@
 class StoryText;
 class StoryEditor;
 
-
-
 class HunspellPluginImpl : public QObject
 {
 	Q_OBJECT
 	public:
 		HunspellPluginImpl();
 		~HunspellPluginImpl();
+
 		bool run(const QString & target, ScribusDoc* doc=0);
 		bool initHunspell();
 		bool checkWithHunspell();
 		bool checkWithHunspellSE();
 		bool parseTextFrame(StoryText *);
-		bool openGUIForTextFrame(StoryText *iText);
+		bool openGUIForTextFrame(PageItem *iText);
 		bool openGUIForStoryEditor(StoryText *iText);
 		void setRunningForSE(bool rfSE, StoryEditor *sE);
 		QList<WordsFound> wordsToCorrect;
@@ -42,11 +41,10 @@
 	protected:
 		QMap<QString, QString> dictionaryMap;
 		QStringList dictionaryPaths;
-		//int numDicts, numAFFs;
 		QMap<QString, HunspellDict*> hspellerMap;
-		ScribusDoc* m_doc;
-		bool m_runningForSE;
-		StoryEditor* m_SE;
+		ScribusDoc* m_doc { nullptr };
+		bool m_runningForSE { false };
+		StoryEditor* m_SE { nullptr };
 };
 
 #endif

Modified: trunk/Scribus/scribus/text/storytext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24041&path=/trunk/Scribus/scribus/text/storytext.cpp
==============================================================================
--- trunk/Scribus/scribus/text/storytext.cpp	(original)
+++ trunk/Scribus/scribus/text/storytext.cpp	Sat Sep 26 18:46:45 2020
@@ -846,15 +846,7 @@
 
 int StoryText::replaceWord(int pos, QString newWord)
 {
-	int eoWord = pos;
-	while (eoWord < length())
-	{
-		if (text(eoWord).isLetterOrNumber() || SpecialChars::isIgnorableCodePoint(text(eoWord).unicode()))
-			++eoWord;
-		else
-			break;
-	}
-	QString word = text(pos, eoWord - pos);
+	QString word = this->word(pos);
 	int lengthDiff = newWord.length() - word.length();
 	if (lengthDiff == 0)
 	{
@@ -1058,9 +1050,22 @@
 QString StoryText::sentence(int pos, int &posn)
 {
 	int sentencePos = qMax(0, prevSentence(pos));
-	posn=sentencePos;
+	posn = sentencePos;
 	int nextSentencePos = qMin(length(), endOfSentence(pos));
-	return text(sentencePos, nextSentencePos-sentencePos);
+	return text(sentencePos, nextSentencePos - sentencePos);
+}
+
+QString StoryText::word(int pos)
+{
+	int eoWord = pos;
+	while (eoWord < length())
+	{
+		if (text(eoWord).isLetterOrNumber() || SpecialChars::isIgnorableCodePoint(text(eoWord).unicode()))
+			++eoWord;
+		else
+			break;
+	}
+	return text(pos, eoWord - pos);
 }
 
 QString StoryText::textWithSoftHyphens(int pos, uint len) const

Modified: trunk/Scribus/scribus/text/storytext.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=24041&path=/trunk/Scribus/scribus/text/storytext.h
==============================================================================
--- trunk/Scribus/scribus/text/storytext.h	(original)
+++ trunk/Scribus/scribus/text/storytext.h	Sat Sep 26 18:46:45 2020
@@ -167,8 +167,10 @@
  	QChar   text(int pos) const;
 	// Get text with len chars at specific position
 	QString text(int pos, uint len) const;
- 	//Get sentence at any position within it
+ 	// Get sentence at any position within it
 	QString sentence(int pos, int &posn);
+	// Get word starting at position
+	QString word(int pos);
 
 	bool hasObject(int pos) const;
 	PageItem* getItem(int pos) const; // deprecated




More information about the scribus-commit mailing list