1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /***************************************************************************
8 						  story.cpp  -  description
9 							 -------------------
10 	begin			   : Tue Nov 11 2003
11 	copyright		   : (C) 2003 by Franz Schmid
12 	email			   : Franz.Schmid@altmuehlnet.de
13  ***************************************************************************/
14 
15 /***************************************************************************
16  *																	   *
17  *   This program is free software; you can redistribute it and/or modify  *
18  *   it under the terms of the GNU General Public License as published by  *
19  *   the Free Software Foundation; either version 2 of the License, or   *
20  *   (at your option) any later version.								   *
21  *																	   *
22  ***************************************************************************/
23 
24 #include <QApplication>
25 #include <QCloseEvent>
26 #include <QColorDialog>
27 #include <QComboBox>
28 #include <QCursor>
29 #include <QDesktopWidget>
30 #include <QEvent>
31 #include <QFocusEvent>
32 #include <QFontDialog>
33 #include <QFrame>
34 #include <QGridLayout>
35 #include <QHBoxLayout>
36 #include <QHideEvent>
37 #include <QKeyEvent>
38 #include <QLabel>
39 #include <QList>
40 #include <QMessageBox>
41 #include <QMouseEvent>
42 #include <QPaintEvent>
43 #include <QPair>
44 #include <QPalette>
45 #include <QPixmap>
46 #include <QRegExp>
47 #include <QScopedPointer>
48 #include <QScopedValueRollback>
49 #include <QScreen>
50 #include <QScrollBar>
51 #include <QShowEvent>
52 #include <QSignalBlocker>
53 #include <QTextBlock>
54 #include <QTextCodec>
55 #include <QTextLayout>
56 #include <QToolTip>
57 
58 #include "actionmanager.h"
59 #include "alignselect.h"
60 #include "directionselect.h"
61 #include "colorcombo.h"
62 #include "colorlistbox.h"
63 #include "commonstrings.h"
64 #include "fontcombo.h"
65 #include "iconmanager.h"
66 #include "loremipsum.h"
67 #include "menumanager.h"
68 #include "pageitem.h"
69 #include "pageitem_textframe.h"
70 #include "pluginmanager.h"
71 #include "prefscontext.h"
72 #include "prefsfile.h"
73 #include "prefsmanager.h"
74 #include "scfonts.h"
75 #include "scplugin.h"
76 #include "scraction.h"
77 #include "scribusapp.h"
78 #include "scribuscore.h"
79 #include "scribusview.h"
80 #include "scrspinbox.h"
81 #include "search.h"
82 #include "serializer.h"
83 #include "shadebutton.h"
84 #include "storyeditor.h"
85 #include "styleitem.h"
86 #include "styleselect.h"
87 #include "ui/charselect.h"
88 #include "ui/customfdialog.h"
89 #include "ui/scmessagebox.h"
90 #include "ui/stylecombos.h"
91 #include "ui/stylemanager.h"
92 #include "units.h"
93 #include "util.h"
94 #include "util_debug.h"
95 
96 
97 class StyledTextMimeData : public QMimeData
98 {
99 protected:
100 	StoryText   m_styledText;
101 	ScGuardedPtr<ScribusDoc> m_styledTextDoc;
102 
103 public:
styledText() const104 	const StoryText&  styledText() const { return m_styledText; }
document() const105 	const ScribusDoc* document()   const { return m_styledTextDoc; }
106 
setStyledText(const StoryText & text,ScribusDoc * doc)107 	void  setStyledText(const StoryText& text, ScribusDoc* doc)
108 	{
109 		QByteArray styledTextData (sizeof(void*), 0);
110 		m_styledText = StoryText(doc);
111 		m_styledText.setDefaultStyle(text.defaultStyle());
112 		m_styledText.insert(0, text, true);
113 		m_styledTextDoc = doc->guardedPtr();
114 		styledTextData.setNum((quintptr)((quintptr*) &m_styledText));
115 		setData("application/x-scribus-styledtext", styledTextData);
116 	};
117 };
118 
SideBar(QWidget * pa)119 SideBar::SideBar(QWidget *pa) : QLabel(pa)
120 {
121 	QPalette pal;
122 	pal.setColor(QPalette::Window, QColor(255,255,255));
123 	setAutoFillBackground(true);
124 	setPalette(pal);
125 	pmen = new QMenu(this);
126 	setMinimumWidth(fontMetrics().horizontalAdvance( tr("No Style") )+30);
127 }
128 
setEditor(SEditor * editor)129 void SideBar::setEditor(SEditor* editor)
130 {
131 	m_editor = editor;
132 	if (!editor)
133 		return;
134 	QPalette pal;
135 	pal.setColor(QPalette::Window, editor->palette().color(QPalette::Base));
136 	setPalette(pal);
137 }
138 
mouseReleaseEvent(QMouseEvent * m)139 void SideBar::mouseReleaseEvent(QMouseEvent *m)
140 {
141 	QPoint globalPos = m->globalPos();
142 	QPoint viewPos   = m_editor->viewport()->mapFromGlobal(globalPos);
143 	int p = m_editor->cursorForPosition(QPoint(2, viewPos.y())).position();
144 	currentPar = m_editor->StyledText.nrOfParagraph(p);
145 	int pos = m_editor->StyledText.startOfParagraph(m_editor->StyledText.nrOfParagraph(p));
146 
147 	pmen->clear();
148 
149 	QString styleName = "";
150 	ParaStyleComboBox* paraStyleCombo = new ParaStyleComboBox(pmen);
151 	paraStyleCombo->setDoc(m_editor->doc);
152 	if ((currentPar < static_cast<int>(m_editor->StyledText.nrOfParagraphs())) && (m_editor->StyledText.length() != 0))
153 	{
154 		int len = m_editor->StyledText.endOfParagraph(currentPar) - m_editor->StyledText.startOfParagraph(currentPar);
155 		if (len > 0)
156 			styleName = m_editor->StyledText.paragraphStyle(pos).parent(); //FIXME ParaStyleComboBox and use localized style name
157 	}
158 	paraStyleCombo->setStyle(styleName);
159 	connect(paraStyleCombo, SIGNAL(newStyle(const QString&)), this, SLOT(setPStyle(const QString&)));
160 
161 	paraStyleAct = new QWidgetAction(pmen);
162 	paraStyleAct->setDefaultWidget(paraStyleCombo);
163 	pmen->addAction(paraStyleAct);
164 	pmen->exec(QCursor::pos());
165 }
166 
167 //void SideBar::editStyles()
168 //{
169 //	emit sigEditStyles();
170 //}
171 
setPStyle(const QString & name)172 void SideBar::setPStyle(const QString& name)
173 {
174 	emit ChangeStyle(currentPar, name);
175 	pmen->close();
176 }
177 
paintEvent(QPaintEvent * e)178 void SideBar::paintEvent(QPaintEvent *e)
179 {
180 	inRep = true;
181 	QLabel::paintEvent(e);
182 
183 	QPair<int, int> paraInfo;
184 	QList< QPair<int,int> > paraList;
185 	if (m_editor != nullptr)
186 	{
187 		QRect  edRect = m_editor->viewport()->rect();
188 		QPoint pt1 = edRect.topLeft(), pt2 = edRect.bottomRight();
189 		QTextCursor cur1 = m_editor->cursorForPosition(pt1);
190 		QTextCursor cur2 = m_editor->cursorForPosition(pt2);
191 		int pos1 = cur1.position(), pos2 = cur2.position();
192 		pos1 = m_editor->StyledText.prevParagraph(pos1);
193 		pos1 = (pos1 == 0) ? 0 : (pos1 + 1);
194 		pos2 = m_editor->StyledText.nextParagraph(pos2);
195 		while ((pos1 <= pos2) && (pos1 < m_editor->StyledText.length()))
196 		{
197 			paraInfo.first = pos1;
198 			if (m_editor->StyledText.text(pos1) == SpecialChars::PARSEP)
199 			{
200 				paraInfo.second = pos1;
201 				pos1 += 1;
202 			}
203 			else
204 			{
205 				pos1 = m_editor->StyledText.nextParagraph(pos1) + 1;
206 				paraInfo.second = qMax(0, qMin(pos1 - 1, m_editor->StyledText.length() - 1));
207 			}
208 			paraList.append(paraInfo);
209 		}
210 	}
211 
212 	QPainter p;
213 	p.begin(this);
214 	if ((m_editor != nullptr) && (noUpdt))
215 	{
216 		QString trNoStyle = tr("No Style");
217 		for (int pa = 0; pa < paraList.count(); ++pa)
218 		{
219 			QPair<int,int> paraInfo = paraList[pa];
220 			// Draw paragraph style name first
221 			QTextCursor cur(m_editor->document());
222 			cur.setPosition(paraInfo.first);
223 			QTextBlock blockStart = cur.block();
224 			QTextLine  lineStart  = blockStart.layout()->lineForTextPosition(paraInfo.first - blockStart.position());
225 			if (lineStart.isValid())
226 			{
227 				QPointF blockPos = blockStart.layout()->position();
228 				QRect re = lineStart.rect().translated(0, blockPos.y()).toRect();
229 				re.setWidth(width() - 5);
230 				re.setHeight(re.height() - 2);
231 				re.translate(5, 2 - offs);
232 				if ((re.top() < height()) && (re.top() >= 0))
233 				{
234 					QString parname = m_editor->StyledText.paragraphStyle(paraInfo.first).parent();
235 					if (parname.isEmpty())
236 						parname = trNoStyle;
237 					p.drawText(re, Qt::AlignLeft | Qt::AlignTop, parname);
238 				}
239 			}
240 			// Draw paragraph separation line
241 			cur.setPosition(paraInfo.second);
242 			QTextBlock blockEnd = cur.block();
243 			QTextLine  lineEnd  = blockEnd.layout()->lineForTextPosition(paraInfo.second - blockEnd.position());
244 			if (lineEnd.isValid())
245 			{
246 				QPointF blockPos = blockEnd.layout()->position();
247 				QRect re = lineEnd.rect().translated(0, 2 + blockPos.y()).toRect();
248 				if ((re.bottom() - offs < height()) && (re.bottom() - offs >= 0))
249 					p.drawLine(0, re.bottom() - offs, width() - 1, re.bottom() - offs);
250 			}
251 		}
252 	}
253 	p.end();
254 
255 	inRep = false;
256 }
257 
doMove(int,int y)258 void SideBar::doMove(int, int y)
259 {
260 	offs -= y;
261 	if (!inRep)
262 		update();
263 }
264 
doRepaint()265 void SideBar::doRepaint()
266 {
267 	if (!inRep)
268 		update();
269 }
270 
setRepaint(bool r)271 void SideBar::setRepaint(bool r)
272 {
273 	noUpdt = r;
274 }
275 
SEditor(QWidget * parent,ScribusDoc * docc,StoryEditor * parentSE)276 SEditor::SEditor(QWidget* parent, ScribusDoc *docc, StoryEditor* parentSE) :
277 		QTextEdit(parent),
278 		parentStoryEditor(parentSE)
279 {
280 	setCurrentDocument(docc);
281 	document()->setUndoRedoEnabled(true);
282 	viewport()->setAcceptDrops(false);
283 	setAutoFillBackground(true);
284 	connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(ClipChange()));
285 	connect(this->document(), SIGNAL(contentsChange(int, int, int)), this, SLOT(handleContentsChange(int, int, int)));
286 }
287 
setCurrentDocument(ScribusDoc * docc)288 void SEditor::setCurrentDocument(ScribusDoc *docc)
289 {
290 	doc = docc;
291 	StyledText = StoryText(docc);
292 }
293 
inputMethodEvent(QInputMethodEvent * event)294 void SEditor::inputMethodEvent(QInputMethodEvent *event)
295 {
296 	QString uc = event->commitString();
297 	SuspendContentsChange = 1;	// prevent our handler from doing anything
298 	bool changed = false;
299 	int pos;
300 	if (textCursor().hasSelection())
301 	{
302 		pos =  textCursor().selectionStart();
303 		StyledText.removeChars(pos, textCursor().selectionEnd() - pos);
304 		changed = true;
305 	}
306 	pos = -1;
307 	if (!uc.isEmpty())
308 	{
309 		pos = textCursor().hasSelection() ? textCursor().selectionStart() : textCursor().position();
310 		pos = qMin(pos, StyledText.length());
311 	}
312 	QTextEdit::inputMethodEvent(event);
313 	SuspendContentsChange = 0;
314 	if (pos >= 0)
315 	{
316 		handleContentsChange(pos, 0, uc.length());
317 		changed = true;
318 	}
319 	if (changed)
320 	{
321 		emit SideBarUp(true);
322 		emit SideBarUpdate();
323 	}
324 }
325 
keyPressEvent(QKeyEvent * k)326 void SEditor::keyPressEvent(QKeyEvent *k)
327 {
328 	emit SideBarUp(false);
329 
330 	if (ScCore->primaryMainWindow()->actionManager->compareKeySeqToShortcut(k->key(), k->modifiers(), "specialUnicodeSequenceBegin"))
331 	{
332 		unicodeTextEditMode = true;
333 		unicodeInputCount = 0;
334 		unicodeInputString = "";
335 		return;
336 	}
337 
338 //	QString uc = k->text();
339 	if ((k->modifiers() == Qt::ControlModifier) ||
340 		(k->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) ||
341 		(k->modifiers() == (Qt::ControlModifier | Qt::KeypadModifier)) ||
342 		(k->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier | Qt::KeypadModifier))
343 	   )
344 	{
345 		bool processed = false;
346 		switch (k->key())
347 		{
348 			case Qt::Key_K:
349 				moveCursor(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
350 				textCursor().removeSelectedText();
351 				processed = true;
352 				break;
353 			case Qt::Key_D:
354 				moveCursor(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
355 				textCursor().removeSelectedText();
356 				processed = true;
357 				break;
358 			case Qt::Key_H:
359 				moveCursor(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
360 				textCursor().removeSelectedText();
361 				processed = true;
362 				break;
363 			case Qt::Key_Y:
364 			case Qt::Key_Z:
365 				emit SideBarUp(true);
366 				return;
367 		}
368 		if (processed)
369 		{
370 			emit SideBarUp(true);
371 			emit SideBarUpdate();
372 			return;
373 		}
374 	}
375 	if ((k->modifiers() == Qt::NoModifier) ||
376 		(k->modifiers() == Qt::KeypadModifier) ||
377 		(k->modifiers() == Qt::ShiftModifier) ||
378 		(k->modifiers() == (Qt::ControlModifier | Qt::AltModifier)) ||
379 		(k->modifiers() == (Qt::ControlModifier | Qt::AltModifier | Qt::ShiftModifier)) // Shift + AltGr on Windows for polish characters
380 	   )
381 	{
382 		if (unicodeTextEditMode)
383 		{
384 			int conv = 0;
385 			bool ok = false;
386 			unicodeInputString += k->text();
387 			conv = unicodeInputString.toInt(&ok, 16);
388 			if (!ok)
389 			{
390 				unicodeTextEditMode = false;
391 				unicodeInputCount = 0;
392 				unicodeInputString = "";
393 				return;
394 			}
395 			unicodeInputCount++;
396 			if (unicodeInputCount == 4)
397 			{
398 				unicodeTextEditMode = false;
399 				unicodeInputCount = 0;
400 				unicodeInputString = "";
401 				if (ok)
402 				{
403 					if (conv < 31)
404 						conv = 32;
405 					insertPlainText(QString(QChar(conv)));
406 					emit SideBarUp(true);
407 					emit SideBarUpdate();
408 					return;
409 				}
410 			}
411 			else
412 			{
413 				emit SideBarUp(true);
414 				emit SideBarUpdate();
415 				return;
416 			}
417 		}
418 		wasMod = false;
419 		switch (k->key())
420 		{
421 			case Qt::Key_Escape:
422 				k->ignore();
423 				break;
424 			case Qt::Key_Shift:
425 			case Qt::Key_Control:
426 			case Qt::Key_Alt:
427 				wasMod = true;
428 				break;
429 			case Qt::Key_Return:
430 			case Qt::Key_Enter:
431 				if (k->modifiers() == Qt::ShiftModifier)
432 					insertChars(SpecialChars::LINEBREAK, k->text());
433 				else
434 					insertChars(SpecialChars::PARSEP, k->text());
435 				emit SideBarUp(true);
436 				emit SideBarUpdate();
437 				return;
438 				break;
439 			case Qt::Key_Delete:
440 			case Qt::Key_Backspace:
441 			case Qt::Key_Left:
442 			case Qt::Key_Right:
443 			case Qt::Key_PageUp:
444 			case Qt::Key_PageDown:
445 			case Qt::Key_Up:
446 			case Qt::Key_Down:
447 			case Qt::Key_Home:
448 			case Qt::Key_End:
449 				break;
450 			default:
451 				if (!k->text().isEmpty())
452 				{
453 					QTextEdit::keyPressEvent(k);
454 					emit SideBarUp(true);
455 					emit SideBarUpdate();
456 				}
457 				return;
458 				break;
459 		}
460 	}
461 	QTextEdit::keyPressEvent(k);
462 	emit SideBarUp(true);
463 	emit SideBarUpdate();
464 }
465 
handleContentsChange(int position,int charsRemoved,int charsAdded)466 void SEditor::handleContentsChange(int position, int charsRemoved, int charsAdded)
467 {
468 	// As of Qt 4.7.4, Cococa-QTextEdit output of input method is broken.
469 	// We need a workaround to avoit the bug.
470 	if (SuspendContentsChange != 0)
471 		return;
472 	if (blockContentsChangeHook <= 0)
473 	{
474 		if (charsRemoved > 0 && StyledText.length() > 0)
475 			StyledText.removeChars(position, charsRemoved);
476 		if (charsAdded > 0)
477 		{
478 			QTextCursor cursor = textCursor();
479 			cursor.setPosition(position);
480 			cursor.setPosition(position + charsAdded, QTextCursor::KeepAnchor);
481 			QString addedChars = cursor.selectedText();
482 			if (addedChars.length() > 0)
483 			{
484 				addedChars.replace(QString(0x2029), SpecialChars::PARSEP);
485 				StyledText.insertChars(position, addedChars, true);
486 			}
487 			//qDebug("handleContentsChange : - %01d, + %01d, len %01d", charsRemoved, charsAdded, addedChars.length());
488 		}
489 	}
490 }
491 
focusOutEvent(QFocusEvent * e)492 void SEditor::focusOutEvent(QFocusEvent *e)
493 {
494 	QTextCursor tc(textCursor());
495 	if (tc.hasSelection())
496 	{
497 		auto selTuple = std::make_tuple(tc.selectionStart(), tc.selectionEnd(), verticalScrollBar()->value());
498 		SelStack.push(selTuple);
499 	}
500 	else
501 	{
502 		auto selTuple = std::make_tuple(tc.position(), -1, verticalScrollBar()->value());
503 		SelStack.push(selTuple);
504 	}
505 	QTextEdit::focusOutEvent(e);
506 }
507 
focusInEvent(QFocusEvent * e)508 void SEditor::focusInEvent(QFocusEvent *e)
509 {
510 	if (SelStack.count() > 0)
511 	{
512 		QTextCursor tc(textCursor());
513 		int selFirst, selSecond, selThird;
514 		std::tie(selFirst, selSecond, selThird) = SelStack.pop();
515 		tc.setPosition(qMin(selFirst, StyledText.length()));
516 		if (selSecond >= 0)
517 			tc.setPosition(selSecond, QTextCursor::KeepAnchor);
518 		setTextCursor(tc);
519 		verticalScrollBar()->setValue(selThird);
520 	}
521 	QTextEdit::focusInEvent(e);
522 }
523 
insertChars(const QString & text)524 void SEditor::insertChars(const QString& text)
525 {
526 	QTextCursor cursor = textCursor();
527 	if (cursor.hasSelection())
528 		cursor.removeSelectedText();
529 	++blockContentsChangeHook;
530 	QTextCursor c(textCursor());
531 	int pos = qMin(c.position(), StyledText.length());
532 	StyledText.insertChars(pos, text, true);
533 // 	insertPlainText(text);
534 	insertUpdate(pos, text.length());
535 	c.setPosition(pos + text.length());
536 	setTextCursor(c);
537 	setColor(false); // HACK to force normal edit color
538 	--blockContentsChangeHook;
539 }
540 
insertChars(const QString & styledText,const QString & editText)541 void SEditor::insertChars(const QString& styledText, const QString& editText)
542 {
543 	if ((styledText.length() == editText.length()) && !styledText.isEmpty())
544 	{
545 		QTextCursor cursor1 = textCursor();
546 		if (cursor1.hasSelection())
547 			cursor1.removeSelectedText();
548 
549 		++blockContentsChangeHook;
550 		QTextCursor cursor2 = textCursor();
551 		int pos = qMin(cursor2.position(), StyledText.length());
552 		StyledText.insertChars(pos, styledText, true);
553  		insertPlainText(editText);
554 		cursor2.setPosition(pos + editText.length());
555 		setTextCursor(cursor2);
556 		--blockContentsChangeHook;
557 	}
558 }
559 
insertCharsInternal(const QString & t)560 void SEditor::insertCharsInternal(const QString& t)
561 {
562 	if (textCursor().hasSelection())
563 		deleteSel();
564 	QTextCursor cursor = textCursor();
565 	int pos = cursor.hasSelection() ? cursor.selectionStart() : cursor.position();
566 	pos = qMin(pos, StyledText.length());
567 	insertCharsInternal(t, pos);
568 }
569 
insertCharsInternal(const QString & t,int pos)570 void SEditor::insertCharsInternal(const QString& t, int pos)
571 {
572 	QTextCursor cursor = textCursor();
573 	if (cursor.hasSelection())
574 		cursor.removeSelectedText();
575 	int oldLength = StyledText.length();
576 	StyledText.insertChars(pos, t, true);
577 	int newLength = StyledText.length();
578 	insertUpdate(pos, newLength - oldLength);
579 }
580 
insertStyledText(const StoryText & styledText)581 void SEditor::insertStyledText(const StoryText& styledText)
582 {
583 	if (styledText.length() == 0)
584 		return;
585 	QTextCursor cursor = textCursor();
586 	int pos = cursor.hasSelection() ? cursor.selectionStart() : cursor.position();
587 	pos = qMin(pos, StyledText.length());
588 	insertStyledText(styledText, pos);
589 }
590 
insertStyledText(const StoryText & styledText,int pos)591 void SEditor::insertStyledText(const StoryText& styledText, int pos)
592 {
593 	if (styledText.length() == 0)
594 		return;
595 	QTextCursor cursor = textCursor();
596 	if (cursor.hasSelection())
597 		cursor.removeSelectedText();
598 	int oldLength = StyledText.length();
599 	StyledText.insert(pos, styledText);
600 	int newLength = StyledText.length();
601 	insertUpdate(pos, newLength - oldLength);
602 }
603 
saveItemText(PageItem * currItem)604 void SEditor::saveItemText(PageItem *currItem)
605 {
606 	currItem->itemText.clear();
607 	currItem->itemText.setDefaultStyle(StyledText.defaultStyle());
608 	currItem->itemText.append(StyledText);
609 /* uh... FIXME
610 		if (ch == SpecialChars::OBJECT)
611 			{
612 				PageItem* embedded = chars->at(c)->cembedded;
613 				currItem->doc()->FrameItems.append(embedded);
614 				if (embedded->Groups.count() != 0)
615 				{
616 					for (uint ga=0; ga<FrameItems.count(); ++ga)
617 					{
618 						if (FrameItems.at(ga)->Groups.count() != 0)
619 						{
620 							if (FrameItems.at(ga)->Groups.top() == embedded->Groups.top())
621 							{
622 								if (FrameItems.at(ga)->ItemNr != embedded->ItemNr)
623 								{
624 									if (currItem->doc()->FrameItems.find(FrameItems.at(ga)) == -1)
625 										currItem->doc()->FrameItems.append(FrameItems.at(ga));
626 								}
627 							}
628 						}
629 					}
630 				}
631 				currItem->itemText.insertObject(pos, embedded);
632 			}
633 */
634 }
635 
setAlign(int align)636 void SEditor::setAlign(int align)
637 {
638 	QTextCursor tCursor = this->textCursor();
639 	setAlign(tCursor, align);
640 }
641 
setAlign(QTextCursor & tCursor,int align)642 void SEditor::setAlign(QTextCursor& tCursor, int align)
643 {
644 	++blockContentsChangeHook;
645 	QTextBlockFormat blockFormat = tCursor.blockFormat();
646 	switch (align)
647 	{
648 	case 0:
649 		blockFormat.setAlignment(Qt::AlignLeft);
650 		break;
651 	case 1:
652 		blockFormat.setAlignment(Qt::AlignCenter);
653 		break;
654 	case 2:
655 		blockFormat.setAlignment(Qt::AlignRight);
656 		break;
657 	case 3:
658 	case 4:
659 		blockFormat.setAlignment(Qt::AlignJustify);
660 		break;
661 	default:
662 		break;
663 	}
664 	tCursor.mergeBlockFormat(blockFormat);
665 	--blockContentsChangeHook;
666 }
667 
setDirection(int dir)668 void SEditor::setDirection(int dir)
669 {
670 	QTextCursor tCursor = this->textCursor();
671 	setDirection(tCursor, dir);
672 }
673 
setDirection(QTextCursor & tCursor,int dir)674 void SEditor::setDirection(QTextCursor& tCursor, int dir)
675 {
676 	++blockContentsChangeHook;
677 	QTextBlockFormat blockFormat = tCursor.blockFormat();
678 	switch (dir)
679 	{
680 	case 0:
681 		blockFormat.setLayoutDirection(Qt::LeftToRight);
682 		break;
683 	case 1:
684 		blockFormat.setLayoutDirection(Qt::RightToLeft);
685 		break;
686 	default:
687 		break;
688 	}
689 	tCursor.mergeBlockFormat(blockFormat);
690 	--blockContentsChangeHook;
691 }
692 
loadItemText(PageItem * currItem)693 void SEditor::loadItemText(PageItem *currItem)
694 {
695 	setTextColor(Qt::black);
696 	FrameItems.clear();
697 	StyledText = StoryText(currItem->doc());
698 	StyledText.setDefaultStyle(currItem->itemText.defaultStyle());
699 	StyledText.append(currItem->itemText);
700 	updateAll();
701 	int npars = currItem->itemText.nrOfParagraphs();
702 	int newSelParaStart = 0;
703 	while (currItem->itemText.cursorPosition() >= (SelCharStart = currItem->itemText.endOfParagraph(newSelParaStart)) && newSelParaStart < npars)
704 		++newSelParaStart;
705 	if (currItem->itemText.cursorPosition() < SelCharStart)
706 		SelCharStart = currItem->itemText.cursorPosition();
707 	SelCharStart -= currItem->itemText.startOfParagraph(newSelParaStart);
708 	if (!SelStack.isEmpty())
709 		std::get<1>(SelStack.top()) = -1;
710 	//qDebug() << "SE::loadItemText: cursor";
711 //	setCursorPosition(SelParaStart, SelCharStart);
712 	emit setProps(newSelParaStart, SelCharStart);
713 	//SelParaStart = 0;
714 }
715 
loadText(const QString & tx,PageItem * currItem)716 void SEditor::loadText(const QString& tx, PageItem *currItem)
717 {
718 	setTextColor(Qt::black);
719 	setUpdatesEnabled(false);
720 	StyledText.clear();
721 	StyledText.setDefaultStyle(currItem->itemText.defaultStyle());
722 	StyledText.insertChars(0, tx);
723 	updateAll();
724 	if (StyledText.length() != 0)
725 		emit setProps(0, 0);
726 	//qDebug() << "SE::loadText: cursor";
727 	textCursor().setPosition(0);
728 }
729 
updateAll()730 void SEditor::updateAll()
731 {
732 	++blockContentsChangeHook;
733 	clear();
734 	insertUpdate(0, StyledText.length());
735 	--blockContentsChangeHook;
736 }
737 
insertUpdate(int position,int len)738 void SEditor::insertUpdate(int position, int len)
739 {
740 	if (StyledText.length() == 0 || len == 0)
741 		return;
742 	QString text;
743 	++blockContentsChangeHook;
744 	setUpdatesEnabled(false);
745 	this->blockSignals(true);
746 	//prevent layout of QTextDocument while updating
747 	this->textCursor().beginEditBlock();
748 	int cursorPos = textCursor().position();
749 	int scrollPos = verticalScrollBar()->value();
750 	int end  = qMin(StyledText.length(), position + len);
751 	int cSty = StyledText.charStyle(position).effects();
752 	int pAli = StyledText.paragraphStyle(position).alignment();
753 	int dir = StyledText.paragraphStyle(position).direction();
754 	setAlign(pAli);
755 	setDirection(dir);
756 	setEffects(cSty);
757 	for (int pos = position; pos < end; ++pos)
758 	{
759 		const CharStyle& cstyle(StyledText.charStyle(pos));
760 		const QChar ch = StyledText.text(pos);
761 		if (ch == SpecialChars::PARSEP)
762 		{
763 			text += "\n";
764 			const ParagraphStyle& pstyle(StyledText.paragraphStyle(pos));
765 			pAli = pstyle.alignment();
766 			setAlign(pAli);
767 			setDirection(dir);
768 			setEffects(cSty);
769 			insertPlainText(text);
770 			cSty = cstyle.effects();
771 			text = "";
772 			continue;
773 		}
774 		if (cSty != cstyle.effects() ||
775 				ch == SpecialChars::OBJECT ||
776 				ch == SpecialChars::PAGENUMBER ||
777 				ch == SpecialChars::PAGECOUNT ||
778 				ch == SpecialChars::NBSPACE ||
779 				ch == SpecialChars::FRAMEBREAK ||
780 				ch == SpecialChars::COLBREAK ||
781 				ch == SpecialChars::NBHYPHEN ||
782 				ch == SpecialChars::LINEBREAK)
783 		{
784 			setAlign(pAli);
785 			setDirection(dir);
786 			setEffects(cSty);
787 			insertPlainText(text);
788 			cSty = cstyle.effects();
789 			text = "";
790 		}
791 		if (ch == SpecialChars::OBJECT)
792 		{
793 			setColor(true);
794 			insertPlainText("@");
795 			setColor(false);
796 		}
797 		else if (ch == SpecialChars::PAGENUMBER)
798 		{
799 			setColor(true);
800 			insertPlainText("#");
801 			setColor(false);
802 		}
803 		else if (ch == SpecialChars::PAGECOUNT)
804 		{
805 			setColor(true);
806 			insertPlainText("%");
807 			setColor(false);
808 		}
809 		else if (ch == SpecialChars::NBSPACE)
810 		{
811 			setColor(true);
812 			insertPlainText("_");
813 			setColor(false);
814 		}
815 		else if (ch == SpecialChars::FRAMEBREAK)
816 		{
817 			setColor(true);
818 			insertPlainText("|");
819 			setColor(false);
820 		}
821 		else if (ch == SpecialChars::COLBREAK)
822 		{
823 			setColor(true);
824 			insertPlainText("^");
825 			setColor(false);
826 		}
827 		else if (ch == SpecialChars::NBHYPHEN)
828 		{
829 			setColor(true);
830 			insertPlainText("=");
831 			setColor(false);
832 		}
833 		else if (ch == SpecialChars::LINEBREAK)
834 		{
835 			setColor(true);
836 			insertPlainText("*");
837 			setColor(false);
838 		}
839 		else
840 			text += ch;
841 	}
842 	if (position < end)
843 	{
844 		const ParagraphStyle& pstyle(StyledText.paragraphStyle(end - 1));
845 		setAlign(pstyle.alignment());
846 		setDirection(pstyle.direction());
847 	}
848 	setEffects(cSty);
849 	insertPlainText(text);
850 	QTextCursor tCursor = textCursor();
851 	tCursor.setPosition(cursorPos);
852 	setTextCursor(tCursor);
853 	verticalScrollBar()->setValue(scrollPos);
854 	this->textCursor().endEditBlock();
855 	this->blockSignals(false);
856 	setUpdatesEnabled(true);
857 	--blockContentsChangeHook;
858 	emit textChanged();
859 	//CB Removed to fix 2083 setCursorPosition(p, i);
860 }
861 
862 
updateFromChars(int pa)863 void SEditor::updateFromChars(int pa)
864 {
865 	int start = StyledText.startOfParagraph(pa);
866 	int end   = StyledText.endOfParagraph(pa);
867 	if (start >= end)
868 		return;
869 	setUpdatesEnabled(false);
870 	int SelStart = start;
871 	int SelEnd   = start;
872 	int pos = textCursor().position();
873 	textCursor().clearSelection();
874 	int effects = StyledText.charStyle(start).effects();
875 	for (int a = start; a < end; ++a)
876 	{
877 		if (effects == StyledText.charStyle(a).effects())
878 			SelEnd++;
879 		else
880 		{
881 			textCursor().setPosition(SelStart);
882 			textCursor().setPosition(SelEnd, QTextCursor::KeepAnchor);
883 			setEffects(effects);
884 			textCursor().clearSelection();
885 			effects = StyledText.charStyle(a).effects();
886 			SelStart = SelEnd;
887 			SelEnd++;
888 		}
889 	}
890 	QTextCursor tCursor = textCursor();
891 	tCursor.setPosition(SelStart);
892 	tCursor.setPosition(SelEnd, QTextCursor::KeepAnchor);
893 	setEffects(tCursor, effects);
894 	setAlign(tCursor, StyledText.paragraphStyle(start).alignment());
895 	setDirection(tCursor, StyledText.paragraphStyle(start).direction());
896 	tCursor.clearSelection();
897 	setUpdatesEnabled(true);
898 	tCursor = textCursor();
899 	tCursor.setPosition(pos);
900 	setTextCursor(tCursor);
901 }
902 
903 /* updates the internal StyledText structure, applies 'newStyle' to the selection */
updateSel(const ParagraphStyle & newStyle)904 void SEditor::updateSel(const ParagraphStyle& newStyle)
905 {
906 	int PStart, PEnd, SelStart, SelEnd, start;
907 	if (!SelStack.isEmpty())
908 	{
909 		QTextCursor tc(textCursor());
910 		int selFirst, selSecond, selThird;
911 		std::tie(selFirst, selSecond, selThird) = SelStack.pop();
912 		if (selSecond >= 0)
913 		{
914 			tc.setPosition(selFirst);
915 			tc.setPosition(selSecond, QTextCursor::KeepAnchor);
916 			setTextCursor(tc);
917 		}
918 	}
919 	SelStart = textCursor().selectionStart();
920 	PStart = StyledText.nrOfParagraph(SelStart);
921 	SelEnd = textCursor().selectionEnd();
922 	PEnd = StyledText.nrOfParagraph(SelEnd);
923 	for (int pa = PStart; pa <= PEnd; ++pa)
924 	{
925 		start = StyledText.startOfParagraph(pa);
926 		StyledText.applyStyle(start, newStyle);
927 	}
928 }
929 
updateSel(const CharStyle & newStyle)930 void SEditor::updateSel(const CharStyle& newStyle)
931 {
932 	if (!SelStack.isEmpty())
933 	{
934 		QTextCursor tc(textCursor());
935 		int selFirst, selSecond, selThird;
936 		std::tie(selFirst, selSecond, selThird) = SelStack.pop();
937 		if (selSecond >= 0)
938 		{
939 			tc.setPosition(selFirst);
940 			tc.setPosition(selSecond, QTextCursor::KeepAnchor);
941 			setTextCursor(tc);
942 		}
943 	}
944 	QTextCursor cursor(textCursor());
945 	int start = cursor.selectionStart();
946 	int end = cursor.selectionEnd();
947 	if (start >= 0 && start < end)
948 		StyledText.applyCharStyle(start, end-start, newStyle);
949 }
950 
951 
deleteSel()952 void SEditor::deleteSel()
953 {
954 	QTextCursor cursor(textCursor());
955 	int start = cursor.selectionStart();
956 	int end   = cursor.selectionEnd();
957 	if (end > start)
958 		StyledText.removeChars(start, end-start);
959 	textCursor().setPosition(start);
960 	SelStack.clear();
961 }
962 
setEffects(int effects)963 void SEditor::setEffects(int effects)
964 {
965 	QTextCursor tCursor = textCursor();
966 	setEffects(tCursor, effects);
967 	setTextCursor(tCursor);
968 }
969 
setEffects(QTextCursor & tCursor,int effects)970 void SEditor::setEffects(QTextCursor& tCursor, int effects)
971 {
972 	++blockContentsChangeHook;
973 	QTextCharFormat charF;
974 	if (effects & 8)
975 		charF.setFontUnderline(true);
976 	else
977 		charF.setFontUnderline(false);
978 	if (effects & 16)
979 		charF.setFontStrikeOut(true);
980 	else
981 		charF.setFontStrikeOut(false);
982 	if (effects & 1)
983 		charF.setVerticalAlignment(QTextCharFormat::AlignSuperScript);
984 	else if (effects & 2)
985 		charF.setVerticalAlignment(QTextCharFormat::AlignSubScript);
986 	else
987 		charF.setVerticalAlignment(QTextCharFormat::AlignNormal);
988 	tCursor.setCharFormat(charF);
989 	--blockContentsChangeHook;
990 }
991 
setColor(bool marker)992 void SEditor::setColor(bool marker)
993 {
994 	QColor tmp;
995 	if (marker)
996 		tmp = QColor(Qt::red);
997 	else
998 		tmp = QColor(Qt::black);
999 	setTextColor(tmp);
1000 }
1001 
copy()1002 void SEditor::copy()
1003 {
1004 	emit SideBarUp(false);
1005 	if ((textCursor().hasSelection()) && (!textCursor().selectedText().isEmpty()))
1006 	{
1007 		disconnect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(ClipChange()));
1008 		QMimeData* mimeData = createMimeDataFromSelection();
1009 		QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
1010 		connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(ClipChange()));
1011 		emit PasteAvail();
1012 	}
1013 	emit SideBarUp(true);
1014 }
1015 
cut()1016 void SEditor::cut()
1017 {
1018 	copy();
1019 	emit SideBarUp(false);
1020 	if (textCursor().hasSelection())
1021 		textCursor().removeSelectedText();
1022 	emit SideBarUp(true);
1023 	emit SideBarUpdate();
1024 }
1025 
paste()1026 void SEditor::paste()
1027 {
1028 	emit SideBarUp(false);
1029 	bool useMimeStyledText = false;
1030 	// int  newParaCount, lengthLastPara,
1031 	int advanceLen = 0;
1032 	int  pos = textCursor().hasSelection() ? textCursor().selectionStart() : textCursor().position();
1033 	const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard);
1034 	if (mimeData->hasFormat("application/x-scribus-styledtext"))
1035 	{
1036 		const StyledTextMimeData* styledData = dynamic_cast<const StyledTextMimeData*>(mimeData);
1037 		if (styledData)
1038 			useMimeStyledText = (styledData->document() == doc);
1039 	}
1040 	if (useMimeStyledText)
1041 	{
1042 		const StyledTextMimeData* styledData = dynamic_cast<const StyledTextMimeData*>(mimeData);
1043 		if (styledData)
1044 		{
1045 			const StoryText& styledText = styledData->styledText();
1046 			advanceLen = styledText.length();
1047 			insertStyledText(styledText, pos);
1048 		}
1049 	}
1050 	else
1051 	{
1052 		QString data = QApplication::clipboard()->text(QClipboard::Clipboard);
1053 		if (!data.isEmpty())
1054 		{
1055 			data.replace(QRegExp("\r"), "");
1056 		//	newParaCount=data.count("\n");
1057 		//	lengthLastPara=data.length()-data.lastIndexOf("\n");
1058 			data.replace(QRegExp("\n"), SpecialChars::PARSEP);
1059 //			inserted=true;
1060 			advanceLen = data.length() /*- newParaCount*/;
1061 			insertCharsInternal(data, pos);
1062 			emit PasteAvail();
1063 		}
1064 		else
1065 		{
1066 			emit SideBarUp(true);
1067 			return;
1068 		}
1069 	}
1070 	setUpdatesEnabled(false);
1071 	//qDebug() << "SE::paste: cursor";
1072 //	setCursorPosition(currentPara, currentCharPos);
1073 	QTextCursor tCursor = textCursor();
1074 	tCursor.setPosition(pos + advanceLen);
1075 	setTextCursor(tCursor);
1076 	/*for (int a = 0; a < advanceLen; ++a)
1077 	{
1078 		moveCursor(QTextCursor::Right, QTextCursor::MoveAnchor);
1079 	}*/
1080 	setUpdatesEnabled(true);
1081 //	if (inserted)
1082 //		setCursorPosition(currentPara+newParaCount,(newParaCount==0?currentCharPos:0)+lengthLastPara-1);
1083 	repaint();
1084 	emit SideBarUp(true);
1085 	emit SideBarUpdate();
1086 }
1087 
canInsertFromMimeData(const QMimeData * source) const1088 bool SEditor::canInsertFromMimeData( const QMimeData * source ) const
1089 {
1090 	return (source->hasText() || source->hasFormat("application/x-scribus-styledtext"));
1091 
1092 }
1093 
createMimeDataFromSelection() const1094 QMimeData* SEditor::createMimeDataFromSelection () const
1095 {
1096 	StyledTextMimeData* mimeData = new StyledTextMimeData();
1097 	QTextCursor cursor = textCursor();
1098 	int start = cursor.selectionStart();
1099 	int end   = cursor.selectionEnd();
1100 	if (start < 0 || end <= start)
1101 		return mimeData;
1102 	StoryText* that = const_cast<StoryText*> (&StyledText);
1103 	that->select(start, end - start);
1104 	QString selectedText = cursor.selectedText();
1105 	selectedText.replace(QChar(0x2029), QChar('\n'));
1106 	mimeData->setText(selectedText);
1107 	mimeData->setStyledText(*that, doc);
1108 	return mimeData;
1109 }
1110 
insertFromMimeData(const QMimeData * source)1111 void SEditor::insertFromMimeData ( const QMimeData * source )
1112 {
1113 	paste();
1114 }
1115 
SelClipChange()1116 void SEditor::SelClipChange()
1117 {
1118 	emit PasteAvail();
1119 }
1120 
ClipChange()1121 void SEditor::ClipChange()
1122 {
1123 	emit PasteAvail();
1124 }
1125 
scrollContentsBy(int dx,int dy)1126 void SEditor::scrollContentsBy(int dx, int dy)
1127 {
1128 	emit contentsMoving(dx, dy);
1129 	QTextEdit::scrollContentsBy(dx, dy);
1130 }
1131 
1132 /* Toolbar for Fill Colour */
SToolBColorF(QMainWindow * parent,ScribusDoc * doc)1133 SToolBColorF::SToolBColorF(QMainWindow* parent, ScribusDoc *doc) : QToolBar( tr("Fill Color Settings"), parent)
1134 {
1135 	FillIcon = new QLabel(this);
1136 	FillIcon->setPixmap(IconManager::instance().loadPixmap("16/color-fill.png"));
1137 	FillIcon->setScaledContents( false );
1138 	fillIconAction = addWidget(FillIcon);
1139 	fillIconAction->setVisible(true);
1140 	TxFill = new ColorCombo(false, this);
1141 	TxFill->setPixmapType(ColorCombo::smallPixmaps);
1142 	txFillAction = addWidget(TxFill);
1143 	txFillAction->setVisible(true);
1144 	PM2 = new ShadeButton(this);
1145 	pm2Action = addWidget(PM2);
1146 	pm2Action->setVisible(true);
1147 
1148 	setCurrentDocument(doc);
1149 	//TxFill->listBox()->setMinimumWidth(TxFill->listBox()->maxItemWidth()+24);
1150 
1151 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
1152 	connect(TxFill, SIGNAL(activated(int)), this, SLOT(newShadeHandler()));
1153 	connect(PM2, SIGNAL(clicked()), this, SLOT(newShadeHandler()));
1154 
1155 	languageChange();
1156 }
1157 
changeEvent(QEvent * e)1158 void SToolBColorF::changeEvent(QEvent *e)
1159 {
1160 	if (e->type() == QEvent::LanguageChange)
1161 	{
1162 		languageChange();
1163 		return;
1164 	}
1165 	QToolBar::changeEvent(e);
1166 }
1167 
iconSetChange()1168 void SToolBColorF::iconSetChange()
1169 {
1170 	FillIcon->setPixmap(IconManager::instance().loadPixmap("16/color-fill.png"));
1171 }
1172 
languageChange()1173 void SToolBColorF::languageChange()
1174 {
1175 	TxFill->setToolTip("");
1176 	PM2->setToolTip("");
1177 	TxFill->setToolTip( tr( "Color of text fill" ));
1178 	PM2->setToolTip( tr( "Saturation of color of text fill" ));
1179 }
1180 
setCurrentDocument(ScribusDoc * doc)1181 void SToolBColorF::setCurrentDocument(ScribusDoc *doc)
1182 {
1183 	ColorList list = doc ? doc->PageColors : ColorList();
1184 	TxFill->setColors(list, true);
1185 	resize(minimumSizeHint());
1186 }
1187 
SetColor(int c)1188 void SToolBColorF::SetColor(int c)
1189 {
1190 	QSignalBlocker sigBlocker(TxFill);
1191 	TxFill->setCurrentIndex(c);
1192 }
1193 
SetShade(double s)1194 void SToolBColorF::SetShade(double s)
1195 {
1196 	QSignalBlocker sigBlocker(PM2);
1197 	PM2->setValue(qRound(s));
1198 }
1199 
newShadeHandler()1200 void SToolBColorF::newShadeHandler()
1201 {
1202 	emit NewColor(TxFill->currentIndex(), PM2->getValue());
1203 }
1204 
1205 /* Toolbar for Stroke Colour */
SToolBColorS(QMainWindow * parent,ScribusDoc * doc)1206 SToolBColorS::SToolBColorS(QMainWindow* parent, ScribusDoc *doc) : QToolBar( tr("Stroke Color Settings"), parent)
1207 {
1208 	StrokeIcon = new QLabel( "", this );
1209 	StrokeIcon->setPixmap(IconManager::instance().loadPixmap("16/color-stroke.png"));
1210 	StrokeIcon->setScaledContents(false);
1211 
1212 	strokeIconAction = addWidget(StrokeIcon);
1213 	strokeIconAction->setVisible(true);
1214 
1215 	TxStroke = new ColorCombo(false, this);
1216 	TxStroke->setPixmapType(ColorCombo::smallPixmaps);
1217 	txStrokeAction = addWidget(TxStroke);
1218 	txStrokeAction->setVisible(true);
1219 
1220 	PM1 = new ShadeButton(this);
1221 	pm1Action = addWidget(PM1);
1222 	pm1Action->setVisible(true);
1223 
1224 	setCurrentDocument(doc);
1225 
1226 	//TxStroke->listBox()->setMinimumWidth(TxStroke->listBox()->maxItemWidth()+24);
1227 
1228 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
1229 	connect(TxStroke, SIGNAL(activated(int)), this, SLOT(newShadeHandler()));
1230 	connect(PM1, SIGNAL(clicked()), this, SLOT(newShadeHandler()));
1231 
1232 	languageChange();
1233 }
1234 
changeEvent(QEvent * e)1235 void SToolBColorS::changeEvent(QEvent *e)
1236 {
1237 	if (e->type() == QEvent::LanguageChange)
1238 	{
1239 		languageChange();
1240 		return;
1241 	}
1242 	QToolBar::changeEvent(e);
1243 }
1244 
iconSetChange()1245 void SToolBColorS::iconSetChange()
1246 {
1247 	IconManager& iconManager = IconManager::instance();
1248 	StrokeIcon->setPixmap(iconManager.loadPixmap("16/color-stroke.png"));
1249 }
1250 
languageChange()1251 void SToolBColorS::languageChange()
1252 {
1253 	TxStroke->setToolTip("");
1254 	PM1->setToolTip("");
1255 	TxStroke->setToolTip( tr("Color of text stroke"));
1256 	PM1->setToolTip( tr("Saturation of color of text stroke"));
1257 }
1258 
setCurrentDocument(ScribusDoc * doc)1259 void SToolBColorS::setCurrentDocument(ScribusDoc *doc)
1260 {
1261 	ColorList list = doc ? doc->PageColors : ColorList();
1262 	TxStroke->setColors(list, true);
1263 	resize(minimumSizeHint());
1264 }
1265 
SetColor(int c)1266 void SToolBColorS::SetColor(int c)
1267 {
1268 	QSignalBlocker sigBlocker(TxStroke);
1269 	TxStroke->setCurrentIndex(c);
1270 }
1271 
SetShade(double s)1272 void SToolBColorS::SetShade(double s)
1273 {
1274 	QSignalBlocker sigBlocker(PM1);
1275 	PM1->setValue(qRound(s));
1276 }
1277 
newShadeHandler()1278 void SToolBColorS::newShadeHandler()
1279 {
1280 	emit NewColor(TxStroke->currentIndex(), PM1->getValue());
1281 }
1282 
1283 /* Toolbar for Character Style Settings */
SToolBStyle(QMainWindow * parent)1284 SToolBStyle::SToolBStyle(QMainWindow* parent) : QToolBar( tr("Character Settings"), parent)
1285 {
1286 	SeStyle = new StyleSelect(this);
1287 	seStyleAction = addWidget(SeStyle);
1288 	seStyleAction->setVisible(true);
1289 
1290 	trackingLabel = new QLabel( this );
1291 	trackingLabel->setText("");
1292 	trackingLabel->setPixmap(IconManager::instance().loadPixmap("textkern.png"));
1293 	trackingLabelAction = addWidget(trackingLabel);
1294 	trackingLabelAction->setVisible(true);
1295 
1296 	Extra = new ScrSpinBox( this, SC_PERCENT );
1297 	Extra->setValues( -300, 300, 2, 0);
1298 	Extra->setSuffix( unitGetSuffixFromIndex(SC_PERCENT) );
1299 	extraAction=addWidget(Extra);
1300 	extraAction->setVisible(true);
1301 
1302 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
1303 
1304 	connect(SeStyle, SIGNAL(State(int)), this, SIGNAL(newStyle(int)));
1305 	connect(Extra, SIGNAL(valueChanged(double)), this, SLOT(newKernHandler()));
1306 	connect(SeStyle->ShadowVal->Xoffset, SIGNAL(valueChanged(double)), this, SLOT(newShadowHandler()));
1307 	connect(SeStyle->ShadowVal->Yoffset, SIGNAL(valueChanged(double)), this, SLOT(newShadowHandler()));
1308 	connect(SeStyle->OutlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(newOutlineHandler()));
1309 	connect(SeStyle->UnderlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(newUnderlineHandler()));
1310 	connect(SeStyle->UnderlineVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(newUnderlineHandler()));
1311 	connect(SeStyle->StrikeVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(newStrikeHandler()));
1312 	connect(SeStyle->StrikeVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(newStrikeHandler()));
1313 
1314 	languageChange();
1315 }
1316 
changeEvent(QEvent * e)1317 void SToolBStyle::changeEvent(QEvent *e)
1318 {
1319 	if (e->type() == QEvent::LanguageChange)
1320 	{
1321 		languageChange();
1322 	}
1323 	else
1324 		QToolBar::changeEvent(e);
1325 }
1326 
iconSetChange()1327 void SToolBStyle::iconSetChange()
1328 {
1329 	IconManager& iconManager = IconManager::instance();
1330 	trackingLabel->setPixmap(iconManager.loadPixmap("textkern.png"));
1331 }
1332 
languageChange()1333 void SToolBStyle::languageChange()
1334 {
1335 	Extra->setToolTip("");
1336 	Extra->setToolTip( tr( "Manual Tracking" ));
1337 }
1338 
newStrikeHandler()1339 void SToolBStyle::newStrikeHandler()
1340 {
1341 	double x = SeStyle->StrikeVal->LPos->value() * 10.0;
1342 	double y = SeStyle->StrikeVal->LWidth->value() * 10.0;
1343 // 	emit newUnderline(x, y);
1344 	emit newStrike(x, y);
1345 }
1346 
newUnderlineHandler()1347 void SToolBStyle::newUnderlineHandler()
1348 {
1349 	double x = SeStyle->UnderlineVal->LPos->value() * 10.0;
1350 	double y = SeStyle->UnderlineVal->LWidth->value() * 10.0;
1351 	emit newUnderline(x, y);
1352 }
1353 
newOutlineHandler()1354 void SToolBStyle::newOutlineHandler()
1355 {
1356 	double x = SeStyle->OutlineVal->LWidth->value() * 10.0;
1357 	emit newOutline(x);
1358 }
1359 
newShadowHandler()1360 void SToolBStyle::newShadowHandler()
1361 {
1362 	double x = SeStyle->ShadowVal->Xoffset->value() * 10.0;
1363 	double y = SeStyle->ShadowVal->Yoffset->value() * 10.0;
1364 	emit NewShadow(x, y);
1365 }
1366 
newKernHandler()1367 void SToolBStyle::newKernHandler()
1368 {
1369 	emit NewKern(Extra->value() * 10.0);
1370 }
1371 
setOutline(double x)1372 void SToolBStyle::setOutline(double x)
1373 {
1374 	QSignalBlocker sigBlocker(SeStyle->OutlineVal->LWidth);
1375 	SeStyle->OutlineVal->LWidth->setValue(x / 10.0);
1376 }
1377 
setStrike(double p,double w)1378 void SToolBStyle::setStrike(double p, double w)
1379 {
1380 	QSignalBlocker sigBlocker1(SeStyle->StrikeVal->LWidth);
1381 	QSignalBlocker sigBlocker2(SeStyle->StrikeVal->LPos);
1382 	SeStyle->StrikeVal->LWidth->setValue(w / 10.0);
1383 	SeStyle->StrikeVal->LPos->setValue(p / 10.0);
1384 }
1385 
setUnderline(double p,double w)1386 void SToolBStyle::setUnderline(double p, double w)
1387 {
1388 	QSignalBlocker sigBlocker1(SeStyle->UnderlineVal->LWidth);
1389 	QSignalBlocker sigBlocker2(SeStyle->UnderlineVal->LPos);
1390 	SeStyle->UnderlineVal->LWidth->setValue(w / 10.0);
1391 	SeStyle->UnderlineVal->LPos->setValue(p / 10.0);
1392 }
1393 
SetShadow(double x,double y)1394 void SToolBStyle::SetShadow(double x, double y)
1395 {
1396 	QSignalBlocker sigBlocker1(SeStyle->ShadowVal->Xoffset);
1397 	QSignalBlocker sigBlocker2(SeStyle->ShadowVal->Yoffset);
1398 	SeStyle->ShadowVal->Xoffset->setValue(x / 10.0);
1399 	SeStyle->ShadowVal->Yoffset->setValue(y / 10.0);
1400 }
1401 
SetStyle(int s)1402 void SToolBStyle::SetStyle(int s)
1403 {
1404 	QSignalBlocker sigBlocker(SeStyle);
1405 	SeStyle->setStyle(s);
1406 }
1407 
SetKern(double k)1408 void SToolBStyle::SetKern(double k)
1409 {
1410 	QSignalBlocker sigBlocker(Extra);
1411 	Extra->setValue(k / 10.0);
1412 }
1413 
1414 /* Toolbar for alignment of Paragraphs */
SToolBAlign(QMainWindow * parent)1415 SToolBAlign::SToolBAlign(QMainWindow* parent) : QToolBar( tr("Style Settings"), parent)
1416 {
1417 	GroupAlign = new AlignSelect(this);
1418 	groupAlignAction=addWidget(GroupAlign);
1419 	groupAlignAction->setVisible(true);
1420 	GroupDirection = new DirectionSelect(this);
1421 	groupDirectionAction=addWidget(GroupDirection);
1422 	groupDirectionAction->setVisible(true);
1423 	paraStyleCombo = new ParaStyleComboBox(this);
1424 	paraStyleComboAction=addWidget(paraStyleCombo);
1425 	paraStyleComboAction->setVisible(true);
1426 	connect(paraStyleCombo, SIGNAL(newStyle(const QString&)), this, SIGNAL(newParaStyle(const QString& )));
1427 	connect(GroupAlign, SIGNAL(State(int)), this, SIGNAL(newAlign(int )));
1428 	connect(GroupDirection, SIGNAL(State(int)), this, SIGNAL(newDirection(int )));
1429 
1430 	languageChange();
1431 }
1432 
changeEvent(QEvent * e)1433 void SToolBAlign::changeEvent(QEvent *e)
1434 {
1435 	if (e->type() == QEvent::LanguageChange)
1436 	{
1437 		languageChange();
1438 	}
1439 	else
1440 		QToolBar::changeEvent(e);
1441 }
1442 
languageChange()1443 void SToolBAlign::languageChange()
1444 {
1445 	GroupAlign->languageChange();
1446 	paraStyleCombo->setToolTip("");
1447 	paraStyleCombo->setToolTip( tr("Style of current paragraph"));
1448 }
1449 
SetAlign(int s)1450 void SToolBAlign::SetAlign(int s)
1451 {
1452 	GroupAlign->setStyle(s, GroupDirection->getStyle());
1453 	QSignalBlocker sigBlocker(GroupAlign);
1454 }
1455 
SetDirection(int s)1456 void SToolBAlign::SetDirection(int s)
1457 {
1458 	GroupDirection->setStyle(s);
1459 	QSignalBlocker sigBlocker(GroupDirection);
1460 }
1461 
SetParaStyle(const QString & s)1462 void SToolBAlign::SetParaStyle(const QString& s)
1463 {
1464 	QSignalBlocker sigBlocker(paraStyleCombo);
1465 	paraStyleCombo->setStyle(s);
1466 }
1467 
1468 /* Toolbar for Font related Settings */
SToolBFont(QMainWindow * parent)1469 SToolBFont::SToolBFont(QMainWindow* parent) : QToolBar( tr("Font Settings"), parent)
1470 {
1471 	Fonts = new FontCombo(this);
1472 	Fonts->setMaximumSize(190, 30);
1473 	fontsAction=addWidget(Fonts);
1474 	fontsAction->setVisible(true);
1475 
1476 	Size = new ScrSpinBox(0.5, 2048, this, SC_POINTS);
1477 	PrefsManager& prefsManager = PrefsManager::instance();
1478 	Size->setSuffix( unitGetSuffixFromIndex(SC_POINTS) );
1479 	Size->setValue(prefsManager.appPrefs.itemToolPrefs.textSize / 10.0);
1480 
1481 	sizeAction = addWidget(Size);
1482 	sizeAction->setVisible(true);
1483 
1484 	lblScaleTxtH = new QLabel(this);
1485 	lblScaleTxtH->setPixmap(IconManager::instance().loadPixmap("textscaleh.png"));
1486 	scaleTxtHAction = addWidget(lblScaleTxtH);
1487 	scaleTxtHAction->setVisible(true);
1488 
1489 	charScaleH = new ScrSpinBox(10, 400,  this, SC_PERCENT);
1490 	charScaleH->setValue(100);
1491 	charScaleH->setSuffix(unitGetSuffixFromIndex(SC_PERCENT));
1492 
1493 	chScaleHAction = addWidget(charScaleH);
1494 	chScaleHAction->setVisible(true);
1495 
1496 	lblScaleTxtV = new QLabel(this);
1497 	lblScaleTxtV->setPixmap(IconManager::instance().loadPixmap("textscalev.png"));
1498 
1499 	scaleTxtVAction = addWidget(lblScaleTxtV);
1500 	scaleTxtVAction->setVisible(true);
1501 	charScaleV = new ScrSpinBox(10, 400, this, SC_PERCENT);
1502 	charScaleV->setValue(100);
1503 	charScaleV->setSuffix(unitGetSuffixFromIndex(SC_PERCENT));
1504 	chScaleVAction = addWidget(charScaleV);
1505 	chScaleVAction->setVisible(true);
1506 
1507 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
1508 
1509 	connect(charScaleH, SIGNAL(valueChanged(double)), this, SIGNAL(newScaleH(double)));
1510 	connect(charScaleV, SIGNAL(valueChanged(double)), this, SIGNAL(newScaleV(double)));
1511 	connect(Fonts, SIGNAL(activated(const QString &)), this, SIGNAL(newFont(const QString &)));
1512 	connect(Size, SIGNAL(valueChanged(double)), this, SIGNAL(newSize(double)));
1513 
1514 	languageChange();
1515 }
1516 
changeEvent(QEvent * e)1517 void SToolBFont::changeEvent(QEvent *e)
1518 {
1519 	if (e->type() == QEvent::LanguageChange)
1520 	{
1521 		languageChange();
1522 	}
1523 	else
1524 		QToolBar::changeEvent(e);
1525 }
1526 
iconSetChange()1527 void SToolBFont::iconSetChange()
1528 {
1529 	IconManager& iconManager = IconManager::instance();
1530 	lblScaleTxtH->setPixmap(iconManager.loadPixmap("textscaleh.png"));
1531 	lblScaleTxtV->setPixmap(iconManager.loadPixmap("textscalev.png"));
1532 }
1533 
languageChange()1534 void SToolBFont::languageChange()
1535 {
1536 	Fonts->setToolTip( tr("Font of selected text"));
1537 	Size->setToolTip( tr("Font Size"));
1538 	charScaleH->setToolTip( tr("Scaling width of characters"));
1539 	charScaleV->setToolTip( tr("Scaling height of characters"));
1540 }
1541 
SetFont(const QString & f)1542 void SToolBFont::SetFont(const QString& f)
1543 {
1544 	QSignalBlocker sigBlocker(Fonts);
1545 	setCurrentComboItem(Fonts, f);
1546 }
1547 
SetSize(double s)1548 void SToolBFont::SetSize(double s)
1549 {
1550 	QSignalBlocker sigBlocker(Size);
1551 	Size->setValue(s / 10.0);
1552 }
1553 
SetScaleH(double s)1554 void SToolBFont::SetScaleH(double s)
1555 {
1556 	QSignalBlocker sigBlocker(charScaleH);
1557 	charScaleH->setValue(s / 10.0);
1558 }
1559 
SetScaleV(double s)1560 void SToolBFont::SetScaleV(double s)
1561 {
1562 	QSignalBlocker sigBlocker(charScaleV);
1563 	charScaleV->setValue(s / 10.0);
1564 }
1565 
1566 /* Main Story Editor Class, no current document */
StoryEditor(QWidget * parent)1567 StoryEditor::StoryEditor(QWidget* parent) : QMainWindow(parent, Qt::Window), // WType_Dialog) //WShowModal |
1568 	prefsManager(PrefsManager::instance())
1569 {
1570 #ifdef Q_OS_MAC
1571 	noIcon = IconManager::instance().loadPixmap("noicon.png");
1572 #endif
1573 	buildGUI();
1574 	/*
1575 	//Editor->loadItemText(ite);
1576 	updateProps(0,0);
1577 	updateStatus();
1578 	*/
1579 	Editor->setFocus();
1580 	Editor->setColor(false);
1581 	loadPrefs();
1582 
1583 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
1584 }
1585 
~StoryEditor()1586 StoryEditor::~StoryEditor()
1587 {
1588 	savePrefs();
1589 	delete StoryEd2Layout;
1590 }
1591 
showEvent(QShowEvent *)1592 void StoryEditor::showEvent(QShowEvent *)
1593 {
1594 	loadPrefs();
1595 	charSelect = new CharSelect(this);
1596 	charSelect->userTableModel()->setCharactersAndFonts(ScCore->primaryMainWindow()->charPalette->userTableModel()->characters(), ScCore->primaryMainWindow()->charPalette->userTableModel()->fonts());
1597 	connect(charSelect, SIGNAL(insertSpecialChar()), this, SLOT(slot_insertSpecialChar()));
1598 	connect(charSelect, SIGNAL(insertUserSpecialChar(QChar,QString)), this, SLOT(slot_insertUserSpecialChar(QChar,QString)));
1599 
1600 	m_smartSelection = prefsManager.appPrefs.storyEditorPrefs.smartTextSelection;
1601 	seActions["settingsSmartTextSelection"]->setChecked(m_smartSelection);
1602 }
1603 
hideEvent(QHideEvent *)1604 void StoryEditor::hideEvent(QHideEvent *)
1605 {
1606 	if (charSelect)
1607 	{
1608 		if (charSelectUsed)
1609 			ScCore->primaryMainWindow()->charPalette->userTableModel()->setCharactersAndFonts(charSelect->userTableModel()->characters(), charSelect->userTableModel()->fonts());
1610 		if (charSelect->isVisible())
1611 			charSelect->close();
1612 		disconnect(charSelect, SIGNAL(insertSpecialChar()),
1613 					this, SLOT(slot_insertSpecialChar()));
1614 		disconnect(charSelect, SIGNAL(insertUserSpecialChar(QChar, QString)),
1615 					this, SLOT(slot_insertUserSpecialChar(QChar, QString)));
1616 		charSelect->deleteLater();
1617 		charSelect = nullptr;
1618 	}
1619 	savePrefs();
1620 }
1621 
savePrefs()1622 void StoryEditor::savePrefs()
1623 {
1624 	// save prefs
1625 	QRect geo = geometry();
1626 	prefs->set("left", geo.left());
1627 	prefs->set("top", geo.top());
1628 	prefs->set("width", width());
1629 	prefs->set("height", height());
1630 	QList<int> splitted = EdSplit->sizes();
1631 	prefs->set("side", splitted[0]);
1632 	prefs->set("main", splitted[1]);
1633 	prefs->set("winstate", QString(saveState().toBase64()));
1634 }
1635 
loadPrefs()1636 void StoryEditor::loadPrefs()
1637 {
1638 	prefs = PrefsManager::instance().prefsFile->getPluginContext("StoryEditor");
1639 	int vleft   = qMax(-80, prefs->getInt("left", 10));
1640 #if defined(Q_OS_MAC) || defined(_WIN32)
1641 	int vtop	= qMax(64, prefs->getInt("top", 10));
1642 #else
1643 	int vtop	= qMax(-80, prefs->getInt("top", 10));
1644 #endif
1645 	int vwidth  = qMax(600, prefs->getInt("width", 600));
1646 	int vheight = qMax(400, prefs->getInt("height", 400));
1647 	// Check values against current screen size
1648 	QRect scr = this->screen()->availableGeometry();
1649 	if (vleft >= scr.width())
1650 		vleft = scr.left();
1651 	if (vtop >= scr.height())
1652 		vtop = qMax(64, scr.top());
1653 	if (vwidth >= scr.width())
1654 		vwidth = qMax(0, scr.width() - vleft);
1655 	if (vheight >= scr.height())
1656 		vheight = qMax(0, scr.height() - vtop);
1657 	setGeometry(vleft, vtop, vwidth, vheight);
1658 	QByteArray state = "";
1659 	state = prefs->get("winstate","").toLatin1();
1660 	if (!state.isEmpty())
1661 		restoreState(QByteArray::fromBase64(state));
1662 	int side = prefs->getInt("side", -1);
1663 	int txtarea = prefs->getInt("main", -1);
1664 	if ((side != -1) && (txtarea != -1))
1665 	{
1666 		QList<int> splitted;
1667 		splitted.append(side);
1668 		splitted.append(txtarea);
1669 		EdSplit->setSizes(splitted);
1670 	}
1671 	setupEditorGUI();
1672 }
1673 
initActions()1674 void StoryEditor::initActions()
1675 {
1676 	//File Menu
1677 	seActions.insert("fileNew", new ScrAction("16/document-new.png", "22/document-new.png", "", Qt::CTRL+Qt::Key_N, this));
1678 	seActions.insert("fileRevert", new ScrAction("reload16.png", "reload.png", "", QKeySequence(), this));
1679 	seActions.insert("fileSaveToFile", new ScrAction("16/document-save.png", "22/document-save.png", "", QKeySequence(), this));
1680 	seActions.insert("fileLoadFromFile", new ScrAction("16/document-open.png",  "22/document-open.png", "", QKeySequence(), this));
1681 	seActions.insert("fileSaveDocument", new ScrAction("", Qt::CTRL+Qt::Key_S, this));
1682 	seActions.insert("fileUpdateAndExit", new ScrAction("ok.png", "ok22.png", "", Qt::CTRL+Qt::Key_W,  this));
1683 	seActions.insert("fileExit", new ScrAction("exit.png", "exit22.png", "", QKeySequence(),  this));
1684 
1685 	connect( seActions["fileNew"], SIGNAL(triggered()), this, SLOT(Do_new()) );
1686 	connect( seActions["fileRevert"], SIGNAL(triggered()), this, SLOT(slotFileRevert()) );
1687 	connect( seActions["fileSaveToFile"], SIGNAL(triggered()), this, SLOT(SaveTextFile()) );
1688 	connect( seActions["fileLoadFromFile"], SIGNAL(triggered()), this, SLOT(LoadTextFile()) );
1689 	connect( seActions["fileSaveDocument"], SIGNAL(triggered()), this, SLOT(Do_saveDocument()) );
1690 	connect( seActions["fileUpdateAndExit"], SIGNAL(triggered()), this, SLOT(Do_leave2()) );
1691 	connect( seActions["fileExit"], SIGNAL(triggered()), this, SLOT(Do_leave()) );
1692 
1693 	//Edit Menu
1694 	seActions.insert("editCut", new ScrAction("16/edit-cut.png", QString(), "", Qt::CTRL+Qt::Key_X, this));
1695 	seActions.insert("editCopy", new ScrAction("16/edit-copy.png", QString(), "", Qt::CTRL+Qt::Key_C, this));
1696 	seActions.insert("editPaste", new ScrAction("16/edit-paste.png", QString(), "", Qt::CTRL+Qt::Key_V, this));
1697 	seActions.insert("editClear", new ScrAction("16/edit-delete.png", QString(), "", Qt::Key_Delete, this));
1698 	seActions.insert("editSelectAll", new ScrAction("16/edit-select-all.png", QString(), "", Qt::CTRL+Qt::Key_A, this));
1699 	seActions.insert("editSearchReplace", new ScrAction("16/edit-find-replace.png", QString(), "", Qt::CTRL+Qt::Key_F, this));
1700 	//seActions.insert("editEditStyle", new ScrAction("", QKeySequence(), this));
1701 	seActions.insert("editFontPreview", new ScrAction("", QKeySequence(), this));
1702 	seActions.insert("editUpdateFrame", new ScrAction("compfile16.png", "compfile.png", "", Qt::CTRL+Qt::Key_U, this));
1703 
1704 	connect( seActions["editCut"], SIGNAL(triggered()), this, SLOT(Do_cut()) );
1705 	connect( seActions["editCopy"], SIGNAL(triggered()), this, SLOT(Do_copy()) );
1706 	connect( seActions["editPaste"], SIGNAL(triggered()), this, SLOT(Do_paste()) );
1707 	connect( seActions["editClear"], SIGNAL(triggered()), this, SLOT(Do_del()) );
1708 	connect( seActions["editSelectAll"], SIGNAL(triggered()), this, SLOT(Do_selectAll()) );
1709 	connect( seActions["editSearchReplace"], SIGNAL(triggered()), this, SLOT(SearchText()) );
1710 	//connect( seActions["editEditStyle"], SIGNAL(triggered()), this, SLOT(slotEditStyles()) );
1711 	connect( seActions["editFontPreview"], SIGNAL(triggered()), this, SLOT(Do_fontPrev()) );
1712 	connect( seActions["editUpdateFrame"], SIGNAL(triggered()), this, SLOT(updateTextFrame()) );
1713 
1714 	//Insert Menu
1715 	seActions.insert("insertGlyph", new ScrAction(QString(), QString(), "", QKeySequence(), this));
1716 	connect( seActions["insertGlyph"], SIGNAL(triggered()), this, SLOT(Do_insSp()) );
1717 	seActions.insert("insertSampleText", new ScrAction(QString(), QString(), "", QKeySequence(), this));
1718 	connect(seActions["insertSampleText"], SIGNAL(triggered()), this, SLOT(insertSampleText()));
1719 
1720 	//Settings Menu
1721 	seActions.insert("settingsDisplayFont", new ScrAction("", QKeySequence(), this));
1722 	seActions.insert("settingsSmartTextSelection", new ScrAction("", QKeySequence(), this));
1723 	seActions["settingsSmartTextSelection"]->setChecked(m_smartSelection);
1724 	seActions["settingsSmartTextSelection"]->setToggleAction(true);
1725 
1726 	connect( seActions["settingsDisplayFont"], SIGNAL(triggered()), this, SLOT(setFontPref()) );
1727 	connect( seActions["settingsSmartTextSelection"], SIGNAL(toggled(bool)), this, SLOT(setSmart(bool)) );
1728 
1729 
1730 //	seActions["fileRevert"]->setEnabled(false);
1731 //	seActions["editCopy"]->setEnabled(false);
1732 //	seActions["editCut"]->setEnabled(false);
1733 //	seActions["editPaste"]->setEnabled(false);
1734 //	seActions["editClear"]->setEnabled(false);
1735 //	seActions["editUpdateFrame"]->setEnabled(false);
1736 }
1737 
buildMenus()1738 void StoryEditor::buildMenus()
1739 {
1740 	seMenuMgr = new MenuManager(this->menuBar(), this->menuBar());
1741 	seMenuMgr->createMenu("File", tr("&File"));
1742 	seMenuMgr->addMenuItemString("fileNew", "File");
1743 	seMenuMgr->addMenuItemString("fileRevert", "File");
1744 	seMenuMgr->addMenuItemString("SEPARATOR", "File");
1745 	seMenuMgr->addMenuItemString("fileSaveToFile", "File");
1746 	seMenuMgr->addMenuItemString("fileLoadFromFile", "File");
1747 	seMenuMgr->addMenuItemString("fileSaveDocument", "File");
1748 	seMenuMgr->addMenuItemString("SEPARATOR", "File");
1749 	seMenuMgr->addMenuItemString("fileUpdateAndExit", "File");
1750 	seMenuMgr->addMenuItemString("fileExit", "File");
1751 	seMenuMgr->createMenu("Edit", tr("&Edit"));
1752 	seMenuMgr->addMenuItemString("editCut", "Edit");
1753 	seMenuMgr->addMenuItemString("editCopy", "Edit");
1754 	seMenuMgr->addMenuItemString("editPaste", "Edit");
1755 	seMenuMgr->addMenuItemString("editClear", "Edit");
1756 	seMenuMgr->addMenuItemString("SEPARATOR", "Edit");
1757 	seMenuMgr->addMenuItemString("editSelectAll", "Edit");
1758 	seMenuMgr->addMenuItemString("SEPARATOR", "Edit");
1759 	seMenuMgr->addMenuItemString("editSearchReplace", "Edit");
1760 	seMenuMgr->addMenuItemString("SEPARATOR", "Edit");
1761 //	seMenuMgr->addMenuItemString("editEditStyle", "Edit");
1762 	seMenuMgr->addMenuItemString("editFontPreview", "Edit");
1763 	seMenuMgr->addMenuItemString("editUpdateFrame", "Edit");
1764 	seMenuMgr->addMenuItemString("SEPARATOR", "Edit");
1765 	seMenuMgr->addMenuItemString("settingsSmartTextSelection", "Edit");
1766 	seMenuMgr->createMenu("Insert", tr("&Insert"));
1767 	seMenuMgr->addMenuItemString("insertGlyph", "Insert");
1768 	seMenuMgr->createMenu("InsertChar", tr("Character"), "Insert");
1769 	seMenuMgr->addMenuItemString("InsertChar", "Insert");
1770 	seMenuMgr->addMenuItemString("unicodePageNumber", "InsertChar");
1771 	seMenuMgr->addMenuItemString("unicodePageCount", "InsertChar");
1772 	seMenuMgr->addMenuItemString("unicodeSoftHyphen", "InsertChar");
1773 	seMenuMgr->addMenuItemString("unicodeNonBreakingHyphen", "InsertChar");
1774 	seMenuMgr->addMenuItemString("unicodeZWJ", "InsertChar");
1775 	seMenuMgr->addMenuItemString("unicodeZWNJ", "InsertChar");
1776 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertChar");
1777 	seMenuMgr->addMenuItemString("unicodeCopyRight", "InsertChar");
1778 	seMenuMgr->addMenuItemString("unicodeRegdTM", "InsertChar");
1779 	seMenuMgr->addMenuItemString("unicodeTM", "InsertChar");
1780 	seMenuMgr->addMenuItemString("unicodeSolidus", "InsertChar");
1781 	seMenuMgr->addMenuItemString("unicodeBullet", "InsertChar");
1782 	seMenuMgr->addMenuItemString("unicodeMidpoint", "InsertChar");
1783 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertChar");
1784 	seMenuMgr->addMenuItemString("unicodeDashEm", "InsertChar");
1785 	seMenuMgr->addMenuItemString("unicodeDashEn", "InsertChar");
1786 	seMenuMgr->addMenuItemString("unicodeDashFigure", "InsertChar");
1787 	seMenuMgr->addMenuItemString("unicodeDashQuotation", "InsertChar");
1788 	seMenuMgr->createMenu("InsertQuote", tr("Quote"), "Insert");
1789 	seMenuMgr->addMenuItemString("InsertQuote", "Insert");
1790 	seMenuMgr->addMenuItemString("unicodeQuoteApostrophe", "InsertQuote");
1791 	seMenuMgr->addMenuItemString("unicodeQuoteStraight", "InsertQuote");
1792 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertQuote");
1793 	seMenuMgr->addMenuItemString("unicodeQuoteSingleLeft", "InsertQuote");
1794 	seMenuMgr->addMenuItemString("unicodeQuoteSingleRight", "InsertQuote");
1795 	seMenuMgr->addMenuItemString("unicodeQuoteDoubleLeft", "InsertQuote");
1796 	seMenuMgr->addMenuItemString("unicodeQuoteDoubleRight", "InsertQuote");
1797 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertQuote");
1798 	seMenuMgr->addMenuItemString("unicodeQuoteSingleReversed", "InsertQuote");
1799 	seMenuMgr->addMenuItemString("unicodeQuoteDoubleReversed", "InsertQuote");
1800 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertQuote");
1801 	seMenuMgr->addMenuItemString("unicodeQuoteLowSingleComma", "InsertQuote");
1802 	seMenuMgr->addMenuItemString("unicodeQuoteLowDoubleComma", "InsertQuote");
1803 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertQuote");
1804 	seMenuMgr->addMenuItemString("unicodeQuoteSingleLeftGuillemet", "InsertQuote");
1805 	seMenuMgr->addMenuItemString("unicodeQuoteSingleRightGuillemet", "InsertQuote");
1806 	seMenuMgr->addMenuItemString("unicodeQuoteDoubleLeftGuillemet", "InsertQuote");
1807 	seMenuMgr->addMenuItemString("unicodeQuoteDoubleRightGuillemet", "InsertQuote");
1808 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertQuote");
1809 	seMenuMgr->addMenuItemString("unicodeQuoteCJKSingleLeft", "InsertQuote");
1810 	seMenuMgr->addMenuItemString("unicodeQuoteCJKSingleRight", "InsertQuote");
1811 	seMenuMgr->addMenuItemString("unicodeQuoteCJKDoubleLeft", "InsertQuote");
1812 	seMenuMgr->addMenuItemString("unicodeQuoteCJKDoubleRight", "InsertQuote");
1813 	seMenuMgr->createMenu("InsertSpace", tr("Spaces && Breaks"), "Insert");
1814 	seMenuMgr->addMenuItemString("InsertSpace", "Insert");
1815 	seMenuMgr->addMenuItemString("unicodeNonBreakingSpace", "InsertSpace");
1816 	seMenuMgr->addMenuItemString("unicodeNarrowNoBreakSpace", "InsertSpace");
1817 	seMenuMgr->addMenuItemString("unicodeSpaceEN", "InsertSpace");
1818 	seMenuMgr->addMenuItemString("unicodeSpaceEM", "InsertSpace");
1819 	seMenuMgr->addMenuItemString("unicodeSpaceThin", "InsertSpace");
1820 	seMenuMgr->addMenuItemString("unicodeSpaceThick", "InsertSpace");
1821 	seMenuMgr->addMenuItemString("unicodeSpaceMid", "InsertSpace");
1822 	seMenuMgr->addMenuItemString("unicodeSpaceHair", "InsertSpace");
1823 	seMenuMgr->addMenuItemString("SEPARATOR", "InsertSpace");
1824 	seMenuMgr->addMenuItemString("unicodeNewLine", "InsertSpace");
1825 	seMenuMgr->addMenuItemString("unicodeFrameBreak", "InsertSpace");
1826 	seMenuMgr->addMenuItemString("unicodeColumnBreak", "InsertSpace");
1827 	seMenuMgr->createMenu("InsertLigature", tr("Ligature"), "Insert");
1828 	seMenuMgr->addMenuItemString("InsertLigature", "Insert");
1829 	seMenuMgr->addMenuItemString("unicodeLigature_ff", "InsertLigature");
1830 	seMenuMgr->addMenuItemString("unicodeLigature_fi", "InsertLigature");
1831 	seMenuMgr->addMenuItemString("unicodeLigature_fl", "InsertLigature");
1832 	seMenuMgr->addMenuItemString("unicodeLigature_ffi", "InsertLigature");
1833 	seMenuMgr->addMenuItemString("unicodeLigature_ffl", "InsertLigature");
1834 	seMenuMgr->addMenuItemString("unicodeLigature_ft", "InsertLigature");
1835 	seMenuMgr->addMenuItemString("unicodeLigature_st", "InsertLigature");
1836 	seMenuMgr->addMenuItemString("insertSampleText", "Insert");
1837 
1838 	seMenuMgr->createMenu("Settings", tr("&Settings"));
1839 	seMenuMgr->addMenuItemString("settingsDisplayFont", "Settings");
1840 //	seMenuMgr->addMenuItemString("settingsSmartTextSelection", "Settings");
1841 
1842 	seMenuMgr->addMenuStringToMenuBar("File");
1843 	seMenuMgr->addMenuItemStringsToMenuBar("File", seActions);
1844 	seMenuMgr->addMenuStringToMenuBar("Edit");
1845 	seMenuMgr->addMenuItemStringsToMenuBar("Edit", seActions);
1846 	seMenuMgr->addMenuStringToMenuBar("Insert");
1847 	seMenuMgr->addMenuItemStringsToMenuBar("Insert", seActions);
1848 	seMenuMgr->addMenuStringToMenuBar("Settings");
1849 	seMenuMgr->addMenuItemStringsToMenuBar("Settings", seActions);
1850 
1851 	PluginManager::instance().setupPluginActions(this);
1852 	PluginManager::instance().languageChange();
1853 }
1854 
buildGUI()1855 void StoryEditor::buildGUI()
1856 {
1857 	unicodeCharActionNames.clear();
1858 	seActions.clear();
1859 	m_smartSelection = prefsManager.appPrefs.storyEditorPrefs.smartTextSelection;
1860 	initActions();
1861 	ActionManager::initUnicodeActions(&seActions, this, &unicodeCharActionNames);
1862 	seActions["unicodeSoftHyphen"]->setEnabled(false);//CB TODO doesn't work in SE yet.
1863 	buildMenus();
1864 
1865 	setWindowIcon(IconManager::instance().loadPixmap("AppIcon.png"));
1866 	StoryEd2Layout = new QHBoxLayout;
1867 	StoryEd2Layout->setSpacing(6);
1868 	StoryEd2Layout->setContentsMargins(9, 9, 9, 9);
1869 
1870 /* Setting up Toolbars */
1871 	FileTools = new QToolBar(this);
1872 	FileTools->setIconSize(QSize(16,16));
1873 	FileTools->setObjectName("File");
1874 	FileTools->addAction(seActions["fileNew"]);
1875 	FileTools->addAction(seActions["fileLoadFromFile"]);
1876 	FileTools->addAction(seActions["fileSaveToFile"]);
1877 	FileTools->addAction(seActions["fileUpdateAndExit"]);
1878 	FileTools->addAction(seActions["fileExit"]);
1879 	FileTools->addAction(seActions["fileRevert"]);
1880 	FileTools->addAction(seActions["editUpdateFrame"]);
1881 	FileTools->addAction(seActions["editSearchReplace"]);
1882 
1883 	FileTools->setAllowedAreas(Qt::LeftToolBarArea);
1884 	FileTools->setAllowedAreas(Qt::RightToolBarArea);
1885 	FileTools->setAllowedAreas(Qt::BottomToolBarArea);
1886 	FileTools->setAllowedAreas(Qt::TopToolBarArea);
1887 	FontTools = new SToolBFont(this);
1888 	FontTools->setIconSize(QSize(16,16));
1889 	FontTools->setObjectName("Font");
1890 	FontTools->setAllowedAreas(Qt::LeftToolBarArea);
1891 	FontTools->setAllowedAreas(Qt::RightToolBarArea);
1892 	FontTools->setAllowedAreas(Qt::BottomToolBarArea);
1893 	FontTools->setAllowedAreas(Qt::TopToolBarArea);
1894 	AlignTools = new SToolBAlign(this);
1895 	AlignTools->setIconSize(QSize(16,16));
1896 	AlignTools->setObjectName("Align");
1897 	AlignTools->setAllowedAreas(Qt::LeftToolBarArea);
1898 	AlignTools->setAllowedAreas(Qt::RightToolBarArea);
1899 	AlignTools->setAllowedAreas(Qt::BottomToolBarArea);
1900 	AlignTools->setAllowedAreas(Qt::TopToolBarArea);
1901 	AlignTools->paraStyleCombo->setDoc(m_doc);
1902 	StyleTools = new SToolBStyle(this);
1903 	StyleTools->setIconSize(QSize(16,16));
1904 	StyleTools->setObjectName("Style");
1905 	StyleTools->setAllowedAreas(Qt::LeftToolBarArea);
1906 	StyleTools->setAllowedAreas(Qt::RightToolBarArea);
1907 	StyleTools->setAllowedAreas(Qt::BottomToolBarArea);
1908 	StyleTools->setAllowedAreas(Qt::TopToolBarArea);
1909 	StrokeTools = new SToolBColorS(this, m_doc);
1910 	StrokeTools->setIconSize(QSize(16,16));
1911 	StrokeTools->setObjectName("Strok");
1912 	StrokeTools->setAllowedAreas(Qt::LeftToolBarArea);
1913 	StrokeTools->setAllowedAreas(Qt::RightToolBarArea);
1914 	StrokeTools->setAllowedAreas(Qt::BottomToolBarArea);
1915 	StrokeTools->setAllowedAreas(Qt::TopToolBarArea);
1916 	StrokeTools->TxStroke->setEnabled(false);
1917 	StrokeTools->PM1->setEnabled(false);
1918 	FillTools = new SToolBColorF(this, m_doc);
1919 	FillTools->setIconSize(QSize(16,16));
1920 	FillTools->setObjectName("Fill");
1921 	FillTools->setAllowedAreas(Qt::LeftToolBarArea);
1922 	FillTools->setAllowedAreas(Qt::RightToolBarArea);
1923 	FillTools->setAllowedAreas(Qt::BottomToolBarArea);
1924 	FillTools->setAllowedAreas(Qt::TopToolBarArea);
1925 
1926 	addToolBar(FileTools);
1927 	addToolBarBreak();
1928 	addToolBar(FontTools);
1929 	addToolBar(AlignTools);
1930 	addToolBarBreak();
1931 	addToolBar(StyleTools);
1932 	addToolBar(StrokeTools);
1933 	addToolBar(FillTools);
1934 
1935 	EdSplit = new QSplitter(this);
1936 /* SideBar Widget */
1937 	EditorBar = new SideBar(this);
1938 	EdSplit->addWidget(EditorBar);
1939 /* Editor Widget, subclass of QTextEdit */
1940 	Editor = new SEditor(this, m_doc, this);
1941 	EdSplit->addWidget(Editor);
1942 	StoryEd2Layout->addWidget( EdSplit );
1943 
1944 /* Setting up Status Bar */
1945 	ButtonGroup1 = new QFrame( statusBar() );
1946 	ButtonGroup1->setFrameShape( QFrame::NoFrame );
1947 	ButtonGroup1->setFrameShadow( QFrame::Plain );
1948 	ButtonGroup1Layout = new QGridLayout( ButtonGroup1 );
1949 	ButtonGroup1Layout->setAlignment( Qt::AlignTop );
1950 	ButtonGroup1Layout->setSpacing(3);
1951 	ButtonGroup1Layout->setContentsMargins(0, 0, 0, 0);
1952 	WordCT1 = new QLabel(ButtonGroup1);
1953 	ButtonGroup1Layout->addWidget( WordCT1, 0, 0, 1, 3 );
1954 	WordCT = new QLabel(ButtonGroup1);
1955 	ButtonGroup1Layout->addWidget( WordCT, 1, 0 );
1956 	WordC = new QLabel(ButtonGroup1);
1957 	ButtonGroup1Layout->addWidget( WordC, 1, 1 );
1958 	CharCT = new QLabel(ButtonGroup1);
1959 	ButtonGroup1Layout->addWidget( CharCT, 1, 2 );
1960 	CharC = new QLabel(ButtonGroup1);
1961 	ButtonGroup1Layout->addWidget( CharC, 1, 3 );
1962 	statusBar()->addPermanentWidget(ButtonGroup1, 1);
1963 	ButtonGroup2 = new QFrame( statusBar() );
1964 	ButtonGroup2->setFrameShape( QFrame::NoFrame );
1965 	ButtonGroup2->setFrameShadow( QFrame::Plain );
1966 	ButtonGroup2Layout = new QGridLayout( ButtonGroup2 );
1967 	ButtonGroup2Layout->setAlignment( Qt::AlignTop );
1968 	ButtonGroup2Layout->setSpacing(3);
1969 	ButtonGroup2Layout->setContentsMargins(0, 0, 0, 0);
1970 	WordCT3 = new QLabel(ButtonGroup2);
1971 	ButtonGroup2Layout->addWidget( WordCT3, 0, 0, 1, 5 );
1972 	ParCT = new QLabel(ButtonGroup2);
1973 	ButtonGroup2Layout->addWidget( ParCT, 1, 0 );
1974 	ParC = new QLabel(ButtonGroup2);
1975 	ButtonGroup2Layout->addWidget( ParC, 1, 1 );
1976 	WordCT2 = new QLabel(ButtonGroup2);
1977 	ButtonGroup2Layout->addWidget( WordCT2, 1, 2 );
1978 	WordC2 = new QLabel(ButtonGroup2);
1979 	ButtonGroup2Layout->addWidget( WordC2, 1, 3 );
1980 	CharCT2 = new QLabel(ButtonGroup2);
1981 	ButtonGroup2Layout->addWidget( CharCT2, 1, 4 );
1982 	CharC2 = new QLabel(ButtonGroup2);
1983 	ButtonGroup2Layout->addWidget( CharC2, 1, 5 );
1984 	statusBar()->addPermanentWidget(ButtonGroup2, 1);
1985 	setCentralWidget( EdSplit );
1986 	//Final setup
1987 	resize( QSize(660, 500).expandedTo(minimumSizeHint()) );
1988 
1989 	EditorBar->setEditor(Editor);
1990 	Editor->installEventFilter(this);
1991 	languageChange();
1992 	ActionManager::setActionTooltips(&seActions);
1993 }
1994 
setupEditorGUI()1995 void StoryEditor::setupEditorGUI()
1996 {
1997 	QFont fo;
1998 	fo.fromString(prefsManager.appPrefs.storyEditorPrefs.guiFont);
1999 	Editor->setFont(fo);
2000 	EditorBar->setFrameStyle(Editor->frameStyle());
2001 	EditorBar->setLineWidth(Editor->lineWidth());
2002 }
2003 
changeEvent(QEvent * e)2004 void StoryEditor::changeEvent(QEvent *e)
2005 {
2006 	if (e->type() == QEvent::LanguageChange)
2007 	{
2008 		languageChange();
2009 	}
2010 	else
2011 		QWidget::changeEvent(e);
2012 }
2013 
iconSetChange()2014 void StoryEditor::iconSetChange()
2015 {
2016 	IconManager& iconManager = IconManager::instance();
2017 #ifdef Q_OS_MAC
2018 	noIcon = iconManager.loadPixmap("noicon.png");
2019 #endif
2020 	setWindowIcon(iconManager.loadPixmap("AppIcon.png"));
2021 }
2022 
languageChange()2023 void StoryEditor::languageChange()
2024 {
2025 	setWindowTitle( tr( "Story Editor" ) );
2026 	//File Menu
2027 	seMenuMgr->setText("File", tr("&File"));
2028 	seActions["fileNew"]->setText( tr("Clear All Text"));
2029 	seActions["fileRevert"]->setTexts( tr("&Reload Text from Frame"));
2030 	seActions["fileSaveToFile"]->setTexts( tr("&Save to File..."));
2031 	seActions["fileLoadFromFile"]->setTexts( tr("&Load from File..."));
2032 	seActions["fileSaveDocument"]->setTexts( tr("Save &Document"));
2033 	seActions["fileUpdateAndExit"]->setTexts( tr("&Update Text Frame and Exit"));
2034 	seActions["fileExit"]->setTexts( tr("&Exit Without Updating Text Frame"));
2035 	//Edit Menu
2036 	seMenuMgr->setText("Edit", tr("&Edit"));
2037 	seActions["editCut"]->setTexts( tr("Cu&t"));
2038 	seActions["editCopy"]->setTexts( tr("&Copy"));
2039 	seActions["editPaste"]->setTexts( tr("&Paste"));
2040 	seActions["editClear"]->setTexts( tr("C&lear"));
2041 	seActions["editSelectAll"]->setTexts( tr("Select &All"));
2042 	seActions["editSearchReplace"]->setTexts( tr("&Search/Replace..."));
2043 //	seActions["editEditStyle"]->setTexts( tr("&Edit Styles..."));
2044 	seActions["editFontPreview"]->setTexts( tr("&Fonts Preview..."));
2045 	seActions["editUpdateFrame"]->setTexts( tr("&Update Text Frame"));
2046 
2047 	//Insert menu
2048 	seActions["insertGlyph"]->setTexts( tr("&Glyph..."));
2049 	seMenuMgr->setText("Insert", tr("&Insert"));
2050 	seMenuMgr->setText("InsertChar", tr("Character"));
2051 	seMenuMgr->setText("InsertQuote", tr("Quote"));
2052 	seMenuMgr->setText("InsertSpace", tr("Space"));
2053 	seActions["insertSampleText"]->setTexts( tr("&Sample Text..."));
2054 
2055 	//Settings Menu
2056 	seMenuMgr->setText("Settings", tr("&Settings"));
2057 	seActions["settingsDisplayFont"]->setTexts( tr("&Display Font..."));
2058 	seActions["settingsSmartTextSelection"]->setTexts( tr("&Smart Text Selection"));
2059 
2060 	//Unicode Actions
2061 	ActionManager::languageChangeUnicodeActions(&seActions);
2062 
2063 	FileTools->setWindowTitle( tr("File"));
2064 
2065 	WordCT1->setText( tr("Current Paragraph:"));
2066 	WordCT->setText( tr("Words: "));
2067 	CharCT->setText( tr("Chars: "));
2068 	WordCT3->setText( tr("Totals:"));
2069 	ParCT->setText( tr("Paragraphs: "));
2070 	WordCT2->setText( tr("Words: "));
2071 	CharCT2->setText( tr("Chars: "));
2072 
2073 }
2074 
disconnectSignals()2075 void StoryEditor::disconnectSignals()
2076 {
2077 	Editor->disconnect();
2078 	Editor->document()->disconnect();
2079 	EditorBar->disconnect();
2080 	AlignTools->disconnect();
2081 	FillTools->disconnect();
2082 	FontTools->disconnect();
2083 	StrokeTools->disconnect();
2084 	StyleTools->disconnect();
2085 }
2086 
connectSignals()2087 void StoryEditor::connectSignals()
2088 {
2089 	connect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
2090 //	connect(Editor, SIGNAL(clicked(int, int)), this, SLOT(updateProps(int, int)));
2091 	connect(Editor, SIGNAL(setProps(int,int)), this, SLOT(updateProps(int, int)));
2092 	connect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
2093 	connect(Editor, SIGNAL(copyAvailable(bool)), this, SLOT(CopyAvail(bool)));
2094 	connect(Editor, SIGNAL(PasteAvail()), this, SLOT(PasteAvail()));
2095 	connect(Editor, SIGNAL(contentsMoving(int,int)), EditorBar, SLOT(doMove(int,int )));
2096 	connect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
2097 	connect(Editor, SIGNAL(SideBarUp(bool)), EditorBar, SLOT(setRepaint(bool )));
2098 	connect(Editor, SIGNAL(SideBarUpdate()), EditorBar, SLOT(doRepaint()));
2099 	connect(Editor->document(), SIGNAL(contentsChange(int,int,int)), Editor, SLOT(handleContentsChange(int,int,int)));
2100 	Editor->SuspendContentsChange = 0;
2101 	// 10/12/2004 - pv - #1203: wrong selection on double click
2102 //	connect(Editor, SIGNAL(doubleClicked(int, int)), this, SLOT(doubleClick(int, int)));
2103 	connect(EditorBar, SIGNAL(ChangeStyle(int, const QString&)), this, SLOT(changeStyleSB(int, const QString&)));
2104 //	connect(EditorBar, SIGNAL(sigEditStyles()), this, SLOT(slotEditStyles()));
2105 	connect(AlignTools, SIGNAL(newParaStyle(const QString&)), this, SLOT(newStyle(const QString&)));
2106 	connect(AlignTools, SIGNAL(newAlign(int)), this, SLOT(newAlign(int)));
2107 	connect(AlignTools, SIGNAL(newDirection(int)), this, SLOT(newDirection(int)));
2108 	connect(FillTools, SIGNAL(NewColor(int,int)), this, SLOT(newTxFill(int,int)));
2109 	connect(StrokeTools, SIGNAL(NewColor(int,int)), this, SLOT(newTxStroke(int,int)));
2110 	connect(FontTools, SIGNAL(newSize(double)), this, SLOT(newTxSize(double)));
2111 	connect(FontTools, SIGNAL(newFont(const QString&)), this, SLOT(newTxFont(const QString&)));
2112 	connect(FontTools, SIGNAL(newScaleH(double)), this, SLOT(newTxScale()));
2113 	connect(FontTools, SIGNAL(newScaleV(double)), this, SLOT(newTxScaleV()));
2114 	connect(StyleTools, SIGNAL(NewKern(double)), this, SLOT(newTxKern(double)));
2115 	connect(StyleTools, SIGNAL(newStyle(int)), this, SLOT(newTxStyle(int)));
2116 	connect(StyleTools, SIGNAL(NewShadow(double,double)), this, SLOT(newShadowOffs(double,double)));
2117 	connect(StyleTools, SIGNAL(newOutline(double)), this, SLOT(newTxtOutline(double)));
2118 	connect(StyleTools, SIGNAL(newUnderline(double,double)), this, SLOT(newTxtUnderline(double,double)));
2119 	connect(StyleTools, SIGNAL(newStrike(double,double)), this, SLOT(newTxtStrike(double,double)));
2120 }
2121 
setCurrentDocumentAndItem(ScribusDoc * doc,PageItem * item)2122 void StoryEditor::setCurrentDocumentAndItem(ScribusDoc *doc, PageItem *item)
2123 {
2124 	disconnectSignals();
2125 	m_doc=doc;
2126 	m_textChanged=false;
2127 	AlignTools->paraStyleCombo->setDoc(m_doc);
2128 	FillTools->setCurrentDocument(m_doc);
2129 	StrokeTools->setCurrentDocument(m_doc);
2130 	Editor->setCurrentDocument(m_doc);
2131 	StyleTools->SetStyle(0);
2132 	m_item = item;
2133 	if (m_item != nullptr)
2134 	{
2135 		setWindowTitle( tr("Story Editor - %1").arg(m_item->itemName()));
2136 		m_firstSet = false;
2137 		FontTools->Fonts->RebuildList(m_doc, m_item->isAnnotation());
2138 		Editor->loadItemText(m_item);
2139 		Editor->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
2140 		Editor->repaint();
2141 		EditorBar->offs = 0;
2142 //		Editor->textCursor().setPosition(0);
2143 //		Editor->ensureCursorVisible();
2144 		EditorBar->setRepaint(true);
2145 		EditorBar->doRepaint();
2146 		updateProps(0,0);
2147 		updateStatus();
2148 		connectSignals();
2149 	}
2150 	else
2151 	{
2152 		Editor->StyledText.clear();
2153 		Editor->clear();
2154 		setWindowTitle( tr( "Story Editor" ));
2155 	}
2156 
2157 	QString clipboardText = QApplication::clipboard()->text(QClipboard::Clipboard);
2158 	seActions["editPaste"]->setEnabled(!clipboardText.isEmpty());
2159 }
2160 
setSpellActive(bool ssa)2161 void StoryEditor::setSpellActive(bool ssa)
2162 {
2163 	m_spellActive=ssa;
2164 }
2165 
2166 /** 10/12/2004 - pv - #1203: wrong selection on double click
2167 Catch the double click signal - cut the wrong selection (with
2168 whitespaces on the tail) - select only one word - return
2169 controlling back to story editor - have rest */
doubleClick(int para,int position)2170 void StoryEditor::doubleClick(int para, int position)
2171 {
2172 	int indexFrom=0; //, indexTo=0;
2173 	QString selText = Editor->textCursor().selectedText();
2174 	if (selText.length() == 0 || !m_smartSelection)
2175 	{
2176 		updateProps(para, position);
2177 		return;
2178 	}
2179 	indexFrom = Editor->textCursor().selectionStart();
2180 //	indexTo = Editor->textCursor().selectionEnd();
2181 	selText =  selText.trimmed();
2182 	Editor->textCursor().clearSelection();
2183 	Editor->textCursor().setPosition(indexFrom);
2184 	Editor->textCursor().setPosition(indexFrom + selText.length(), QTextCursor::KeepAnchor);
2185 	updateProps(para, position);
2186 }
2187 
setSmart(bool newSmartSelection)2188 void StoryEditor::setSmart(bool newSmartSelection)
2189 {
2190 	m_smartSelection = newSmartSelection;
2191 }
2192 
closeEvent(QCloseEvent * e)2193 void StoryEditor::closeEvent(QCloseEvent *e)
2194 {
2195 	if (m_textChanged)
2196 	{
2197 		m_blockUpdate = true;
2198 		int t = ScMessageBox::warning(this, CommonStrings::trWarning,
2199 									tr("Do you want to save your changes?"),
2200 									QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
2201 									QMessageBox::No);
2202 		qApp->processEvents();
2203 		if (t == QMessageBox::Yes)
2204 		{
2205 			updateTextFrame();
2206 			m_result = QDialog::Accepted;
2207 		}
2208 		else if (t == QMessageBox::Cancel)
2209 		{
2210 			e->ignore();
2211 			m_blockUpdate = false;
2212 			return;
2213 		}
2214 		else if (t == QMessageBox::No)
2215 			m_result = QDialog::Rejected;
2216 	}
2217 	else
2218 		m_result = QDialog::Rejected;
2219 	setCurrentDocumentAndItem(nullptr, nullptr);
2220 	savePrefs();
2221 // 	if (charSelect != nullptr)
2222 // 		charSelect->close();
2223 	hide();
2224 	m_blockUpdate = false;
2225 }
2226 
keyPressEvent(QKeyEvent * e)2227 void StoryEditor::keyPressEvent(QKeyEvent *e)
2228 {
2229 	if (e->key() == Qt::Key_Escape)
2230 		close();
2231 	else
2232 	{
2233 		activFromApp = false;
2234 		QMainWindow::keyReleaseEvent(e);
2235 	}
2236 }
2237 
eventFilter(QObject * ob,QEvent * ev)2238 bool StoryEditor::eventFilter(QObject* ob, QEvent *ev)
2239 {
2240 	if (!m_spellActive)
2241 	{
2242 		if ( ev->type() == QEvent::WindowDeactivate )
2243 		{
2244 			if ((m_item != nullptr) && (!m_blockUpdate))
2245 				updateTextFrame();
2246 			activFromApp = false;
2247 		}
2248 		if ( ev->type() == QEvent::WindowActivate )
2249 		{
2250 			if ((!activFromApp) && (!m_textChanged) && (!m_blockUpdate))
2251 			{
2252 				activFromApp = true;
2253 				if (m_item != nullptr)
2254 				{
2255 					//set to false otherwise some dialog properties won't be set correctly
2256 					if (m_item->itemText.length() == 0)
2257 						m_firstSet = false;
2258 					disconnectSignals();
2259 					Editor->setUndoRedoEnabled(false);
2260 					Editor->setUndoRedoEnabled(true);
2261 					Editor->textCursor().setPosition(0);
2262 					seActions["fileRevert"]->setEnabled(false);
2263 					seActions["editCopy"]->setEnabled(false);
2264 					seActions["editCut"]->setEnabled(false);
2265 					seActions["editClear"]->setEnabled(false);
2266 					m_textChanged = false;
2267 					FontTools->Fonts->RebuildList(m_doc, m_item->isAnnotation());
2268 					Editor->loadItemText(m_item);
2269 					updateStatus();
2270 					m_textChanged = false;
2271 					//Editor->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
2272 					Editor->repaint();
2273 					EditorBar->offs = 0;
2274 	//				EditorBar->doMove(0, Editor->contentsY());
2275 					EditorBar->setRepaint(true);
2276 					EditorBar->doRepaint();
2277 					updateProps(0, 0);
2278 					connectSignals();
2279 				}
2280 			}
2281 		}
2282 	}
2283 	return QMainWindow::eventFilter(ob, ev);
2284 }
2285 
setFontPref()2286 void StoryEditor::setFontPref()
2287 {
2288 	m_blockUpdate = true;
2289 	Editor->setFont( QFontDialog::getFont( nullptr, Editor->font(), this ) );
2290 	prefsManager.appPrefs.storyEditorPrefs.guiFont = Editor->font().toString();
2291 	EditorBar->doRepaint();
2292 	m_blockUpdate = false;
2293 }
2294 
newTxFill(int c,int s)2295 void StoryEditor::newTxFill(int c, int s)
2296 {
2297 	if (c != -1)
2298 		Editor->CurrTextFill = FillTools->TxFill->itemText(c);
2299 	if (s != -1)
2300 		Editor->CurrTextFillSh = s;
2301 	CharStyle charStyle;
2302 	charStyle.setFillColor(Editor->CurrTextFill);
2303 	charStyle.setFillShade(Editor->CurrTextFillSh);
2304 	Editor->updateSel(charStyle);
2305 	modifiedText();
2306 	Editor->setFocus();
2307 }
2308 
newTxStroke(int c,int s)2309 void StoryEditor::newTxStroke(int c, int s)
2310 {
2311 	if (c != -1)
2312 		Editor->CurrTextStroke = StrokeTools->TxStroke->itemText(c);
2313 	if (s != -1)
2314 		Editor->CurrTextStrokeSh = s;
2315 	CharStyle charStyle;
2316 	charStyle.setStrokeColor(Editor->CurrTextStroke);
2317 	charStyle.setStrokeShade(Editor->CurrTextStrokeSh);
2318 	Editor->updateSel(charStyle);
2319 	modifiedText();
2320 	Editor->setFocus();
2321 }
2322 
newTxFont(const QString & f)2323 void StoryEditor::newTxFont(const QString &f)
2324 {
2325 	if (!m_doc->UsedFonts.contains(f)) {
2326 		if (!m_doc->AddFont(f)) {
2327 //, prefsManager.appPrefs.AvailFonts[f]->Font)) {
2328 			FontTools->Fonts->RebuildList(m_doc);
2329 			return;
2330 		};
2331 	}
2332 	Editor->prevFont = Editor->CurrFont;
2333 	Editor->CurrFont = f;
2334 	updateUnicodeActions();
2335 	CharStyle charStyle;
2336 	charStyle.setFont((*m_doc->AllFonts)[Editor->CurrFont]);
2337 	Editor->updateSel(charStyle);
2338 	modifiedText();
2339 	Editor->setFocus();
2340 }
2341 
newTxSize(double s)2342 void StoryEditor::newTxSize(double s)
2343 {
2344 	Editor->CurrFontSize = qRound(s * 10.0);
2345 	CharStyle charStyle;
2346 	charStyle.setFontSize(Editor->CurrFontSize);
2347 	Editor->updateSel(charStyle);
2348 	modifiedText();
2349 	Editor->setFocus();
2350 }
2351 
newTxStyle(int s)2352 void StoryEditor::newTxStyle(int s)
2353 {
2354 	Editor->CurrentEffects = static_cast<StyleFlag>(s);
2355 	CharStyle charStyle;
2356 	charStyle.setFeatures(Editor->CurrentEffects.featureList());
2357 	Editor->updateSel(charStyle);
2358 	Editor->setEffects(s);
2359 	bool setter=((s & ScStyle_Outline) || (s & ScStyle_Shadowed));
2360 	StrokeTools->TxStroke->setEnabled(setter);
2361 	StrokeTools->PM1->setEnabled(setter);
2362 	modifiedText();
2363 	Editor->setFocus();
2364 }
2365 
newTxScale()2366 void StoryEditor::newTxScale()
2367 {
2368 	int ss = qRound(FontTools->charScaleH->value() * 10);
2369 	Editor->CurrTextScaleH = ss;
2370 	CharStyle charStyle;
2371 	charStyle.setScaleH(Editor->CurrTextScaleH);
2372 	Editor->updateSel(charStyle);
2373 	modifiedText();
2374 	Editor->setFocus();
2375 }
2376 
newTxScaleV()2377 void StoryEditor::newTxScaleV()
2378 {
2379 	int ss = qRound(FontTools->charScaleV->value() * 10);
2380 	Editor->CurrTextScaleV = ss;
2381 	CharStyle charStyle;
2382 	charStyle.setScaleV(Editor->CurrTextScaleV);
2383 	Editor->updateSel(charStyle);
2384 	modifiedText();
2385 	Editor->setFocus();
2386 }
2387 
newTxKern(double s)2388 void StoryEditor::newTxKern(double s)
2389 {
2390 	Editor->CurrTextKern = s;
2391 	CharStyle charStyle;
2392 	charStyle.setTracking(Editor->CurrTextKern);
2393 	Editor->updateSel(charStyle);
2394 	modifiedText();
2395 	Editor->setFocus();
2396 }
2397 
newShadowOffs(double x,double y)2398 void StoryEditor::newShadowOffs(double x, double y)
2399 {
2400 	CharStyle charStyle;
2401 	charStyle.setShadowXOffset(x);
2402 	charStyle.setShadowYOffset(y);
2403 	Editor->CurrTextShadowX = x;
2404 	Editor->CurrTextShadowY = y;
2405 	Editor->updateSel(charStyle);
2406 	modifiedText();
2407 	Editor->setFocus();
2408 }
2409 
newTxtOutline(double o)2410 void StoryEditor::newTxtOutline(double o)
2411 {
2412 	Editor->CurrTextOutline = o;
2413 	CharStyle charStyle;
2414 	charStyle.setOutlineWidth(Editor->CurrTextOutline);
2415 	Editor->updateSel(charStyle);
2416 	modifiedText();
2417 	Editor->setFocus();
2418 }
2419 
newTxtUnderline(double p,double w)2420 void StoryEditor::newTxtUnderline(double p, double w)
2421 {
2422 	CharStyle charStyle;
2423 	charStyle.setUnderlineOffset(p);
2424 	charStyle.setUnderlineWidth(w);
2425 	Editor->CurrTextUnderPos = p;
2426 	Editor->CurrTextUnderWidth = w;
2427 	Editor->updateSel(charStyle);
2428 	modifiedText();
2429 	Editor->setFocus();
2430 }
2431 
newTxtStrike(double p,double w)2432 void StoryEditor::newTxtStrike(double p, double w)
2433 {
2434 	CharStyle charStyle;
2435 	charStyle.setStrikethruOffset(p);
2436 	charStyle.setStrikethruWidth(w);
2437 	Editor->CurrTextStrikePos = p;
2438 	Editor->CurrTextStrikeWidth = w;
2439 	Editor->updateSel(charStyle);
2440 	modifiedText();
2441 	Editor->setFocus();
2442 }
2443 
updateProps()2444 void StoryEditor::updateProps()
2445 {
2446 	QTextCursor cur = Editor->textCursor();
2447 	updateProps(cur);
2448 }
2449 
updateProps(QTextCursor & cur)2450 void StoryEditor::updateProps(QTextCursor &cur)
2451 {
2452 	int pos = cur.position();
2453 	int para = Editor->StyledText.nrOfParagraph(pos);
2454 	int start = Editor->StyledText.startOfParagraph(para);
2455 	updateProps(para, pos - start);
2456 }
2457 
updateProps(int p,int ch)2458 void StoryEditor::updateProps(int p, int ch)
2459 {
2460 	if (Editor->wasMod)
2461 		return;
2462 	ColorList::Iterator it;
2463 	int c = 0;
2464 
2465 	if ((p >= static_cast<int>(Editor->StyledText.nrOfParagraphs())) || (Editor->StyledText.length() == 0) || (!m_firstSet))
2466 	{
2467 		int pos = Editor->StyledText.startOfParagraph(p) + ch;
2468 		if (!m_firstSet)
2469 		{
2470 			const CharStyle& curstyle(pos < Editor->StyledText.length()? m_item->itemText.charStyle(pos) : m_item->itemText.defaultStyle().charStyle());
2471 			const ParagraphStyle parStyle(pos < Editor->StyledText.length()? m_item->itemText.paragraphStyle(pos) : m_item->itemText.defaultStyle());
2472 			Editor->currentParaStyle = parStyle.parent();
2473 			Editor->CurrAlign = parStyle.alignment();
2474 			Editor->CurrDirection = parStyle.direction();
2475 			Editor->CurrTextFill = curstyle.fillColor();
2476 			Editor->CurrTextFillSh = curstyle.fillShade();
2477 			Editor->CurrTextStroke = curstyle.strokeColor();
2478 			Editor->CurrTextStrokeSh = curstyle.strokeShade();
2479 			Editor->prevFont = Editor->CurrFont;
2480 			Editor->CurrFont = curstyle.font().scName();
2481 			Editor->CurrFontSize = curstyle.fontSize();
2482 			Editor->CurrentEffects = curstyle.effects();
2483 			Editor->CurrTextKern = curstyle.tracking();
2484 			Editor->CurrTextScaleH = curstyle.scaleH();
2485 			Editor->CurrTextScaleV = curstyle.scaleV();
2486 			Editor->CurrTextBase = curstyle.baselineOffset();
2487 			Editor->CurrTextShadowX = curstyle.shadowXOffset();
2488 			Editor->CurrTextShadowY = curstyle.shadowYOffset();
2489 			Editor->CurrTextOutline = curstyle.outlineWidth();
2490 			Editor->CurrTextUnderPos = curstyle.underlineOffset();
2491 			Editor->CurrTextUnderWidth = curstyle.underlineWidth();
2492 			Editor->CurrTextStrikePos = curstyle.strikethruOffset();
2493 			Editor->CurrTextStrikeWidth = curstyle.strikethruWidth();
2494 			c = 0;
2495 			StrokeTools->SetShade(Editor->CurrTextStrokeSh);
2496 			FillTools->SetShade(Editor->CurrTextFillSh);
2497 			QString b = Editor->CurrTextFill;
2498 			if ((b != CommonStrings::None) && (!b.isEmpty()))
2499 			{
2500 				c++;
2501 				for (it = m_doc->PageColors.begin(); it != m_doc->PageColors.end(); ++it)
2502 				{
2503 					if (it.key() == b)
2504 						break;
2505 					c++;
2506 				}
2507 			}
2508 			FillTools->SetColor(c);
2509 			c = 0;
2510 			b = Editor->CurrTextStroke;
2511 			if ((b != CommonStrings::None) && (!b.isEmpty()))
2512 			{
2513 				c++;
2514 				for (it = m_doc->PageColors.begin(); it != m_doc->PageColors.end(); ++it)
2515 				{
2516 					if (it.key() == b)
2517 						break;
2518 					c++;
2519 				}
2520 			}
2521 			StrokeTools->SetColor(c);
2522 			AlignTools->SetAlign(Editor->CurrAlign);
2523 			AlignTools->SetParaStyle(Editor->currentParaStyle);
2524 			AlignTools->SetDirection(Editor->CurrDirection);
2525 			StyleTools->SetKern(Editor->CurrTextKern);
2526 			StyleTools->SetStyle(Editor->CurrentEffects);
2527 			StyleTools->SetShadow(Editor->CurrTextShadowX, Editor->CurrTextShadowY);
2528 			StyleTools->setOutline(Editor->CurrTextOutline);
2529 			StyleTools->setUnderline(Editor->CurrTextUnderPos, Editor->CurrTextUnderWidth);
2530 			StyleTools->setStrike(Editor->CurrTextStrikePos, Editor->CurrTextStrikeWidth);
2531 			FontTools->SetSize(Editor->CurrFontSize);
2532 			FontTools->SetFont(Editor->CurrFont);
2533 			FontTools->SetScaleH(Editor->CurrTextScaleH);
2534 			FontTools->SetScaleV(Editor->CurrTextScaleV);
2535 		}
2536 		if ((Editor->CurrentEffects & ScStyle_Outline) || (Editor->CurrentEffects & ScStyle_Shadowed))
2537 		{
2538 			StrokeTools->TxStroke->setEnabled(true);
2539 			StrokeTools->PM1->setEnabled(true);
2540 		}
2541 		else
2542 		{
2543 			StrokeTools->TxStroke->setEnabled(false);
2544 			StrokeTools->PM1->setEnabled(false);
2545 		}
2546 		Editor->setEffects(Editor->CurrentEffects);
2547 		m_firstSet = true;
2548 		updateUnicodeActions();
2549 		return;
2550 	}
2551 	int parStart = Editor->StyledText.startOfParagraph(p);
2552 	const ParagraphStyle& parStyle(Editor->StyledText.paragraphStyle(parStart));
2553 	Editor->currentParaStyle = parStyle.parent(); //FIXME ParaStyleComboBox and use localized style name
2554 	if (Editor->StyledText.endOfParagraph(p) <= parStart)
2555 	{
2556 		Editor->prevFont = Editor->CurrFont;
2557 		Editor->CurrFont = parStyle.charStyle().font().scName();
2558 		Editor->CurrFontSize = parStyle.charStyle().fontSize();
2559 		Editor->CurrentEffects = parStyle.charStyle().effects();
2560 		Editor->CurrTextFill   = parStyle.charStyle().fillColor();
2561 		Editor->CurrTextFillSh = parStyle.charStyle().fillShade();
2562 		Editor->CurrTextStroke = parStyle.charStyle().strokeColor();
2563 		Editor->CurrTextStrokeSh = parStyle.charStyle().strokeShade();
2564 		Editor->CurrTextShadowX = parStyle.charStyle().shadowXOffset();
2565 		Editor->CurrTextShadowY = parStyle.charStyle().shadowYOffset();
2566 		Editor->CurrTextOutline = parStyle.charStyle().outlineWidth();
2567 		Editor->CurrTextUnderPos = parStyle.charStyle().underlineOffset();
2568 		Editor->CurrTextUnderWidth = parStyle.charStyle().underlineWidth();
2569 		Editor->CurrTextStrikePos = parStyle.charStyle().strikethruOffset();
2570 		Editor->CurrTextStrikeWidth = parStyle.charStyle().strikethruWidth();
2571 		Editor->setAlign(Editor->CurrAlign);
2572 		Editor->setDirection(Editor->CurrDirection);
2573 		Editor->setEffects(Editor->CurrentEffects);
2574 	}
2575 	else
2576 	{
2577 		int start;
2578 		if (Editor->textCursor().hasSelection())
2579 //		{
2580 //			int PStart=0, PEnd=0, SelStart=0, SelEnd=0;
2581 			start = Editor->textCursor().selectionStart();
2582 //			Editor->getSelection(&PStart, &SelStart, &PEnd, &SelEnd);
2583 //			start = Editor->StyledText.startOfParagraph(PStart);
2584 //			if (SelStart >= 0 && start + SelStart < Editor->StyledText.endOfParagraph(PStart))
2585 //				start = qMin(start + SelStart, Editor->StyledText.endOfParagraph(PStart)-1);
2586 //			else
2587 //				start = qMin(start + qMax(ch-1, 0), Editor->StyledText.endOfParagraph(p)-1);
2588 //		}
2589 		else
2590 			start = qMin(Editor->StyledText.startOfParagraph(p) + qMax(ch-1, 0), Editor->StyledText.endOfParagraph(p)-1);
2591 		if (start >= Editor->StyledText.length())
2592 			start = Editor->StyledText.length() - 1;
2593 		if (start < 0)
2594 			start = 0;
2595 		const ParagraphStyle& paraStyle(Editor->StyledText.paragraphStyle(start));
2596 		const CharStyle& charStyle(Editor->StyledText.charStyle(start));
2597 		Editor->CurrAlign = paraStyle.alignment();
2598 		Editor->CurrDirection = paraStyle.direction();
2599 		Editor->CurrTextFill = charStyle.fillColor();
2600 		Editor->CurrTextFillSh = charStyle.fillShade();
2601 		Editor->CurrTextStroke = charStyle.strokeColor();
2602 		Editor->CurrTextStrokeSh = charStyle.strokeShade();
2603 		Editor->prevFont = Editor->CurrFont;
2604 		Editor->CurrFont = charStyle.font().scName();
2605 		Editor->CurrFontSize = charStyle.fontSize();
2606 		Editor->CurrentEffects = charStyle.effects() & static_cast<StyleFlag>(ScStyle_UserStyles);
2607 		Editor->CurrTextKern   = charStyle.tracking();
2608 		Editor->CurrTextScaleH = charStyle.scaleH();
2609 		Editor->CurrTextScaleV = charStyle.scaleV();
2610 		Editor->CurrTextBase   = charStyle.baselineOffset();
2611 		Editor->CurrTextShadowX = charStyle.shadowXOffset();
2612 		Editor->CurrTextShadowY = charStyle.shadowYOffset();
2613 		Editor->CurrTextOutline = charStyle.outlineWidth();
2614 		Editor->CurrTextUnderPos = charStyle.underlineOffset();
2615 		Editor->CurrTextUnderWidth = charStyle.underlineWidth();
2616 		Editor->CurrTextStrikePos = charStyle.strikethruOffset();
2617 		Editor->CurrTextStrikeWidth = charStyle.strikethruWidth();
2618 	}
2619 	StrokeTools->SetShade(Editor->CurrTextStrokeSh);
2620 	FillTools->SetShade(Editor->CurrTextFillSh);
2621 	QString b = Editor->CurrTextFill;
2622 	if ((b != CommonStrings::None) && (!b.isEmpty()))
2623 	{
2624 		c++;
2625 		for (it = m_doc->PageColors.begin(); it != m_doc->PageColors.end(); ++it)
2626 		{
2627 			if (it.key() == b)
2628 				break;
2629 			c++;
2630 		}
2631 	}
2632 	FillTools->SetColor(c);
2633 	c = 0;
2634 	b = Editor->CurrTextStroke;
2635 	if ((b != CommonStrings::None) && (!b.isEmpty()))
2636 	{
2637 		c++;
2638 		for (it = m_doc->PageColors.begin(); it != m_doc->PageColors.end(); ++it)
2639 		{
2640 			if (it.key() == b)
2641 				break;
2642 			c++;
2643 		}
2644 	}
2645 	StrokeTools->SetColor(c);
2646 	if ((Editor->CurrentEffects & ScStyle_Outline) || (Editor->CurrentEffects & ScStyle_Shadowed))
2647 	{
2648 		StrokeTools->TxStroke->setEnabled(true);
2649 		StrokeTools->PM1->setEnabled(true);
2650 	}
2651 	else
2652 	{
2653 		StrokeTools->TxStroke->setEnabled(false);
2654 		StrokeTools->PM1->setEnabled(false);
2655 	}
2656 	StyleTools->SetKern(Editor->CurrTextKern);
2657 	StyleTools->SetStyle(Editor->CurrentEffects);
2658 	StyleTools->SetShadow(Editor->CurrTextShadowX, Editor->CurrTextShadowY);
2659 	StyleTools->setOutline(Editor->CurrTextOutline);
2660 	StyleTools->setUnderline(Editor->CurrTextUnderPos, Editor->CurrTextUnderWidth);
2661 	StyleTools->setStrike(Editor->CurrTextStrikePos, Editor->CurrTextStrikeWidth);
2662 	FontTools->SetSize(Editor->CurrFontSize);
2663 	FontTools->SetFont(Editor->CurrFont);
2664 	FontTools->SetScaleH(Editor->CurrTextScaleH);
2665 	FontTools->SetScaleV(Editor->CurrTextScaleV);
2666 	AlignTools->SetAlign(Editor->CurrAlign);
2667 	AlignTools->SetParaStyle(Editor->currentParaStyle);
2668 	AlignTools->SetDirection(Editor->CurrDirection);
2669 	updateUnicodeActions();
2670 	updateStatus();
2671 }
2672 
updateStatus()2673 void StoryEditor::updateStatus()
2674 {
2675 	QString tmp;
2676 	int p = Editor->StyledText.nrOfParagraph(Editor->textCursor().position());
2677 	int start = Editor->StyledText.startOfParagraph(p);
2678 	int end = Editor->StyledText.endOfParagraph(p);
2679 
2680 	int paragraphCount = Editor->StyledText.nrOfParagraphs();
2681 	ParC->setText(tmp.setNum(paragraphCount));
2682 	CharC->setText(tmp.setNum(end - start));
2683 
2684 	QRegExp rx( "(\\w+)\\b" );
2685 	const QString& txt(Editor->StyledText.text(0, Editor->StyledText.length()));
2686 	int counter  = 0;
2687 	int counter2 = 0;
2688 
2689 	int realCharCount = Editor->StyledText.length();
2690 	int parSepCount   = paragraphCount;
2691 	if ((realCharCount > 0) && (!txt.endsWith(SpecialChars::PARSEP)))
2692 		parSepCount -= 1;
2693 	CharC2->setText(tmp.setNum(realCharCount - parSepCount));
2694 
2695 	int pos = rx.indexIn(txt, 0);
2696 	while (pos >= 0)
2697 	{
2698 		if (pos >= start && pos < end)
2699 			counter++;
2700 
2701 		counter2++;
2702 		pos += rx.matchedLength();
2703 		pos  = rx.indexIn(txt, pos);
2704 	}
2705 
2706 	WordC->setText(tmp.setNum(counter));
2707 	WordC2->setText(tmp.setNum(counter2));
2708 }
2709 
Do_insSp()2710 void StoryEditor::Do_insSp()
2711 {
2712 	//ScCore->primaryMainWindow()->charPalette->show();
2713 	charSelectUsed = true;
2714 	if (charSelect->isVisible())
2715 		return;
2716 	charSelect->setEnabled(true, nullptr);
2717 	charSelect->setDoc(m_doc);
2718 	charSelect->show();
2719 }
2720 
insertSampleText()2721 void StoryEditor::insertSampleText()
2722 {
2723 	LoremManager dia(m_doc, this);
2724 	if (!dia.exec())
2725 		return;
2726 	m_blockUpdate = true;
2727 	Editor->insertChars(dia.loremIpsum());
2728 	m_blockUpdate = false;
2729 }
2730 
slot_insertSpecialChar()2731 void StoryEditor::slot_insertSpecialChar()
2732 {
2733 	m_blockUpdate = true;
2734 	if (!charSelect->getCharacters().isEmpty())
2735 		Editor->insertPlainText(charSelect->getCharacters());
2736 	m_blockUpdate = false;
2737 }
2738 
slot_insertUserSpecialChar(QChar c,const QString &)2739 void StoryEditor::slot_insertUserSpecialChar(QChar c, const QString&)
2740 {
2741 	m_blockUpdate = true;
2742 	Editor->insertPlainText(c);
2743 	m_blockUpdate = false;
2744 }
2745 
Do_fontPrev()2746 void StoryEditor::Do_fontPrev()
2747 {
2748 	m_blockUpdate = true;
2749 	QString retval;
2750 	ScActionPlugin* plugin;
2751 	bool result = false;
2752 
2753 	if (PluginManager::instance().DLLexists("fontpreview"))
2754 	{
2755 		plugin = qobject_cast<ScActionPlugin*>(PluginManager::instance().getPlugin("fontpreview", false));
2756 		if (plugin)
2757 			result = plugin->run(this, m_doc, Editor->CurrFont);
2758 		if (result)
2759 		{
2760 			retval = plugin->runResult();
2761 			if (!retval.isEmpty())
2762 			{
2763 				newTxFont(retval);
2764 				FontTools->SetFont(retval);
2765 			}
2766 		}
2767 	}
2768 	m_blockUpdate = false;
2769 }
2770 
Do_leave2()2771 void StoryEditor::Do_leave2()
2772 {
2773 	updateTextFrame();
2774 	m_result = QDialog::Accepted;
2775 	setCurrentDocumentAndItem(m_doc, nullptr);
2776 	hide();
2777 	m_blockUpdate = false;
2778 }
2779 
Do_leave()2780 void StoryEditor::Do_leave()
2781 {
2782 	if (m_textChanged)
2783 	{
2784 		m_blockUpdate = true;
2785 		int t = ScMessageBox::warning(this, CommonStrings::trWarning,
2786 									 tr("Do you really want to lose all your changes?"),
2787 									 QMessageBox::Yes | QMessageBox::No,
2788 									 QMessageBox::No,	// GUI default
2789 									 QMessageBox::Yes);	// batch default
2790 		qApp->processEvents();
2791 		if (t == QMessageBox::No)
2792 		{
2793 			m_blockUpdate = false;
2794 			return;
2795 		}
2796 	}
2797 	m_result = QDialog::Rejected;
2798 	setCurrentDocumentAndItem(m_doc, nullptr);
2799 	hide();
2800 	m_blockUpdate = false;
2801 }
2802 
Do_saveDocument()2803 void StoryEditor::Do_saveDocument()
2804 {
2805 	m_blockUpdate = true;
2806 	if (ScCore->primaryMainWindow()->slotFileSave())
2807 		updateTextFrame();
2808 	m_blockUpdate = false;
2809 }
2810 
Do_new()2811 bool StoryEditor::Do_new()
2812 {
2813 	if (!Editor->document()->isEmpty())
2814 	{
2815 		m_blockUpdate = true;
2816 		int t = ScMessageBox::warning(this, CommonStrings::trWarning,
2817 								 tr("Do you really want to clear all your text?"),
2818 								 QMessageBox::Yes | QMessageBox::No,
2819 								 QMessageBox::No,	// GUI default
2820 								 QMessageBox::Yes);	// batch default
2821 		qApp->processEvents();
2822 		if (t == QMessageBox::No)
2823 		{
2824 			m_blockUpdate = false;
2825 			return false;
2826 		}
2827 	}
2828 	Editor->clear();
2829 	Editor->setUndoRedoEnabled(false);
2830 	Editor->setUndoRedoEnabled(true);
2831 	//qDebug() << "SE::Do_new: cursor";
2832 	Editor->textCursor().setPosition(0);
2833 	seActions["fileRevert"]->setEnabled(false);
2834 	seActions["editCopy"]->setEnabled(false);
2835 	seActions["editCut"]->setEnabled(false);
2836 	seActions["editClear"]->setEnabled(false);
2837 //	m_textChanged = false;
2838 	EditorBar->setRepaint(true);
2839 	EditorBar->doRepaint();
2840 	updateProps(0, 0);
2841 	updateStatus();
2842 	m_blockUpdate = false;
2843 	return true;
2844 }
2845 
slotFileRevert()2846 void StoryEditor::slotFileRevert()
2847 {
2848 	if (Do_new())
2849 	{
2850 		Editor->loadItemText(m_item);
2851 		updateStatus();
2852 		EditorBar->setRepaint(true);
2853 		EditorBar->doRepaint();
2854 		Editor->repaint();
2855 	}
2856 }
2857 
Do_selectAll()2858 void StoryEditor::Do_selectAll()
2859 {
2860 	if (Editor->StyledText.length() == 0)
2861 		return;
2862 	Editor->selectAll();
2863 /*	int lastPar = Editor->StyledText.nrOfParagraphs()-1;
2864 	if (lastPar > 0)
2865 	{
2866 		int lastParStart = Editor->StyledText.startOfParagraph(lastPar);
2867 		int lastParEnd = Editor->StyledText.endOfParagraph(lastPar);
2868 		Editor->setSelection(0, 0, lastPar, lastParEnd - lastParStart);
2869 	}
2870 	else
2871 	{
2872 		Editor->setSelection(0, 0, 0, Editor->StyledText.length());
2873 	} */
2874 }
2875 
Do_copy()2876 void StoryEditor::Do_copy()
2877 {
2878 	Editor->copy();
2879 }
2880 
Do_paste()2881 void StoryEditor::Do_paste()
2882 {
2883 	Editor->paste();
2884 }
2885 
Do_cut()2886 void StoryEditor::Do_cut()
2887 {
2888 	Editor->cut();
2889 }
2890 
Do_del()2891 void StoryEditor::Do_del()
2892 {
2893 	if (Editor->StyledText.length() == 0)
2894 		return;
2895 	EditorBar->setRepaint(false);
2896 	if (Editor->textCursor().hasSelection())
2897 		Editor->textCursor().removeSelectedText();
2898 	EditorBar->setRepaint(true);
2899 	EditorBar->doRepaint();
2900 }
2901 
CopyAvail(bool u)2902 void StoryEditor::CopyAvail(bool u)
2903 {
2904 	seActions["editCopy"]->setEnabled(u);
2905 	seActions["editCut"]->setEnabled(u);
2906 	seActions["editClear"]->setEnabled(u);
2907 //	seActions["editCopy"]->setEnabled(Editor->tBuffer.length() != 0);
2908 }
2909 
PasteAvail()2910 void StoryEditor::PasteAvail()
2911 {
2912 	seActions["editPaste"]->setEnabled(true);
2913 }
2914 
updateTextFrame()2915 void StoryEditor::updateTextFrame()
2916 {
2917 	//Return immediately if we don't have to update the frame
2918 	if (!m_textChanged)
2919 		return;
2920 	PageItem *nextItem = m_item;
2921 	if (m_item->isTextFrame())
2922 		nextItem = m_item->firstInChain();
2923 	m_item->invalidateLayout();
2924 	PageItem* nb2 = nextItem;
2925 	nb2->itemText.clear();
2926 #if 0
2927 	if (m_item->isTextFrame())
2928 	{
2929 		while (nb2 != 0)
2930 		{
2931 		for (int j = nb2->firstInFrame(); j <= nb2->lastInFrame(); ++j)
2932 		{
2933 			if ((nb2->itemText.text(j) == SpecialChars::OBJECT) && (nb2->itemText.item(j)->cembedded != 0))
2934 			{
2935 				QList<PageItem*> emG;
2936 				emG.clear();
2937 				emG.append(nb2->itemText.item(j)->cembedded);
2938 				if (nb2->itemText.item(j)->cembedded->Groups.count() != 0)
2939 				{
2940 					for (uint ga=0; ga<Editor->FrameItems.count(); ++ga)
2941 					{
2942 						if (Editor->FrameItems.at(ga)->Groups.count() != 0)
2943 						{
2944 							if (Editor->FrameItems.at(ga)->Groups.top() == nb2->itemText.item(j)->cembedded->Groups.top())
2945 							{
2946 								if (Editor->FrameItems.at(ga)->ItemNr != nb2->itemText.item(j)->cembedded->ItemNr)
2947 								{
2948 									if (emG.find(Editor->FrameItems.at(ga)) == -1)
2949 										emG.append(Editor->FrameItems.at(ga));
2950 								}
2951 							}
2952 						}
2953 					}
2954 				}
2955 				for (uint em = 0; em < emG.count(); ++em)
2956 				{
2957 					m_doc->FrameItems.remove(emG.at(em));
2958 				}
2959 			}
2960 		}
2961 		nb2->itemText.clear();
2962 			nb2->CPos = 0;
2963 			nb2 = nb2->nextInChain();
2964 		}
2965 	}
2966 #endif
2967 	Editor->saveItemText(nextItem);
2968 	// #9180 : force relayout here, it appears that relayout is sometime disabled
2969 	// to speed up selection, but re layout() cannot be avoided here
2970 	if (nextItem->isTextFrame())
2971 		nextItem->asTextFrame()->invalidateLayout(true);
2972 	nextItem->layout();
2973 #if 0
2974 	QList<PageItem*> FrameItemsDel;
2975 	FrameItemsDel.setAutoDelete(true);
2976 	for (uint a = 0; a < Editor->FrameItems.count(); ++a)
2977 	{
2978 		if (m_doc->FrameItems.findRef(Editor->FrameItems.at(a)) == -1)
2979 			FrameItemsDel.append(Editor->FrameItems.at(a));
2980 	}
2981 	for (uint a = 0; a < FrameItemsDel.count(); ++a)
2982 	{
2983 		Editor->FrameItems.remove(FrameItemsDel.at(a));
2984 	}
2985 	FrameItemsDel.clear();
2986 #endif
2987 #if 0
2988 	if (currItem->isTextFrame())
2989 	{
2990 		nextItem->layout();
2991 		nb2 = nextItem;
2992 		while (nb2 != 0)
2993 		{
2994 			nb2->Dirty = false;
2995 			nb2 = nb2->nextInChain();
2996 		}
2997 	}
2998 #endif
2999 	ScCore->primaryMainWindow()->view->DrawNew();
3000 	m_textChanged = false;
3001 	seActions["fileRevert"]->setEnabled(false);
3002 	seActions["editUpdateFrame"]->setEnabled(false);
3003 	emit DocChanged();
3004 }
3005 
SearchText()3006 void StoryEditor::SearchText()
3007 {
3008 	m_blockUpdate = true;
3009 	EditorBar->setRepaint(false);
3010 	QScopedPointer<SearchReplace> dia(new SearchReplace(this, m_doc, m_item, false));
3011 	if (dia->exec())
3012 	{
3013 		int pos = dia->firstMatchCursorPosition();
3014 		if (pos >= 0)
3015 		{
3016 			QTextCursor tCursor = Editor->textCursor();
3017 			tCursor.setPosition(pos);
3018 			Editor->setTextCursor(tCursor);
3019 			Editor->SelStack.push(std::make_tuple(pos, -1, Editor->verticalScrollBar()->value()));
3020 		}
3021 	}
3022 	qApp->processEvents();
3023 	m_blockUpdate = false;
3024 	EditorBar->setRepaint(true);
3025 	EditorBar->doRepaint();
3026 }
3027 
3028 //void StoryEditor::slotEditStyles()
3029 //{
3030 //	ScCore->primaryMainWindow()->styleMgr()->exec(this);
3031 //}
3032 
newAlign(int st)3033 void StoryEditor::newAlign(int st)
3034 {
3035 	Editor->CurrAlign = st;
3036 	changeAlign(st);
3037 }
3038 
newDirection(int dir)3039 void StoryEditor::newDirection(int dir)
3040 {
3041 	Editor->CurrDirection = dir;
3042 	if (dir == ParagraphStyle::LTR && Editor->CurrAlign == ParagraphStyle::RightAligned)
3043 		Editor->CurrAlign = ParagraphStyle::LeftAligned;
3044 	else if (dir == ParagraphStyle::RTL && Editor->CurrAlign == ParagraphStyle::LeftAligned)
3045 		Editor->CurrAlign = ParagraphStyle::RightAligned;
3046 	changeDirection(dir);
3047 }
3048 
3049 
newStyle(const QString & name)3050 void StoryEditor::newStyle(const QString& name)
3051 {
3052 	Editor->currentParaStyle = name;
3053 	changeStyle();
3054 }
3055 
3056 
changeStyleSB(int pa,const QString & name)3057 void StoryEditor::changeStyleSB(int pa, const QString& name)
3058 {
3059 	Editor->currentParaStyle = name;
3060 	ParagraphStyle newStyle;
3061 	newStyle.setParent(Editor->currentParaStyle);
3062 
3063 	if (Editor->StyledText.length() != 0)
3064 	{
3065 		disconnect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3066 		disconnect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3067 		disconnect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3068 		int cursorPos = Editor->textCursor().position();
3069 		int scrollPos = Editor->verticalScrollBar()->value();
3070 
3071 /*		qDebug() << QString("changeStyleSB: pa=%2, start=%2, new=%3 %4")
3072 			   .arg(pa)
3073 			   .arg(Editor->StyledText.startOfParagraph(pa))
3074 			   .arg(newStyle.parent())
3075 			   .arg(newStyle.hasParent());
3076 */
3077 		int paraStart= Editor->StyledText.startOfParagraph(pa);
3078 		if (name.isEmpty()) // erase parent style
3079 		{
3080 			newStyle = Editor->StyledText.paragraphStyle(paraStart);
3081 			newStyle.setParent(name);
3082 			Editor->StyledText.setStyle(paraStart, newStyle);
3083 		}
3084 		else
3085 			Editor->StyledText.applyStyle(paraStart, newStyle, true);
3086 
3087 		Editor->updateFromChars(pa);
3088 		QTextCursor tCursor = Editor->textCursor();
3089 		tCursor.setPosition(cursorPos);
3090 		Editor->setTextCursor(tCursor);
3091 		Editor->verticalScrollBar()->setValue(scrollPos);
3092 
3093 		EditorBar->doRepaint();
3094 		connect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3095 		connect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3096 		connect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3097 	}
3098 	else
3099 	{
3100 		const CharStyle& currentCharStyle = m_doc->paragraphStyles().get(Editor->currentParaStyle).charStyle();
3101 		Editor->prevFont = Editor->CurrFont;
3102 		Editor->CurrFont = currentCharStyle.font().scName();
3103 		Editor->CurrFontSize   = currentCharStyle.fontSize();
3104 		Editor->CurrentEffects = currentCharStyle.effects();
3105 		Editor->CurrTextFill   = currentCharStyle.fillColor();
3106 		Editor->CurrTextFillSh = currentCharStyle.fillShade();
3107 		Editor->CurrTextStroke = currentCharStyle.strokeColor();
3108 		Editor->CurrTextStrokeSh = currentCharStyle.strokeShade();
3109 		Editor->CurrTextShadowX = currentCharStyle.shadowXOffset();
3110 		Editor->CurrTextShadowY = currentCharStyle.shadowYOffset();
3111 		Editor->CurrTextOutline = currentCharStyle.outlineWidth();
3112 		Editor->CurrTextUnderPos = currentCharStyle.underlineOffset();
3113 		Editor->CurrTextUnderWidth = currentCharStyle.underlineWidth();
3114 		Editor->CurrTextStrikePos = currentCharStyle.strikethruOffset();
3115 		Editor->CurrTextStrikeWidth = currentCharStyle.strikethruWidth();
3116 
3117 		Editor->setEffects(Editor->CurrentEffects);
3118 		if ((Editor->CurrentEffects & ScStyle_Outline) || (Editor->CurrentEffects & ScStyle_Shadowed))
3119 		{
3120 			StrokeTools->TxStroke->setEnabled(true);
3121 			StrokeTools->PM1->setEnabled(true);
3122 		}
3123 		else
3124 		{
3125 			StrokeTools->TxStroke->setEnabled(false);
3126 			StrokeTools->PM1->setEnabled(false);
3127 		}
3128 		//qDebug() << "SE::changeStyleSB: cursor";
3129 		Editor->textCursor().setPosition(0);
3130 		updateProps(0, 0);
3131 	}
3132 
3133 	Editor-> repaint();
3134 	modifiedText();
3135 	Editor->setFocus();
3136 }
3137 
changeStyle()3138 void StoryEditor::changeStyle()
3139 {
3140 	int p = 0;
3141 	bool sel = false;
3142 	ParagraphStyle newStyle;
3143 	newStyle.setParent(Editor->currentParaStyle);
3144 
3145 	int pos = Editor->textCursor().position();
3146 	p = Editor->StyledText.nrOfParagraph(pos);
3147 	if (Editor->StyledText.length() != 0)
3148 	{
3149 		int scrollPos = Editor->verticalScrollBar()->value();
3150 		disconnect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3151 		disconnect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3152 		disconnect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3153 		int PStart = 0;
3154 		int PEnd = 0;
3155 		int SelStart = 0;
3156 		int SelEnd = 0;
3157 		if (Editor->textCursor().hasSelection())
3158 		{
3159 			QTextCursor textCursor = Editor->textCursor();
3160 			PStart = Editor->StyledText.nrOfParagraph(textCursor.selectionStart());
3161 			PEnd = Editor->StyledText.nrOfParagraph(textCursor.selectionEnd());
3162 			SelStart = textCursor.selectionStart();
3163 			SelEnd = textCursor.selectionEnd();
3164 			sel = true;
3165 		}
3166 		else
3167 		{
3168 			PStart = p;
3169 			PEnd = p;
3170 		}
3171 		for (int pa = PStart; pa <= PEnd; ++pa)
3172 		{
3173 			Editor->StyledText.applyStyle(Editor->StyledText.startOfParagraph(pa), newStyle);
3174 			Editor->updateFromChars(pa);
3175 		}
3176 		QTextCursor textCursor = Editor->textCursor();
3177 		textCursor.setPosition(sel ? SelStart : pos);
3178 		if (sel)
3179 			textCursor.setPosition(SelEnd, QTextCursor::KeepAnchor);
3180 		Editor->setTextCursor(textCursor);
3181 		Editor->verticalScrollBar()->setValue(scrollPos);
3182 		updateProps();
3183 		EditorBar->doRepaint();
3184 		connect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3185 		connect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3186 		connect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3187 	}
3188 	else
3189 	{
3190 		const CharStyle& currentCharStyle = m_doc->paragraphStyles().get(Editor->currentParaStyle).charStyle();
3191 		Editor->prevFont = Editor->CurrFont;
3192 		Editor->CurrFont = currentCharStyle.font().scName();
3193 		Editor->CurrFontSize   = currentCharStyle.fontSize();
3194 		Editor->CurrentEffects = currentCharStyle.effects();
3195 		Editor->CurrTextFill   = currentCharStyle.fillColor();
3196 		Editor->CurrTextFillSh = currentCharStyle.fillShade();
3197 		Editor->CurrTextStroke = currentCharStyle.strokeColor();
3198 		Editor->CurrTextStrokeSh = currentCharStyle.strokeShade();
3199 		Editor->CurrTextShadowX = currentCharStyle.shadowXOffset();
3200 		Editor->CurrTextShadowY = currentCharStyle.shadowYOffset();
3201 		Editor->CurrTextOutline = currentCharStyle.outlineWidth();
3202 		Editor->CurrTextUnderPos = currentCharStyle.underlineOffset();
3203 		Editor->CurrTextUnderWidth = currentCharStyle.underlineWidth();
3204 		Editor->CurrTextStrikePos = currentCharStyle.strikethruOffset();
3205 		Editor->CurrTextStrikeWidth = currentCharStyle.strikethruWidth();
3206 
3207 		Editor->setEffects(Editor->CurrentEffects);
3208 		if ((Editor->CurrentEffects & ScStyle_Outline) || (Editor->CurrentEffects & ScStyle_Shadowed))
3209 		{
3210 			StrokeTools->TxStroke->setEnabled(true);
3211 			StrokeTools->PM1->setEnabled(true);
3212 		}
3213 		else
3214 		{
3215 			StrokeTools->TxStroke->setEnabled(false);
3216 			StrokeTools->PM1->setEnabled(false);
3217 		}
3218 		Editor->textCursor().setPosition(0);
3219 		updateProps(0, 0);
3220 	}
3221 	modifiedText();
3222 	Editor-> repaint();
3223 	Editor->setFocus();
3224 }
3225 
3226 
changeAlign(int)3227 void StoryEditor::changeAlign(int )
3228 {
3229 	int p = 0;
3230 	bool sel = false;
3231 	ParagraphStyle newStyle;
3232 	newStyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(Editor->CurrAlign));
3233 
3234 	int pos = Editor->textCursor().position();
3235 	p = Editor->StyledText.nrOfParagraph(pos);
3236 	if (Editor->StyledText.length() != 0)
3237 	{
3238 		disconnect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3239 		disconnect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3240 		disconnect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3241 		int PStart = 0;
3242 		int PEnd = 0;
3243 		int SelStart = 0;
3244 		int SelEnd = 0;
3245 		if (Editor->textCursor().hasSelection())
3246 		{
3247 			QTextCursor textCursor = Editor->textCursor();
3248 			PStart = Editor->StyledText.nrOfParagraph(textCursor.selectionStart());
3249 			PEnd = Editor->StyledText.nrOfParagraph(textCursor.selectionEnd());
3250 			SelStart = textCursor.selectionStart();
3251 			SelEnd = textCursor.selectionEnd();
3252 			sel = true;
3253 		}
3254 		else
3255 		{
3256 			PStart = p;
3257 			PEnd = p;
3258 		}
3259 		for (int pa = PStart; pa <= PEnd; ++pa)
3260 		{
3261 			Editor->StyledText.applyStyle(Editor->StyledText.startOfParagraph(pa), newStyle);
3262 			Editor->updateFromChars(pa);
3263 		}
3264 		QTextCursor textCursor = Editor->textCursor();
3265 		textCursor.setPosition(sel ? SelStart : pos);
3266 		if (sel)
3267 			textCursor.setPosition(SelEnd, QTextCursor::KeepAnchor);
3268 		Editor->setTextCursor(textCursor);
3269 		Editor->ensureCursorVisible();
3270 		updateProps();
3271 		EditorBar->doRepaint();
3272 		connect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3273 		connect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3274 		connect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3275 	}
3276 	modifiedText();
3277 	Editor->repaint();
3278 	Editor->setFocus();
3279 }
3280 
changeDirection(int)3281 void StoryEditor::changeDirection(int )
3282 {
3283 	int p = 0;
3284 	bool sel = false;
3285 	ParagraphStyle newStyle;
3286 
3287 	newStyle.setDirection(static_cast<ParagraphStyle::DirectionType>(Editor->CurrDirection));
3288 	newStyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(Editor->CurrAlign));
3289 
3290 	int pos = Editor->textCursor().position();
3291 	p = Editor->StyledText.nrOfParagraph(pos);
3292 	if (Editor->StyledText.length() != 0)
3293 	{
3294 		disconnect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3295 		disconnect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3296 		disconnect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3297 		int PStart = 0;
3298 		int PEnd = 0;
3299 		int SelStart = 0;
3300 		int SelEnd = 0;
3301 		if (Editor->textCursor().hasSelection())
3302 		{
3303 			QTextCursor textCursor = Editor->textCursor();
3304 			PStart = Editor->StyledText.nrOfParagraph(textCursor.selectionStart());
3305 			PEnd = Editor->StyledText.nrOfParagraph(textCursor.selectionEnd());
3306 			SelStart = textCursor.selectionStart();
3307 			SelEnd = textCursor.selectionEnd();
3308 			sel = true;
3309 		}
3310 		else
3311 		{
3312 			PStart = p;
3313 			PEnd = p;
3314 		}
3315 		for (int pa = PStart; pa <= PEnd; ++pa)
3316 		{
3317 			Editor->StyledText.applyStyle(Editor->StyledText.startOfParagraph(pa), newStyle);
3318 			Editor->updateFromChars(pa);
3319 		}
3320 		QTextCursor textCursor = Editor->textCursor();
3321 		textCursor.setPosition(sel ? SelStart : pos);
3322 		if (sel)
3323 			textCursor.setPosition(SelEnd, QTextCursor::KeepAnchor);
3324 		Editor->setTextCursor(textCursor);
3325 		Editor->ensureCursorVisible();
3326 		updateProps();
3327 		EditorBar->doRepaint();
3328 		connect(Editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateProps()));
3329 		connect(Editor, SIGNAL(textChanged()), this, SLOT(modifiedText()));
3330 		connect(Editor, SIGNAL(textChanged()), EditorBar, SLOT(doRepaint()));
3331 	}
3332 	modifiedText();
3333 	Editor->repaint();
3334 	Editor->setFocus();
3335 }
3336 
modifiedText()3337 void StoryEditor::modifiedText()
3338 {
3339 	m_textChanged = true;
3340 	m_firstSet = true;
3341 	seActions["fileRevert"]->setEnabled(true);
3342 	seActions["editUpdateFrame"]->setEnabled(true);
3343 //	seActions["editPaste"]->setEnabled(Editor->tBuffer.length() != 0);
3344 	updateStatus();
3345 }
3346 
LoadTextFile()3347 void StoryEditor::LoadTextFile()
3348 {
3349 	if (Do_new())
3350 	{
3351 		EditorBar->setRepaint(false);
3352 		PrefsContext* dirs = prefsManager.prefsFile->getContext("dirs");
3353 		QString wdir = dirs->get("story_load", prefsManager.documentDir());
3354 		CustomFDialog dia(this, wdir, tr("Open"), tr("Text Files (*.txt);;All Files (*)"), fdExistingFiles | fdShowCodecs | fdDisableOk);
3355 		if (dia.exec() != QDialog::Accepted)
3356 			return;
3357 		QString textEncoding = dia.textCodec();
3358 		QString fileName =  dia.selectedFile();
3359 		if (!fileName.isEmpty())
3360 		{
3361 			dirs->set("story_load", fileName.left(fileName.lastIndexOf("/")));
3362 			QString txt;
3363 			if (Serializer::readWithEncoding(fileName, textEncoding, txt))
3364 			{
3365 				txt.replace(QRegExp("\r"), "");
3366 				txt.replace(QRegExp("\n"), QChar(13));
3367 				Editor->loadText(txt, m_item);
3368 				seActions["editPaste"]->setEnabled(false);
3369 				seActions["editCopy"]->setEnabled(false);
3370 				seActions["editCut"]->setEnabled(false);
3371 				seActions["editClear"]->setEnabled(false);
3372 			}
3373 		}
3374 		EditorBar->setRepaint(true);
3375 		EditorBar->doRepaint();
3376 	}
3377 	Editor-> repaint();
3378 }
3379 
SaveTextFile()3380 void StoryEditor::SaveTextFile()
3381 {
3382 	QScopedValueRollback<bool> blockUpdateRollback(m_blockUpdate);
3383 	PrefsContext* dirsContext = prefsManager.prefsFile->getContext("dirs");
3384 	PrefsContext* textContext = prefsManager.prefsFile->getContext("textsave_dialog");
3385 	QString prefsDocDir = prefsManager.documentDir();
3386 	QString workingDir = dirsContext->get("save_text", prefsDocDir.isEmpty() ? "." : prefsDocDir);
3387 	QString textEncoding = textContext->get("encoding");
3388 
3389 	CustomFDialog dia(this, workingDir, tr("Save as"), tr("Text Files (*.txt);;All Files (*)"), fdShowCodecs|fdHidePreviewCheckBox);
3390 	dia.setTextCodec(textEncoding);
3391 	if (dia.exec() != QDialog::Accepted)
3392 		return;
3393 
3394 	QString fileName = dia.selectedFile();
3395 	if (fileName.isEmpty())
3396 		return;
3397 	textEncoding = dia.textCodec();
3398 
3399 	dirsContext->set("save_text", fileName.left(fileName.lastIndexOf("/")));
3400 	textContext->set("encoding", dia.textCodec());
3401 	Serializer::writeWithEncoding(fileName, textEncoding, Editor->StyledText.plainText());
3402 }
3403 
textDataChanged() const3404 bool StoryEditor::textDataChanged() const
3405 {
3406 	return m_textChanged;
3407 }
3408 
currentItem() const3409 PageItem* StoryEditor::currentItem() const
3410 {
3411 	return m_item;
3412 }
3413 
currentDocument() const3414 ScribusDoc* StoryEditor::currentDocument() const
3415 {
3416 	return m_doc;
3417 }
3418 
specialActionKeyEvent(int unicodevalue)3419 void StoryEditor::specialActionKeyEvent(int unicodevalue)
3420 {
3421 	QString guiInsertString = QChar(unicodevalue);
3422 	bool setColor = false;
3423 	if (unicodevalue == seActions["unicodePageNumber"]->actionInt())
3424 	{
3425 		setColor = true;
3426 		guiInsertString = "#";
3427 	}
3428 	if (unicodevalue == seActions["unicodeNonBreakingSpace"]->actionInt())
3429 	{
3430 		setColor = true;
3431 		guiInsertString = "_";
3432 	}
3433 	if (unicodevalue == seActions["unicodeFrameBreak"]->actionInt())
3434 	{
3435 		setColor = true;
3436 		guiInsertString = "|";
3437 	}
3438 	if (unicodevalue == seActions["unicodeNewLine"]->actionInt())
3439 	{
3440 		setColor = true;
3441 		guiInsertString = "*";
3442 	}
3443 	if (unicodevalue == seActions["unicodeColumnBreak"]->actionInt())
3444 	{
3445 		setColor = true;
3446 		guiInsertString = "^";
3447 	}
3448 	if (unicodevalue == seActions["unicodeNonBreakingHyphen"]->actionInt())
3449 	{
3450 		setColor = true;
3451 		guiInsertString = "=";
3452 	}
3453 	if (setColor)
3454 		Editor->setColor(true);
3455 	Editor->insertChars(QString(QChar(unicodevalue)), guiInsertString);
3456 	if (setColor)
3457 		Editor->setColor(false);
3458 	modifiedText();
3459 	EditorBar->setRepaint(true);
3460 	EditorBar->doRepaint();
3461 }
3462 
updateUnicodeActions()3463 void StoryEditor::updateUnicodeActions()
3464 {
3465 	if (Editor->prevFont != Editor->CurrFont)
3466 		ScCore->primaryMainWindow()->actionManager->enableUnicodeActions(&seActions, true, Editor->CurrFont);
3467 }
3468