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 #include <QEvent>
9 #include <QMessageBox>
10 #include <QTabWidget>
11 
12 #include "alignselect.h"
13 #include "colorcombo.h"
14 #include "commonstrings.h"
15 #include "fontcombo.h"
16 #include "langmgr.h"
17 #include "ui/scmwmenumanager.h"
18 #include "prefsmanager.h"
19 #include "scribus.h"
20 #include "scribusdoc.h"
21 #include "scrspinbox.h"
22 #include "selection.h"
23 #include "shadebutton.h"
24 #include "smalignselect.h"
25 #include "smcolorcombo.h"
26 #include "smcstylewidget.h"
27 #include "smpstylewidget.h"
28 #include "smsccombobox.h"
29 #include "smshadebutton.h"
30 #include "smspinbox.h"
31 #include "smtabruler.h"
32 #include "smtextstyles.h"
33 #include "storyeditor.h"
34 #include "style.h"
35 #include "styleselect.h"
36 #include "tabruler.h"
37 #include "units.h"
38 #include "util.h"
39 
40 
SMParagraphStyle(SMCharacterStyle * cstyleItem)41 SMParagraphStyle::SMParagraphStyle(SMCharacterStyle* cstyleItem):
42 	m_cstyleItem(cstyleItem)
43 {
44 	Q_ASSERT(m_cstyleItem);
45 	m_cstyles = m_cstyleItem->tmpStyles();
46 	m_pwidget = new SMPStyleWidget(m_doc, m_cstyles);
47 	Q_CHECK_PTR(m_pwidget);
48 }
49 
widget()50 QTabWidget* SMParagraphStyle::widget()
51 {
52 	return m_pwidget->tabWidget;
53 }
54 
typeNamePlural()55 QString SMParagraphStyle::typeNamePlural()
56 {
57 	return tr("Paragraph Styles");
58 }
59 
typeNameSingular()60 QString SMParagraphStyle::typeNameSingular()
61 {
62 	return tr("Paragraph Style");
63 }
64 
setCurrentDoc(ScribusDoc * doc)65 void SMParagraphStyle::setCurrentDoc(ScribusDoc *doc)
66 {
67 	m_doc = doc;
68 	if (m_doc)
69 	{
70 		if (m_pwidget)
71 		{
72 			m_pwidget->setDoc(m_doc);
73 			if (m_unitRatio != m_doc->unitRatio())
74 				unitChange();
75 		}
76 	}
77 	else
78 	{
79 		if (m_pwidget)
80 			m_pwidget->setDoc(nullptr);
81 		removeConnections();
82 		m_selection.clear();
83 		m_tmpStyles.clear();
84 		m_deleted.clear();
85 	}
86 }
87 
tmpStyles()88 StyleSet<ParagraphStyle>* SMParagraphStyle::tmpStyles()
89 {
90 	return &m_tmpStyles;
91 }
92 
styles(bool reloadFromDoc)93 QList<StyleName> SMParagraphStyle::styles(bool reloadFromDoc)
94 {
95 	QList<StyleName> tmpList;
96 
97 	if (!m_doc)
98 		return tmpList; // no doc available
99 
100 	if (reloadFromDoc)
101 	{
102 		m_deleted.clear();
103 		reloadTmpStyles();
104 	}
105 
106 	for (int i = 0; i < m_tmpStyles.count(); ++i)
107 	{
108 		if (m_tmpStyles[i].hasName())
109 		{
110 			QString styleName(m_tmpStyles[i].displayName());
111 			QString parentName;
112 
113 			if (m_tmpStyles[i].hasParent())
114 			{
115 				const BaseStyle* parentStyle = m_tmpStyles[i].parentStyle();
116 				if (parentStyle)
117 					parentName = parentStyle->displayName();
118 			}
119 
120 			tmpList << StyleName(styleName, parentName);
121 		}
122 	}
123 	std::sort(tmpList.begin(), tmpList.end(), sortingQPairOfStrings);
124 
125 	return tmpList;
126 }
127 
reload()128 void SMParagraphStyle::reload()
129 {
130 	reloadTmpStyles();
131 }
132 
selected(const QStringList & styleNames)133 void SMParagraphStyle::selected(const QStringList &styleNames)
134 {
135 	if (!m_doc)
136 		return;
137 
138 	m_selection.clear();
139 	m_selectionIsDirty = false;
140 	removeConnections(); // we don't want to record changes during style setup
141 
142 	m_tmpStyles.invalidate();
143 
144 	QList<ParagraphStyle> pstyles; // get saved styles
145 	QList<CharStyle> cstyles;
146 	for (int i = 0; i < m_tmpStyles.count(); ++i)
147 		pstyles << m_tmpStyles[i];
148 	for (int i = 0; i < m_cstyles->count(); ++i)
149 		cstyles << (*m_cstyles)[i];
150 
151 	int index;
152 	for (int i = 0; i < styleNames.count(); ++i)
153 	{
154 		index = m_tmpStyles.find(styleNames[i]);
155 		//FIXME: #7133: Use .isDefaultStyle() instead here rather than relying on tr text comparison
156 		if (index<0 && styleNames[i]==CommonStrings::trDefaultParagraphStyle)
157 			index = m_tmpStyles.find(CommonStrings::DefaultParagraphStyle);
158 		if (index > -1)
159 			m_selection.append(&m_tmpStyles[index]);
160 	}
161 
162 	m_pwidget->show(m_selection, pstyles, cstyles, m_doc->unitIndex(), PrefsManager::instance().appPrefs.docSetupPrefs.language);
163 
164 	setupConnections();
165 }
166 
getCharStyles()167 QList<CharStyle> SMParagraphStyle::getCharStyles()
168 {
169 	QList<CharStyle> charStyles;
170 	if (!m_doc)
171 		return charStyles; // no doc available
172 
173 	const StyleSet<CharStyle> &tmp(m_doc->charStyles());
174 	for (int i = 0; i < tmp.count(); ++i)
175 		charStyles.append(tmp[i]);
176 	return charStyles;
177 }
178 
fromSelection() const179 QString SMParagraphStyle::fromSelection() const
180 {
181 	QString lsName;
182 	if (!m_doc)
183 		return lsName; // no doc available
184 
185 	for (int i = 0; i < m_doc->m_Selection->count(); ++i)
186 	{
187 		// wth is going on here
188 		PageItem *item = m_doc->m_Selection->itemAt(i);
189 
190 		QString tmpName = item->itemText.defaultStyle().parent();
191 
192 		if (lsName.isNull() && !tmpName.isEmpty() && tmpName != "")
193 		{
194 			lsName = tmpName;
195 		}
196 		else if (!lsName.isNull() && !tmpName.isEmpty() && tmpName != "" && lsName != tmpName)
197 		{
198 			lsName.clear();
199 			break;
200 		}
201 	}
202 	return lsName;
203 }
204 
toSelection(const QString & styleName) const205 void SMParagraphStyle::toSelection(const QString &styleName) const
206 {
207 	if (!m_doc)
208 		return; // nowhere to apply or no doc
209 
210 	QString realName = styleName;
211 	int styleIndex = m_tmpStyles.find(styleName);
212 	if (styleIndex < 0 && (styleName == CommonStrings::trDefaultParagraphStyle))
213 	{
214 		styleIndex = m_tmpStyles.find(CommonStrings::DefaultParagraphStyle);
215 		if (styleIndex >= 0)
216 			realName = CommonStrings::DefaultParagraphStyle;
217 	}
218 	if (styleIndex >= 0)
219 	{
220 		m_doc->itemSelection_SetNamedParagraphStyle(realName);
221 	}
222 }
223 
newStyle()224 QString SMParagraphStyle::newStyle()
225 {
226 	if (!m_doc)
227 		return QString();
228 
229 	QString s(getUniqueName( tr("New Style")));
230 	ParagraphStyle p;
231 	p.setDefaultStyle(false);
232 	p.setName(s);
233 	p.charStyle().setLanguage(m_doc->language());
234 	m_tmpStyles.create(p);
235 	return s;
236 }
237 
newStyle(const QString & fromStyle)238 QString SMParagraphStyle::newStyle(const QString &fromStyle)
239 {
240 	//#7179, do our name switch yet again to handle this properly for default styles
241 	//FIXME: use isDefaultStyle somehow
242 	QString copiedStyleName(fromStyle);
243 	if (fromStyle==CommonStrings::trDefaultParagraphStyle)
244 		copiedStyleName=CommonStrings::DefaultParagraphStyle;
245 
246 	Q_ASSERT(m_tmpStyles.resolve(copiedStyleName));
247 	if (!m_tmpStyles.resolve(copiedStyleName))
248 		return QString();
249 
250 	//Copy the style with the original name
251 	QString s(getUniqueName(fromStyle));
252 	ParagraphStyle p(m_tmpStyles.get(copiedStyleName));
253 	p.setDefaultStyle(false);
254 	p.setName(s);
255 	p.setShortcut(QString()); // do not clone the sc
256 	m_tmpStyles.create(p);
257 
258 	return s;
259 }
260 
261 // helper function to find a unique name to a new style or a clone
getUniqueName(const QString & name)262 QString SMParagraphStyle::getUniqueName(const QString &name)
263 {
264 	return m_tmpStyles.getUniqueCopyName(name);
265 }
266 
apply()267 void SMParagraphStyle::apply()
268 {
269 	if (!m_doc)
270 		return;
271 
272 	QMap<QString, QString> replacement;
273 	for (int i = 0; i < m_deleted.count(); ++i)
274 	{
275 		if (m_deleted[i].first == m_deleted[i].second)
276 			continue;
277 		replacement[m_deleted[i].first] = m_deleted[i].second;
278 	}
279 	m_doc->redefineStyles(m_tmpStyles, false);
280 	m_doc->replaceStyles(replacement);
281 
282 	m_deleted.clear(); // deletion done at this point
283 
284 	m_doc->scMW()->requestUpdate(reqTextStylesUpdate);
285 	// Better not call DrawNew() here, as this will cause several unnecessary calls
286 	// m_doc->view()->DrawNew();
287 	m_doc->changed();
288 }
289 
editMode(bool isOn)290 void SMParagraphStyle::editMode(bool isOn)
291 {
292 	if (isOn)
293 		reloadTmpStyles();
294 }
295 
isDefaultStyle(const QString & stylename) const296 bool SMParagraphStyle::isDefaultStyle(const QString &stylename) const
297 {
298 	int index = m_tmpStyles.find(stylename);
299 	bool b=false;
300 	if (index > -1)
301 		b = m_tmpStyles[index].isDefaultStyle();
302 	else
303 	{
304 		if (CommonStrings::trDefaultParagraphStyle==stylename)
305 		{
306 			index = m_tmpStyles.find(CommonStrings::DefaultParagraphStyle);
307 			if (index > -1)
308 				b = m_tmpStyles[index].isDefaultStyle();
309 		}
310 	}
311 	return b;
312 }
313 
setDefaultStyle(bool ids)314 void SMParagraphStyle::setDefaultStyle(bool ids)
315 {
316 	Q_ASSERT(m_selection.count() == 1);
317 	if (m_selection.count() != 1)
318 		return;
319 
320 	m_selection[0]->setDefaultStyle(ids);
321 
322 	slotSelectionDirty();
323 }
324 
shortcut(const QString & stylename) const325 QString SMParagraphStyle::shortcut(const QString &stylename) const
326 {
327 	QString s;
328 
329 	int index = m_tmpStyles.find(stylename);
330 	if (index > -1)
331 		s = m_tmpStyles[index].shortcut();
332 	else
333 	{
334 		//FIXME: Use isDefaultStyle somehow
335 		if (CommonStrings::trDefaultParagraphStyle==stylename)
336 		{
337 			index = m_tmpStyles.find(CommonStrings::DefaultParagraphStyle);
338 			if (index > -1)
339 				s = m_tmpStyles[index].shortcut();
340 		}
341 	}
342 
343 	return s;
344 }
345 
setShortcut(const QString & shortcut)346 void SMParagraphStyle::setShortcut(const QString &shortcut)
347 {
348 	Q_ASSERT(m_selection.count() == 1);
349 	if (m_selection.count() != 1)
350 		return;
351 
352 	m_selection[0]->setShortcut(shortcut);
353 
354 	slotSelectionDirty();
355 }
356 
deleteStyles(const QList<RemoveItem> & removeList)357 void SMParagraphStyle::deleteStyles(const QList<RemoveItem> &removeList)
358 {
359 	for (int i = 0; i < removeList.count(); ++i)
360 	{
361 		for (int k = 0; k < m_selection.count(); ++k)
362 		{
363 			if (m_selection[k]->name() == removeList[i].first)
364 			{
365 				m_selection.removeAt(k);
366 				break;
367 			}
368 		}
369 
370 		int index = m_tmpStyles.find(removeList[i].first);
371 		if (index > -1)
372 			m_tmpStyles.remove(index);
373 
374 		m_deleted.append(removeList[i]);
375 	}
376 
377 	// Check other paragraph styles and replace inherited styles if necessary
378 	for (int i = 0; i < m_tmpStyles.count(); ++i)
379 	{
380 		ParagraphStyle& parStyle = m_tmpStyles[i];
381 		QString parentName = parStyle.parent();
382 		if (parentName.isEmpty())
383 			continue;
384 
385 		QString replacementName = parentName;
386 		for (int j = 0; j < removeList.count(); ++j)
387 		{
388 			if (removeList.at(j).first == parentName)
389 			{
390 				replacementName = removeList.at(j).second;
391 				break;
392 			}
393 		}
394 
395 		if (replacementName == parentName)
396 			continue;
397 		if (replacementName == CommonStrings::trDefaultParagraphStyle)
398 			replacementName = CommonStrings::DefaultParagraphStyle;
399 		if (!parStyle.canInherit(replacementName))
400 			replacementName = QString();
401 		if (!replacementName.isEmpty() && (m_tmpStyles.find(replacementName) < 0))
402 			replacementName = QString();
403 		parStyle.setParent(replacementName);
404 	}
405 }
406 
nameChanged(const QString & newName)407 void SMParagraphStyle::nameChanged(const QString &newName)
408 {
409 	if (m_selection.count() != 1)
410 		return;
411 
412 	QString oldName(m_selection[0]->name());
413 	ParagraphStyle p(*m_selection[0]);
414 	p.setName(newName);
415 	m_tmpStyles.create(p);
416 	m_selection.clear();
417 	m_selection.append(&m_tmpStyles[m_tmpStyles.find(newName)]);
418 	for (int j = 0; j < m_tmpStyles.count(); ++j)
419 	{
420 		int index = m_tmpStyles.find(oldName);
421 		if (index > -1)
422 		{
423 			m_tmpStyles.remove(index);
424 			break;
425 		}
426 	}
427 
428 	for (int j = 0; j < m_tmpStyles.count(); ++j)
429 	{
430 		if (m_tmpStyles[j].parent() == oldName)
431 			m_tmpStyles[j].setParent(newName);
432 	}
433 
434 	QList<RemoveItem>::iterator it;
435 	for (it = m_deleted.begin(); it != m_deleted.end(); ++it)
436 	{
437 		if (it->second == oldName)
438 		{
439 			oldName = (*it).first;
440 			m_deleted.erase(it);
441 			break;
442 		}
443 	}
444 
445 	if (oldName != newName)
446 		m_deleted.append(RemoveItem(oldName, newName));
447 
448 	slotSelectionDirty();
449 }
450 
languageChange()451 void SMParagraphStyle::languageChange()
452 {
453 	if (m_pwidget)
454 	{
455 		m_pwidget->languageChange();
456 		m_pwidget->cpage->languageChange();
457 	}
458 }
459 
unitChange()460 void SMParagraphStyle::unitChange()
461 {
462 	double oldRatio = m_unitRatio;
463 	m_unitRatio = m_doc->unitRatio();
464 	m_pwidget->unitChange(oldRatio, m_unitRatio, m_doc->unitIndex());
465 }
466 
reloadTmpStyles()467 void SMParagraphStyle::reloadTmpStyles()
468 {
469 	if (!m_doc)
470 		return;
471 
472 	m_selection.clear();
473 	m_tmpStyles.clear();
474 	m_deleted.clear();
475 	m_tmpStyles.redefine(m_doc->paragraphStyles(), true);
476 	Q_ASSERT(m_tmpStyles.count() > 0);
477 	m_tmpStyles[0].charStyle().setContext(m_cstyles);
478 }
479 
setupConnections()480 void SMParagraphStyle::setupConnections()
481 {
482 	if (!m_pwidget)
483 		return;
484 
485 	// paragraph attributes
486 	connect(m_pwidget->lineSpacingMode, SIGNAL(activated(int)), this, SLOT(slotLineSpacingMode(int)));
487 	connect(m_pwidget->lineSpacing, SIGNAL(valueChanged(double)), this, SLOT(slotLineSpacing()));
488 	connect(m_pwidget->spaceAbove, SIGNAL(valueChanged(double)), this, SLOT(slotSpaceAbove()));
489 	connect(m_pwidget->spaceBelow, SIGNAL(valueChanged(double)), this, SLOT(slotSpaceBelow()));
490 	connect(m_pwidget->alignment->TextL, SIGNAL(clicked()), this, SLOT(slotAlignment()));
491 	connect(m_pwidget->alignment->TextR, SIGNAL(clicked()), this, SLOT(slotAlignment()));
492 	connect(m_pwidget->alignment->TextC, SIGNAL(clicked()), this, SLOT(slotAlignment()));
493 	connect(m_pwidget->alignment->TextB, SIGNAL(clicked()), this, SLOT(slotAlignment()));
494 	connect(m_pwidget->alignment->TextF, SIGNAL(clicked()), this, SLOT(slotAlignment()));
495 	connect(m_pwidget->alignment->parentButton, SIGNAL(clicked()), this, SLOT(slotAlignment()));
496 	connect(m_pwidget->direction->RTL, SIGNAL(clicked()), this, SLOT(slotDirection()));
497 	connect(m_pwidget->direction->LTR, SIGNAL(clicked()), this, SLOT(slotDirection()));
498 	connect(m_pwidget->direction->parentButton, SIGNAL(clicked()), this, SLOT(slotDirection()));
499 //	connect(m_pwidget->optMarginCombo, SIGNAL(activated(int)), this, SLOT(slotOpticalMargin(int)));
500 	connect(m_pwidget->optMarginRadioNone, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
501 	connect(m_pwidget->optMarginRadioLeft, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
502 	connect(m_pwidget->optMarginRadioRight, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
503 	connect(m_pwidget->optMarginRadioBoth, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
504 	connect(m_pwidget, SIGNAL(useParentOptMargins()), this, SLOT(slotParentOpticalMargin()));
505 
506 	connect(m_pwidget->minSpaceSpin, SIGNAL(valueChanged(double)),this,SLOT(slotMinSpace()));
507 	connect(m_pwidget->minGlyphExtSpin, SIGNAL(valueChanged(double)),this,SLOT(slotMinGlyphExt()));
508 	connect(m_pwidget->maxGlyphExtSpin, SIGNAL(valueChanged(double)),this,SLOT(slotMaxGlyphExt()));
509 
510 	connect(m_pwidget->maxConsecutiveCountSpinBox, SIGNAL(valueChanged(int)),this,SLOT(slotConsecutiveLines()));
511 
512 	connect(m_pwidget, SIGNAL(useParentParaEffects()), this, SLOT(slotParentParaEffects()));
513 	connect(m_pwidget->dropCapsBox, SIGNAL(toggled(bool)), this, SLOT(slotDropCap(bool)));
514 	connect(m_pwidget->dropCapLines, SIGNAL(valueChanged(int)), this, SLOT(slotDropCapLines(int)));
515 	connect(m_pwidget->parEffectOffset, SIGNAL(valueChanged(double)), this, SLOT(slotParEffectOffset()));
516 	connect(m_pwidget->parEffectIndentBox, SIGNAL(toggled(bool)), this, SLOT(slotParEffectIndent(bool)));
517 	connect(m_pwidget->parEffectCharStyleCombo, SIGNAL(activated(int)), this, SLOT(slotParEffectCharStyle(int)));
518 
519 	connect(m_pwidget->bulletBox, SIGNAL(toggled(bool)), this, SLOT(slotBullet(bool)));
520 	connect(m_pwidget->bulletStrEdit, SIGNAL(editTextChanged(QString)), this, SLOT(slotBulletStr(QString)));
521 	connect(m_pwidget->numBox, SIGNAL(toggled(bool)), this, SLOT(slotNumeration(bool)));
522 	connect(m_pwidget->numComboBox, SIGNAL(activated(QString)), this, SLOT(slotNumName(QString)));
523 	connect(m_pwidget->numLevelSpin, SIGNAL(valueChanged(int)), this, SLOT(slotNumLevel(int)));
524 	connect(m_pwidget->numFormatCombo, SIGNAL(activated(int)), this, SLOT(slotNumFormat(int)));
525 	connect(m_pwidget->numStartSpin, SIGNAL(valueChanged(int)), this, SLOT(slotNumStart(int)));
526 	connect(m_pwidget->numRestartCombo, SIGNAL(activated(int)), this, SLOT(slotNumRestart(int)));
527 	connect(m_pwidget->numRestartOtherBox, SIGNAL(toggled(bool)), this, SLOT(slotNumOther(bool)));
528 	connect(m_pwidget->numRestartHigherBox, SIGNAL(toggled(bool)), this, SLOT(slotNumHigher(bool)));
529 	connect(m_pwidget->numPrefix, SIGNAL(textChanged(QString)), this, SLOT(slotNumPrefix(QString)));
530 	connect(m_pwidget->numSuffix, SIGNAL(textChanged(QString)), this, SLOT(slotNumSuffix(QString)));
531 	connect(m_pwidget->numNewLineEdit, SIGNAL(editingFinished()), this, SLOT(slotNumNew()));
532 	connect(m_pwidget->numNewLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSelectionDirty()));
533 
534 	connect(m_pwidget->keepLinesStart, SIGNAL(valueChanged(int)), this, SLOT(handleKeepLinesStart()));
535 	connect(m_pwidget->keepLinesEnd, SIGNAL(valueChanged(int)), this, SLOT(handleKeepLinesEnd()));
536 	connect(m_pwidget->keepTogether, SIGNAL(stateChanged(int)), this, SLOT(handleKeepTogether()));
537 	connect(m_pwidget->keepWithNext, SIGNAL(stateChanged(int)), this, SLOT(handleKeepWithNext()));
538 
539 	connect(m_pwidget->tabList, SIGNAL(tabsChanged()), this, SLOT(slotTabRuler()));
540 	connect(m_pwidget->tabList, SIGNAL(mouseReleased()), this, SLOT(slotTabRuler()));
541 	connect(m_pwidget->tabList->leftIndentSpin, SIGNAL(valueChanged(double)), this, SLOT(slotLeftIndent()));
542 	connect(m_pwidget->tabList->rightIndentSpin, SIGNAL(valueChanged(double)), this, SLOT(slotRightIndent()));
543 	connect(m_pwidget->tabList->firstLineSpin, SIGNAL(valueChanged(double)), this, SLOT(slotFirstLine()));
544 
545 	connect(m_pwidget->parentCombo, SIGNAL(activated(const QString&)), this, SLOT(slotParentChanged(const QString&)));
546 	connect(m_pwidget->backColor_, SIGNAL(activated(const QString&)), this, SLOT(slotBackPColor()));
547 	connect(m_pwidget->backShade_, SIGNAL(clicked()), this, SLOT(slotBackPShade()));
548 
549 	// character attributes
550 	connect(m_pwidget->cpage->fontFace_, SIGNAL(fontSelected(QString)), this, SLOT(slotFont(QString)));
551 	connect(m_pwidget->cpage->effects_, SIGNAL(State(int)), this, SLOT(slotEffects(int)));
552 	connect(m_pwidget->cpage->effects_->ShadowVal->Xoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
553 	connect(m_pwidget->cpage->effects_->ShadowVal->Yoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
554 	connect(m_pwidget->cpage->effects_->OutlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
555 	connect(m_pwidget->cpage->effects_->UnderlineVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
556 	connect(m_pwidget->cpage->effects_->UnderlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
557 	connect(m_pwidget->cpage->effects_->StrikeVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
558 	connect(m_pwidget->cpage->effects_->StrikeVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
559 	connect(m_pwidget->cpage->fillColor_, SIGNAL(activated(const QString&)), this, SLOT(slotFillColor()));
560 	connect(m_pwidget->cpage->fillShade_, SIGNAL(clicked()), this, SLOT(slotFillShade()));
561 	connect(m_pwidget->cpage->strokeColor_, SIGNAL(activated(const QString&)), this, SLOT(slotStrokeColor()));
562 	connect(m_pwidget->cpage->strokeShade_, SIGNAL(clicked()), this, SLOT(slotStrokeShade()));
563 	connect(m_pwidget->cpage->language_, SIGNAL(activated(int)), this, SLOT(slotLanguage()));
564 	connect(m_pwidget->cpage->fontSize_, SIGNAL(valueChanged(double)), this, SLOT(slotFontSize()));
565 	connect(m_pwidget->cpage->fontHScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleH()));
566 	connect(m_pwidget->cpage->fontVScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleV()));
567 	connect(m_pwidget->cpage->tracking_, SIGNAL(valueChanged(double)), this, SLOT(slotTracking()));
568 	connect(m_pwidget->cpage->widthSpaceSpin, SIGNAL(valueChanged(double)), this, SLOT(slotWordTracking()));
569 	connect(m_pwidget->cpage->baselineOffset_, SIGNAL(valueChanged(double)), this, SLOT(slotBaselineOffset()));
570 	connect(m_pwidget->cpage->parentCombo, SIGNAL(activated(const QString&)), this, SLOT(slotCharParentChanged(const QString&)));
571 	connect(m_pwidget->cpage->backColor_, SIGNAL(activated(const QString&)), this, SLOT(slotBackColor()));
572 	connect(m_pwidget->cpage->backShade_, SIGNAL(clicked()), this, SLOT(slotBackShade()));
573 	connect(m_pwidget->cpage->fontfeaturesSetting,SIGNAL(changed()), this, SLOT(slotFontFeatures()));
574 	connect(m_pwidget->cpage->hyphenCharLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotHyphenChar()));
575 	connect(m_pwidget->cpage->smallestWordSpinBox, SIGNAL(valueChanged(int)), this, SLOT(slotWordMin()));
576 
577 	// Referenced character style changes
578 	connect(m_cstyleItem, SIGNAL(charStylesDeleted(const QList<RemoveItem>&)), this, SLOT(slotCharStylesDeleted(const QList<RemoveItem>&)));
579 }
580 
removeConnections()581 void SMParagraphStyle::removeConnections()
582 {
583 	if (!m_pwidget)
584 		return;
585 
586 	disconnect(m_pwidget->lineSpacingMode, SIGNAL(activated(int)), this, SLOT(slotLineSpacingMode(int)));
587 	disconnect(m_pwidget->lineSpacing, SIGNAL(valueChanged(double)), this, SLOT(slotLineSpacing()));
588 	disconnect(m_pwidget->spaceAbove, SIGNAL(valueChanged(double)), this, SLOT(slotSpaceAbove()));
589 	disconnect(m_pwidget->spaceBelow, SIGNAL(valueChanged(double)), this, SLOT(slotSpaceBelow()));
590 	disconnect(m_pwidget->alignment->TextL, SIGNAL(clicked()), this, SLOT(slotAlignment()));
591 	disconnect(m_pwidget->alignment->TextR, SIGNAL(clicked()), this, SLOT(slotAlignment()));
592 	disconnect(m_pwidget->alignment->TextC, SIGNAL(clicked()), this, SLOT(slotAlignment()));
593 	disconnect(m_pwidget->alignment->TextB, SIGNAL(clicked()), this, SLOT(slotAlignment()));
594 	disconnect(m_pwidget->alignment->TextF, SIGNAL(clicked()), this, SLOT(slotAlignment()));
595 	disconnect(m_pwidget->alignment->parentButton, SIGNAL(clicked()), this, SLOT(slotAlignment()));
596 	disconnect(m_pwidget->direction->RTL, SIGNAL(clicked()), this, SLOT(slotDirection()));
597 	disconnect(m_pwidget->direction->LTR, SIGNAL(clicked()), this, SLOT(slotDirection()));
598 	disconnect(m_pwidget->direction->parentButton, SIGNAL(clicked()), this, SLOT(slotDirection()));
599 //	disconnect(m_pwidget->optMarginCombo, SIGNAL(activated(int)), this, SLOT(slotOpticalMargin(int)));
600 	disconnect(m_pwidget->optMarginRadioNone, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
601 	disconnect(m_pwidget->optMarginRadioLeft, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
602 	disconnect(m_pwidget->optMarginRadioRight, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
603 	disconnect(m_pwidget->optMarginRadioBoth, SIGNAL(clicked()), this, SLOT(slotOpticalMarginSelector()));
604 
605 	disconnect(m_pwidget->minSpaceSpin, SIGNAL(valueChanged(double)),this,SLOT(slotMinSpace()));
606 	disconnect(m_pwidget->minGlyphExtSpin, SIGNAL(valueChanged(double)),this,SLOT(slotMinGlyphExt()));
607 	disconnect(m_pwidget->maxGlyphExtSpin, SIGNAL(valueChanged(double)),this,SLOT(slotMaxGlyphExt()));
608 
609 	disconnect(m_pwidget->maxConsecutiveCountSpinBox, SIGNAL(valueChanged(int)),this,SLOT(slotConsecutiveLines()));
610 
611 	disconnect(m_pwidget, SIGNAL(useParentParaEffects()), this, SLOT(slotParentParaEffects()));
612 	disconnect(m_pwidget->dropCapsBox, SIGNAL(toggled(bool)), this, SLOT(slotDropCap(bool)));
613 	disconnect(m_pwidget->dropCapLines, SIGNAL(valueChanged(int)), this, SLOT(slotDropCapLines(int)));
614 	disconnect(m_pwidget->parEffectOffset, SIGNAL(valueChanged(double)), this, SLOT(slotParEffectOffset()));
615 	disconnect(m_pwidget->parEffectIndentBox, SIGNAL(toggled(bool)), this, SLOT(slotParEffectIndent(bool)));
616 	disconnect(m_pwidget->parEffectCharStyleCombo, SIGNAL(activated(int)), this, SLOT(slotParEffectCharStyle(int)));
617 
618 	disconnect(m_pwidget->bulletBox, SIGNAL(toggled(bool)), this, SLOT(slotBullet(bool)));
619 	disconnect(m_pwidget->bulletStrEdit, SIGNAL(editTextChanged(QString)), this, SLOT(slotBulletStr(QString)));
620 	disconnect(m_pwidget->numBox, SIGNAL(toggled(bool)), this, SLOT(slotNumeration(bool)));
621 	disconnect(m_pwidget->numComboBox, SIGNAL(activated(QString)), this, SLOT(slotNumName(QString)));
622 	disconnect(m_pwidget->numFormatCombo, SIGNAL(activated(int)), this, SLOT(slotNumFormat(int)));
623 	disconnect(m_pwidget->numLevelSpin, SIGNAL(valueChanged(int)), this, SLOT(slotNumLevel(int)));
624 	disconnect(m_pwidget->numStartSpin, SIGNAL(valueChanged(int)), this, SLOT(slotNumStart(int)));
625 	disconnect(m_pwidget->numRestartCombo, SIGNAL(activated(int)), this, SLOT(slotNumRestart(int)));
626 	disconnect(m_pwidget->numRestartOtherBox, SIGNAL(toggled(bool)), this, SLOT(slotNumOther(bool)));
627 	disconnect(m_pwidget->numRestartHigherBox, SIGNAL(toggled(bool)), this, SLOT(slotNumHigher(bool)));
628 	disconnect(m_pwidget->numPrefix, SIGNAL(textChanged(QString)), this, SLOT(slotNumPrefix(QString)));
629 	disconnect(m_pwidget->numSuffix, SIGNAL(textChanged(QString)), this, SLOT(slotNumSuffix(QString)));
630 	disconnect(m_pwidget->numNewLineEdit, SIGNAL(editingFinished()), this, SLOT(slotNumNew()));
631 	disconnect(m_pwidget->numNewLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotSelectionDirty()));
632 
633 	disconnect(m_pwidget->parentCombo, SIGNAL(activated(const QString&)), this, SLOT(slotParentChanged(const QString&)));
634 
635 	disconnect(m_pwidget->keepLinesStart, SIGNAL(valueChanged(int)), this, SLOT(handleKeepLinesStart()));
636 	disconnect(m_pwidget->keepLinesEnd, SIGNAL(valueChanged(int)), this, SLOT(handleKeepLinesEnd()));
637 	disconnect(m_pwidget->keepTogether, SIGNAL(stateChanged(int)), this, SLOT(handleKeepTogether()));
638 	disconnect(m_pwidget->keepWithNext, SIGNAL(stateChanged(int)), this, SLOT(handleKeepWithNext()));
639 
640 	disconnect(m_pwidget->tabList, SIGNAL(tabsChanged()), this, SLOT(slotTabRuler()));
641 	disconnect(m_pwidget->tabList->leftIndentSpin, SIGNAL(valueChanged(double)), this, SLOT(slotLeftIndent()));
642 	disconnect(m_pwidget->tabList->rightIndentSpin, SIGNAL(valueChanged(double)), this, SLOT(slotRightIndent()));
643 	disconnect(m_pwidget->tabList->firstLineSpin, SIGNAL(valueChanged(double)), this, SLOT(slotFirstLine()));
644 	disconnect(m_pwidget->backColor_, SIGNAL(activated(const QString&)), this, SLOT(slotBackPColor()));
645 	disconnect(m_pwidget->backShade_, SIGNAL(clicked()), this, SLOT(slotBackPShade()));
646 
647 	disconnect(m_pwidget->cpage->fontFace_, SIGNAL(fontSelected(QString)), this, SLOT(slotFont(QString)));
648 	disconnect(m_pwidget->cpage->effects_, SIGNAL(State(int)), this, SLOT(slotEffects(int)));
649 	disconnect(m_pwidget->cpage->effects_->ShadowVal->Xoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
650 	disconnect(m_pwidget->cpage->effects_->ShadowVal->Yoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
651 	disconnect(m_pwidget->cpage->effects_->OutlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
652 	disconnect(m_pwidget->cpage->effects_->UnderlineVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
653 	disconnect(m_pwidget->cpage->effects_->UnderlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
654 	disconnect(m_pwidget->cpage->effects_->StrikeVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
655 	disconnect(m_pwidget->cpage->effects_->StrikeVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
656 	disconnect(m_pwidget->cpage->fillColor_, SIGNAL(activated(const QString&)), this, SLOT(slotFillColor()));
657 	disconnect(m_pwidget->cpage->fillShade_, SIGNAL(clicked()), this, SLOT(slotFillShade()));
658 	disconnect(m_pwidget->cpage->strokeColor_, SIGNAL(activated(const QString&)), this, SLOT(slotStrokeColor()));
659 	disconnect(m_pwidget->cpage->strokeShade_, SIGNAL(clicked()), this, SLOT(slotStrokeShade()));
660 	disconnect(m_pwidget->cpage->language_, SIGNAL(activated(int)), this, SLOT(slotLanguage()));
661 	disconnect(m_pwidget->cpage->fontSize_, SIGNAL(valueChanged(double)), this, SLOT(slotFontSize()));
662 	disconnect(m_pwidget->cpage->fontHScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleH()));
663 	disconnect(m_pwidget->cpage->fontVScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleV()));
664 	disconnect(m_pwidget->cpage->tracking_, SIGNAL(valueChanged(double)), this, SLOT(slotTracking()));
665 	disconnect(m_pwidget->cpage->widthSpaceSpin, SIGNAL(valueChanged(double)), this, SLOT(slotWordTracking()));
666 	disconnect(m_pwidget->cpage->baselineOffset_, SIGNAL(valueChanged(double)), this, SLOT(slotBaselineOffset()));
667 	disconnect(m_pwidget->cpage->parentCombo, SIGNAL(activated(const QString&)), this, SLOT(slotCharParentChanged(const QString&)));
668 	disconnect(m_pwidget->cpage->backColor_, SIGNAL(activated(const QString&)), this, SLOT(slotBackColor()));
669 	disconnect(m_pwidget->cpage->backShade_, SIGNAL(clicked()), this, SLOT(slotBackShade()));
670 	disconnect(m_pwidget->cpage->fontfeaturesSetting, SIGNAL(changed()), this, SLOT(slotFontFeatures()));
671 	disconnect(m_pwidget->cpage->hyphenCharLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotHyphenChar()));
672 	disconnect(m_pwidget->cpage->smallestWordSpinBox, SIGNAL(valueChanged(int)), this, SLOT(slotWordMin()));
673 	disconnect(m_cstyleItem, SIGNAL(charStylesDeleted(const QList<RemoveItem>&)), this, SLOT(slotCharStylesDeleted(const QList<RemoveItem>&)));
674 }
675 
slotLineSpacingMode(int mode)676 void SMParagraphStyle::slotLineSpacingMode(int mode)
677 {
678 	ParagraphStyle::LineSpacingMode lsm = static_cast<ParagraphStyle::LineSpacingMode>(mode);
679 
680 	if (m_pwidget->lineSpacingMode->useParentValue())
681 		for (int i = 0; i < m_selection.count(); ++i)
682 			m_selection[i]->resetLineSpacingMode();
683 	else
684 		for (int i = 0; i < m_selection.count(); ++i)
685 			m_selection[i]->setLineSpacingMode(lsm);
686 
687 	slotSelectionDirty();
688 }
689 
slotLineSpacing()690 void SMParagraphStyle::slotLineSpacing()
691 {
692 	if (m_pwidget->lineSpacing->useParentValue())
693 		for (int i = 0; i < m_selection.count(); ++i)
694 			m_selection[i]->resetLineSpacing();
695 	else
696 	{
697 		double a, b, value;
698 		int c;
699 
700 		m_pwidget->lineSpacing->getValues(&a, &b, &c, &value);
701 		for (int i = 0; i < m_selection.count(); ++i)
702 			m_selection[i]->setLineSpacing(value);
703 	}
704 
705 	slotSelectionDirty();
706 }
707 
slotSpaceAbove()708 void SMParagraphStyle::slotSpaceAbove()
709 {
710 	if (m_pwidget->spaceAbove->useParentValue())
711 		for (int i = 0; i < m_selection.count(); ++i)
712 			m_selection[i]->resetGapBefore();
713 	else
714 	{
715 		double a, b, value;
716 		int c;
717 
718 		m_pwidget->spaceAbove->getValues(&a, &b, &c, &value);
719 		for (int i = 0; i < m_selection.count(); ++i)
720 			m_selection[i]->setGapBefore(value);
721 	}
722 
723 	slotSelectionDirty();
724 }
725 
slotSpaceBelow()726 void SMParagraphStyle::slotSpaceBelow()
727 {
728 	if (m_pwidget->spaceBelow->useParentValue())
729 		for (int i = 0; i < m_selection.count(); ++i)
730 			m_selection[i]->resetGapAfter();
731 	else
732 	{
733 		double a, b, value;
734 		int c;
735 
736 		m_pwidget->spaceBelow->getValues(&a, &b, &c, &value);
737 		for (int i = 0; i < m_selection.count(); ++i)
738 			m_selection[i]->setGapAfter(value);
739 	}
740 
741 	slotSelectionDirty();
742 }
743 
slotAlignment()744 void SMParagraphStyle::slotAlignment()
745 {
746 	ParagraphStyle::AlignmentType style = static_cast<ParagraphStyle::AlignmentType>(m_pwidget->alignment->getStyle());
747 	if (m_pwidget->alignment->useParentValue())
748 		for (int i = 0; i < m_selection.count(); ++i)
749 			m_selection[i]->resetAlignment();
750 	else
751 		for (int i = 0; i < m_selection.count(); ++i)
752 			m_selection[i]->setAlignment(style);
753 
754 	slotSelectionDirty();
755 }
756 
slotDirection()757 void SMParagraphStyle::slotDirection()
758 {
759 	ParagraphStyle::DirectionType style = static_cast<ParagraphStyle::DirectionType>(m_pwidget->direction->getStyle());
760 	if (m_pwidget->direction->useParentValue())
761 		for (int i = 0; i < m_selection.count(); ++i)
762 			m_selection[i]->resetDirection();
763 	else
764 		for (int i = 0; i < m_selection.count(); ++i)
765 			m_selection[i]->setDirection(style);
766 
767 	slotSelectionDirty();
768 }
769 
slotOpticalMargin(int i)770 void SMParagraphStyle::slotOpticalMargin(int i)
771 {
772 //	ParagraphStyle::OpticalMarginType omt( static_cast<ParagraphStyle::OpticalMarginType>(m_pwidget->optMarginCombo->itemData(i).toInt()));
773 //	if (m_pwidget->optMarginCombo->useParentValue())
774 //		for (int i = 0; i < m_selection.count(); ++i)
775 //			m_selection[i]->resetOpticalMargins();
776 //	else
777 //		for (int i = 0; i < m_selection.count(); ++i)
778 //			m_selection[i]->setOpticalMargins(omt);
779 //
780 //	slotSelectionDirty();
781 }
782 
slotOpticalMarginSelector()783 void SMParagraphStyle::slotOpticalMarginSelector()
784 {
785 	int omt(ParagraphStyle::OM_None);
786 
787 	if (m_pwidget->optMarginRadioRight->isChecked()) omt = ParagraphStyle::OM_RightHangingPunct;
788 	else if (m_pwidget->optMarginRadioLeft->isChecked()) omt = ParagraphStyle::OM_LeftHangingPunct;
789 	else if (m_pwidget->optMarginRadioBoth->isChecked()) omt = ParagraphStyle::OM_Default;
790 
791 	for (int i = 0; i < m_selection.count(); ++i)
792 		m_selection[i]->setOpticalMargins(omt);
793 
794 	slotSelectionDirty();
795 }
796 
slotParentOpticalMargin()797 void SMParagraphStyle::slotParentOpticalMargin()
798 {
799 	for (int i = 0; i < m_selection.count(); ++i)
800 		m_selection[i]->resetOpticalMargins();
801 
802 	slotSelectionDirty();
803 }
804 
slotMinSpace()805 void SMParagraphStyle::slotMinSpace()
806 {
807 	if (m_pwidget->minSpaceSpin->useParentValue())
808 		for (int i = 0; i < m_selection.count(); ++i)
809 			m_selection[i]->resetMinWordTracking();
810 	else
811 	{
812 		double ms(m_pwidget->minSpaceSpin->getValue(SC_PERCENT));
813 		for (int i = 0; i < m_selection.count(); ++i)
814 			m_selection[i]->setMinWordTracking(ms / 100.0);
815 	}
816 
817 	slotSelectionDirty();
818 }
819 
slotMinGlyphExt()820 void SMParagraphStyle::slotMinGlyphExt()
821 {
822 	if (m_pwidget->minGlyphExtSpin->useParentValue())
823 		for (int i = 0; i < m_selection.count(); ++i)
824 			m_selection[i]->resetMinGlyphExtension();
825 	else
826 	{
827 		double mge(m_pwidget->minGlyphExtSpin->getValue(SC_PERCENT));
828 		for (int i = 0; i < m_selection.count(); ++i)
829 			m_selection[i]->setMinGlyphExtension(mge / 100.0);
830 	}
831 
832 	slotSelectionDirty();
833 }
834 
slotMaxGlyphExt()835 void SMParagraphStyle::slotMaxGlyphExt()
836 {
837 	if (m_pwidget->maxGlyphExtSpin->useParentValue())
838 		for (int i = 0; i < m_selection.count(); ++i)
839 			m_selection[i]->resetMaxGlyphExtension();
840 	else
841 	{
842 		double mge(m_pwidget->maxGlyphExtSpin->getValue(SC_PERCENT));
843 		for (int i = 0; i < m_selection.count(); ++i)
844 			m_selection[i]->setMaxGlyphExtension(mge / 100.0);
845 	}
846 
847 	slotSelectionDirty();
848 }
849 
slotConsecutiveLines()850 void SMParagraphStyle::slotConsecutiveLines()
851 {
852 	if (m_pwidget->maxConsecutiveCountSpinBox->useParentValue())
853 		for (int i = 0; i < m_selection.count(); ++i)
854 			m_selection[i]->resetHyphenConsecutiveLines();
855 	else
856 	{
857 		double cL(m_pwidget->maxConsecutiveCountSpinBox->value());
858 		for (int i = 0; i < m_selection.count(); ++i)
859 			m_selection[i]->setHyphenConsecutiveLines(cL);
860 	}
861 
862 	slotSelectionDirty();
863 }
864 
slotDropCap(bool isOn)865 void SMParagraphStyle::slotDropCap(bool isOn)
866 {
867 	for (int i = 0; i < m_selection.count(); ++i)
868 	{
869 		m_selection[i]->setHasDropCap(isOn);
870 		if (isOn)
871 		{
872 			m_selection[i]->setHasBullet(false);
873 			m_selection[i]->setHasNum(false);
874 		}
875 	}
876 
877 	slotSelectionDirty();
878 }
879 
slotParentParaEffects()880 void SMParagraphStyle::slotParentParaEffects()
881 {
882 	for (int i = 0; i < m_selection.count(); ++i)
883 	{
884 		m_selection[i]->resetHasDropCap();
885 		m_selection[i]->resetHasBullet();
886 		m_selection[i]->resetHasNum();
887 	}
888 
889 	slotSelectionDirty();
890 }
891 
slotDropCapLines(int lines)892 void SMParagraphStyle::slotDropCapLines(int lines)
893 {
894 	if (m_pwidget->dropCapLines->useParentValue())
895 		for (int i = 0; i < m_selection.count(); ++i)
896 			m_selection[i]->resetDropCapLines();
897 	else
898 		for (int i = 0; i < m_selection.count(); ++i)
899 			m_selection[i]->setDropCapLines(lines);
900 
901 	slotSelectionDirty();
902 }
903 
slotParEffectOffset()904 void SMParagraphStyle::slotParEffectOffset()
905 {
906 	if (m_pwidget->parEffectOffset->useParentValue())
907 		for (int i = 0; i < m_selection.count(); ++i)
908 			m_selection[i]->resetParEffectOffset();
909 	else
910 	{
911 		double a, b, value;
912 		int c;
913 
914 		m_pwidget->parEffectOffset->getValues(&a, &b, &c, &value);
915 		value = value / m_unitRatio;
916 		for (int i = 0; i < m_selection.count(); ++i)
917 			m_selection[i]->setParEffectOffset(value);
918 	}
919 
920 	slotSelectionDirty();
921 }
922 
slotParEffectIndent(bool isOn)923 void SMParagraphStyle::slotParEffectIndent(bool isOn)
924 {
925 	if (m_pwidget->parEffectIndentBox->useParentValue())
926 		for (int i = 0; i < m_selection.count(); ++i)
927 			m_selection[i]->resetParEffectIndent();
928 	else
929 	{
930 		for (int i = 0; i < m_selection.count(); ++i)
931 			m_selection[i]->setParEffectIndent(isOn);
932 	}
933 
934 	slotSelectionDirty();
935 }
936 
slotParEffectCharStyle(int index)937 void SMParagraphStyle::slotParEffectCharStyle(int index)
938 {
939 	QString name;
940 
941 	if (index > 0)
942 		name = m_pwidget->parEffectCharStyleCombo->itemText(index);
943 
944 	if (name.isEmpty() || m_pwidget->parEffectCharStyleCombo->useParentValue())
945 		for (int i = 0; i < m_selection.count(); ++i)
946 			m_selection[i]->resetPeCharStyleName();
947 	else
948 		for (int i = 0; i < m_selection.count(); ++i)
949 			m_selection[i]->setPeCharStyleName(name);
950 
951 	slotSelectionDirty();
952 }
953 
slotBullet(bool isOn)954 void SMParagraphStyle::slotBullet(bool isOn)
955 {
956 	for (int i = 0; i < m_selection.count(); ++i)
957 	{
958 		m_selection[i]->setHasBullet(isOn);
959 		if (isOn)
960 		{
961 			m_selection[i]->setBulletStr(m_pwidget->bulletStrEdit->currentText());
962 			m_selection[i]->setHasDropCap(false);
963 			m_selection[i]->setHasNum(false);
964 		}
965 	}
966 
967 	slotSelectionDirty();
968 }
969 
slotBulletStr(const QString & str)970 void SMParagraphStyle::slotBulletStr(const QString &str)
971 {
972 	QString bstr(str);
973 	if (bstr.isEmpty())
974 	{
975 		bstr = m_pwidget->bulletStrEdit->itemText(0);
976 		m_pwidget->bulletStrEdit->setEditText(bstr);
977 	}
978 	for (int i = 0; i < m_selection.count(); ++i)
979 		m_selection[i]->setBulletStr(bstr);
980 
981 	slotSelectionDirty();
982 }
983 
slotNumeration(bool isOn)984 void SMParagraphStyle::slotNumeration(bool isOn)
985 {
986 	for (int i = 0; i < m_selection.count(); ++i)
987 	{
988 		m_selection[i]->setHasNum(isOn);
989 		if (isOn)
990 		{
991 			m_selection[i]->setHasDropCap(false);
992 			m_selection[i]->setHasBullet(false);
993 		}
994 	}
995 
996 	slotSelectionDirty();
997 }
998 
slotNumName(const QString & str)999 void SMParagraphStyle::slotNumName(const QString &str)
1000 {
1001 	if (!str.isEmpty())
1002 	{
1003 		for (int i = 0; i < m_selection.count(); ++i)
1004 			m_selection[i]->setNumName(str);
1005 		m_pwidget->numComboBox->setCurrentItem(m_pwidget->numComboBox->findText(m_selection[0]->numName()));
1006 		m_pwidget->numLevelSpin->setValue(m_selection[0]->numLevel()+1);
1007 		NumStruct * numS = m_doc->numerations.value(m_selection[0]->numName());
1008 		if (numS)
1009 			m_pwidget->numLevelSpin->setMaximum(numS->m_counters.count()+1);
1010 		else
1011 			m_pwidget->numLevelSpin->setMaximum(1);
1012 		m_doc->flag_NumUpdateRequest = true;
1013 	}
1014 
1015 	slotSelectionDirty();
1016 }
1017 
slotNumNew()1018 void SMParagraphStyle::slotNumNew()
1019 {
1020 	QString newName = m_pwidget->numNewLineEdit->text();
1021 	if (!newName.isEmpty())
1022 	{
1023 		for (int i = 0; i < m_selection.count(); ++i)
1024 			m_selection[i]->setNumName(newName);
1025 		m_doc->flag_NumUpdateRequest = true;
1026 	}
1027 
1028 	slotSelectionDirty();
1029 }
1030 
slotSelectionDirty()1031 void SMParagraphStyle::slotSelectionDirty()
1032 {
1033 	if (m_selectionIsDirty)
1034 		return;
1035 	m_selectionIsDirty = true;
1036 	emit selectionDirty();
1037 }
1038 
slotNumFormat(int)1039 void SMParagraphStyle::slotNumFormat(int)
1040 {
1041 	if (m_pwidget->numFormatCombo->useParentFormat())
1042 	{
1043 		for (int i = 0; i < m_selection.count(); ++i)
1044 			m_selection[i]->resetNumFormat();
1045 	}
1046 	else
1047 	{
1048 		NumFormat numFormat = m_pwidget->numFormatCombo->currentFormat();
1049 		for (int i = 0; i < m_selection.count(); ++i)
1050 			m_selection[i]->setNumFormat(numFormat);
1051 	}
1052 
1053 	slotSelectionDirty();
1054 }
1055 
slotNumLevel(int level)1056 void SMParagraphStyle::slotNumLevel(int level)
1057 {
1058 	if (m_pwidget->numLevelSpin->useParentValue())
1059 	{
1060 		for (int i = 0; i < m_selection.count(); ++i)
1061 			m_selection[i]->resetNumLevel();
1062 	}
1063 	else
1064 	{
1065 		for (int i = 0; i < m_selection.count(); ++i)
1066 			m_selection[i]->setNumLevel(level - 1);
1067 	}
1068 
1069 	if (level == 0)
1070 		slotNumHigher(false);
1071 
1072 	slotSelectionDirty();
1073 }
1074 
slotNumPrefix(const QString & str)1075 void SMParagraphStyle::slotNumPrefix(const QString &str)
1076 {
1077 	for (int i = 0; i < m_selection.count(); ++i)
1078 		m_selection[i]->setNumPrefix(str);
1079 
1080 	slotSelectionDirty();
1081 }
1082 
slotNumSuffix(const QString & str)1083 void SMParagraphStyle::slotNumSuffix(const QString &str)
1084 {
1085 	for (int i = 0; i < m_selection.count(); ++i)
1086 		m_selection[i]->setNumSuffix(str);
1087 
1088 	slotSelectionDirty();
1089 }
1090 
slotNumStart(int start)1091 void SMParagraphStyle::slotNumStart(int start)
1092 {
1093 	if (m_pwidget->numStartSpin->useParentValue())
1094 	{
1095 		for (int i = 0; i < m_selection.count(); ++i)
1096 			m_selection[i]->resetNumStart();
1097 	}
1098 	else
1099 	{
1100 		for (int i = 0; i < m_selection.count(); ++i)
1101 			m_selection[i]->setNumStart(start);
1102 	}
1103 
1104 	slotSelectionDirty();
1105 }
1106 
slotNumRestart(int restart)1107 void SMParagraphStyle::slotNumRestart(int restart)
1108 {
1109 	int restartRange = m_pwidget->numRestartCombo->itemData(restart).toInt();
1110 
1111 	if (m_pwidget->numRestartCombo->useParentValue())
1112 	{
1113 		for (int i = 0; i < m_selection.count(); ++i)
1114 			m_selection[i]->resetNumRestart();
1115 	}
1116 	else
1117 	{
1118 		for (int i = 0; i < m_selection.count(); ++i)
1119 			m_selection[i]->setNumRestart(restartRange);
1120 	}
1121 
1122 	slotSelectionDirty();
1123 }
1124 
slotNumOther(bool isOn)1125 void SMParagraphStyle::slotNumOther(bool isOn)
1126 {
1127 	if (m_pwidget->numRestartOtherBox->useParentValue())
1128 	{
1129 		for (int i = 0; i < m_selection.count(); ++i)
1130 			m_selection[i]->resetNumOther();
1131 	}
1132 	else
1133 	{
1134 		for (int i = 0; i < m_selection.count(); ++i)
1135 			m_selection[i]->setNumOther(isOn);
1136 	}
1137 
1138 	slotSelectionDirty();
1139 }
1140 
slotNumHigher(bool isOn)1141 void SMParagraphStyle::slotNumHigher(bool isOn)
1142 {
1143 	if (m_pwidget->numRestartHigherBox->useParentValue())
1144 	{
1145 		for (int i = 0; i < m_selection.count(); ++i)
1146 			m_selection[i]->resetNumHigher();
1147 	}
1148 	else
1149 	{
1150 		for (int i = 0; i < m_selection.count(); ++i)
1151 			m_selection[i]->setNumHigher(isOn);
1152 	}
1153 
1154 	slotSelectionDirty();
1155 }
1156 
1157 
handleKeepLinesStart()1158 void SMParagraphStyle::handleKeepLinesStart()
1159 {
1160 	if (m_pwidget->keepLinesStart->useParentValue())
1161 	{
1162 		for (int i = 0; i < m_selection.count(); ++i)
1163 			m_selection[i]->resetKeepLinesStart();
1164 	}
1165 	else
1166 	{
1167 		int value = m_pwidget->keepLinesStart->value();
1168 		for (int i = 0; i < m_selection.count(); ++i)
1169 			m_selection[i]->setKeepLinesStart (value);
1170 	}
1171 
1172 	slotSelectionDirty();
1173 }
1174 
handleKeepLinesEnd()1175 void SMParagraphStyle::handleKeepLinesEnd()
1176 {
1177 	if (m_pwidget->keepLinesEnd->useParentValue())
1178 	{
1179 		for (int i = 0; i < m_selection.count(); ++i)
1180 			m_selection[i]->resetKeepLinesEnd();
1181 	}
1182 	else
1183 	{
1184 		int value = m_pwidget->keepLinesEnd->value();
1185 		for (int i = 0; i < m_selection.count(); ++i)
1186 			m_selection[i]->setKeepLinesEnd (value);
1187 	}
1188 
1189 	slotSelectionDirty();
1190 }
1191 
handleKeepTogether()1192 void SMParagraphStyle::handleKeepTogether()
1193 {
1194 	if (m_pwidget->keepTogether->useParentValue())
1195 	{
1196 		for (int i = 0; i < m_selection.count(); ++i)
1197 			m_selection[i]->resetKeepTogether();
1198 	}
1199 	else
1200 	{
1201 		bool value = m_pwidget->keepTogether->isChecked();
1202 		for (int i = 0; i < m_selection.count(); ++i)
1203 			m_selection[i]->setKeepTogether (value);
1204 	}
1205 
1206 	slotSelectionDirty();
1207 }
1208 
handleKeepWithNext()1209 void SMParagraphStyle::handleKeepWithNext()
1210 {
1211 	if (m_pwidget->keepWithNext->useParentValue())
1212 	{
1213 		for (int i = 0; i < m_selection.count(); ++i)
1214 			m_selection[i]->resetKeepWithNext();
1215 	}
1216 	else
1217 	{
1218 		bool value = m_pwidget->keepWithNext->isChecked();
1219 		for (int i = 0; i < m_selection.count(); ++i)
1220 			m_selection[i]->setKeepWithNext (value);
1221 	}
1222 
1223 	slotSelectionDirty();
1224 }
1225 
slotTabRuler()1226 void SMParagraphStyle::slotTabRuler()
1227 {
1228 	if (m_pwidget->tabList->useParentTabs())
1229 	{
1230 		for (int i = 0; i < m_selection.count(); ++i)
1231 			m_selection[i]->resetTabValues();
1232 	}
1233 	else
1234 	{
1235 		QList<ParagraphStyle::TabRecord> newTabs = m_pwidget->tabList->getTabVals();
1236 		for (int i = 0; i < m_selection.count(); ++i)
1237 			m_selection[i]->setTabValues(newTabs);
1238 	}
1239 
1240 	slotSelectionDirty();
1241 }
1242 
slotLeftIndent()1243 void SMParagraphStyle::slotLeftIndent()
1244 {
1245 	if (m_pwidget->tabList->useParentLeftIndent())
1246 	{
1247 		for (int i = 0; i < m_selection.count(); ++i)
1248 			m_selection[i]->resetLeftMargin();
1249 	}
1250 	else
1251 	{
1252 		double a, b, value;
1253 		int c;
1254 
1255 		m_pwidget->tabList->leftIndentSpin->getValues(&a, &b, &c, &value);
1256 		value = value / m_unitRatio;
1257 		for (int i = 0; i < m_selection.count(); ++i)
1258 			m_selection[i]->setLeftMargin(value);
1259 	}
1260 
1261 	slotSelectionDirty();
1262 }
1263 
slotRightIndent()1264 void SMParagraphStyle::slotRightIndent()
1265 {
1266 	if (m_pwidget->tabList->useParentRightIndent())
1267 	{
1268 		for (int i = 0; i < m_selection.count(); ++i)
1269 			m_selection[i]->resetRightMargin();
1270 	}
1271 	else
1272 	{
1273 		double a, b, value;
1274 		int c;
1275 
1276 		m_pwidget->tabList->rightIndentSpin->getValues(&a, &b, &c, &value);
1277 		value = value / m_unitRatio;
1278 		for (int i = 0; i < m_selection.count(); ++i)
1279 			m_selection[i]->setRightMargin(value);
1280 	}
1281 
1282 	slotSelectionDirty();
1283 }
1284 
slotFirstLine()1285 void SMParagraphStyle::slotFirstLine()
1286 {
1287 	if (m_pwidget->tabList->useParentFirstLine())
1288 	{
1289 		for (int i = 0; i < m_selection.count(); ++i)
1290 			m_selection[i]->resetFirstIndent();
1291 	}
1292 	else
1293 	{
1294 		double a, b, value;
1295 		int c;
1296 
1297 		m_pwidget->tabList->firstLineSpin->getValues(&a, &b, &c, &value);
1298 		value = value / m_unitRatio;
1299 		for (int i = 0; i < m_selection.count(); ++i)
1300 			m_selection[i]->setFirstIndent(value);
1301 	}
1302 
1303 	slotSelectionDirty();
1304 }
1305 
slotFontSize()1306 void SMParagraphStyle::slotFontSize()
1307 {
1308 	if (m_pwidget->cpage->fontSize_->useParentValue())
1309 		for (int i = 0; i < m_selection.count(); ++i)
1310 			m_selection[i]->charStyle().resetFontSize();
1311 	else
1312 	{
1313 		double a, b, value;
1314 		int c;
1315 
1316 		m_pwidget->cpage->fontSize_->getValues(&a, &b, &c, &value);
1317 		value = value * 10;
1318 		for (int i = 0; i < m_selection.count(); ++i)
1319 			m_selection[i]->charStyle().setFontSize(qRound(value));
1320 	}
1321 
1322 
1323 	slotSelectionDirty();
1324 }
1325 
slotEffects(int e)1326 void SMParagraphStyle::slotEffects(int e)
1327 {
1328 	StyleFlag s = ScStyle_None;
1329 	if (m_pwidget->cpage->effects_->useParentValue())
1330 	{
1331 		for (int i = 0; i < m_selection.count(); ++i)
1332 		{
1333 			m_selection[i]->charStyle().resetFeatures();
1334 			m_selection[i]->charStyle().resetShadowXOffset();
1335 			m_selection[i]->charStyle().resetShadowYOffset();
1336 			m_selection[i]->charStyle().resetOutlineWidth();
1337 			m_selection[i]->charStyle().resetUnderlineOffset();
1338 			m_selection[i]->charStyle().resetUnderlineWidth();
1339 			m_selection[i]->charStyle().resetStrikethruOffset();
1340 			m_selection[i]->charStyle().resetStrikethruWidth();
1341 		}
1342 	}
1343 	else
1344 	{
1345 		double a, b, sxo, syo, olw, ulp, ulw, slp, slw;
1346 		int c;
1347 
1348 		s = static_cast<StyleFlag>(e);
1349 		m_pwidget->cpage->effects_->ShadowVal->Xoffset->getValues(&a, &b, &c, &sxo);
1350 		sxo *= 10;
1351 		m_pwidget->cpage->effects_->ShadowVal->Yoffset->getValues(&a, &b, &c, &syo);
1352 		syo *= 10;
1353 
1354 		m_pwidget->cpage->effects_->OutlineVal->LWidth->getValues(&a, &b, &c, &olw);
1355 		olw *= 10;
1356 
1357 		m_pwidget->cpage->effects_->UnderlineVal->LPos->getValues(&a, &b, &c, &ulp);
1358 		ulp *= 10;
1359 		m_pwidget->cpage->effects_->UnderlineVal->LWidth->getValues(&a, &b, &c, &ulw);
1360 		ulw *= 10;
1361 
1362 		m_pwidget->cpage->effects_->StrikeVal->LPos->getValues(&a, &b, &c, &slp);
1363 		slp *= 10;
1364 		m_pwidget->cpage->effects_->StrikeVal->LWidth->getValues(&a, &b, &c, &slw);
1365 		slw *= 10;
1366 
1367 		for (int i = 0; i < m_selection.count(); ++i)
1368 		{
1369 			QStringList feList = s.featureList();
1370 			feList.removeAll(CharStyle::INHERIT);
1371 			m_selection[i]->charStyle().setFeatures(feList);
1372 //			m_selection[i]->charStyle().setFeatures(s.featureList());
1373 			m_selection[i]->charStyle().setShadowXOffset(qRound(sxo));
1374 			m_selection[i]->charStyle().setShadowYOffset(qRound(syo));
1375 			m_selection[i]->charStyle().setOutlineWidth(qRound(olw));
1376 			m_selection[i]->charStyle().setUnderlineOffset(qRound(ulp));
1377 			m_selection[i]->charStyle().setUnderlineWidth(qRound(ulw));
1378 			m_selection[i]->charStyle().setStrikethruOffset(qRound(slp));
1379 			m_selection[i]->charStyle().setStrikethruWidth(qRound(slw));
1380 		}
1381 	}
1382 
1383 	slotSelectionDirty();
1384 }
1385 
slotEffectProperties()1386 void SMParagraphStyle::slotEffectProperties()
1387 {
1388 	double a, b, sxo, syo, olw, ulp, ulw, slp, slw;
1389 	int c;
1390 
1391 	m_pwidget->cpage->effects_->ShadowVal->Xoffset->getValues(&a, &b, &c, &sxo);
1392 	sxo *= 10;
1393 	m_pwidget->cpage->effects_->ShadowVal->Yoffset->getValues(&a, &b, &c, &syo);
1394 	syo *= 10;
1395 
1396 	m_pwidget->cpage->effects_->OutlineVal->LWidth->getValues(&a, &b, &c, &olw);
1397 	olw *= 10;
1398 
1399 	m_pwidget->cpage->effects_->UnderlineVal->LPos->getValues(&a, &b, &c, &ulp);
1400 	ulp *= 10;
1401 	m_pwidget->cpage->effects_->UnderlineVal->LWidth->getValues(&a, &b, &c, &ulw);
1402 	ulw *= 10;
1403 
1404 	m_pwidget->cpage->effects_->StrikeVal->LPos->getValues(&a, &b, &c, &slp);
1405 	slp *= 10;
1406 	m_pwidget->cpage->effects_->StrikeVal->LWidth->getValues(&a, &b, &c, &slw);
1407 	slw *= 10;
1408 
1409 	for (int i = 0; i < m_selection.count(); ++i)
1410 	{
1411 		m_selection[i]->charStyle().setShadowXOffset(qRound(sxo));
1412 		m_selection[i]->charStyle().setShadowYOffset(qRound(syo));
1413 		m_selection[i]->charStyle().setOutlineWidth(qRound(olw));
1414 		m_selection[i]->charStyle().setUnderlineOffset(qRound(ulp));
1415 		m_selection[i]->charStyle().setUnderlineWidth(qRound(ulw));
1416 		m_selection[i]->charStyle().setStrikethruOffset(qRound(slp));
1417 		m_selection[i]->charStyle().setStrikethruWidth(qRound(slw));
1418 	}
1419 
1420 	slotSelectionDirty();
1421 }
1422 
slotFillColor()1423 void SMParagraphStyle::slotFillColor()
1424 {
1425 	if (m_pwidget->cpage->fillColor_->useParentValue())
1426 	{
1427 		for (int i = 0; i < m_selection.count(); ++i)
1428 			m_selection[i]->charStyle().resetFillColor();
1429 	}
1430 	else
1431 	{
1432 		QString col( m_pwidget->cpage->fillColor_->currentText());
1433 		if (col == CommonStrings::tr_NoneColor)
1434 			col = CommonStrings::None;
1435 		for (int i = 0; i < m_selection.count(); ++i)
1436 			m_selection[i]->charStyle().setFillColor(col);
1437 	}
1438 
1439 	slotSelectionDirty();
1440 }
1441 
slotFillShade()1442 void SMParagraphStyle::slotFillShade()
1443 {
1444 	if (m_pwidget->cpage->fillShade_->useParentValue())
1445 	{
1446 		for (int i = 0; i < m_selection.count(); ++i)
1447 			m_selection[i]->charStyle().resetFillShade();
1448 	}
1449 	else
1450 	{
1451 		int fs = m_pwidget->cpage->fillShade_->getValue();
1452 		for (int i = 0; i < m_selection.count(); ++i)
1453 			m_selection[i]->charStyle().setFillShade(fs);
1454 	}
1455 
1456 	slotSelectionDirty();
1457 }
1458 
slotBackPColor()1459 void SMParagraphStyle::slotBackPColor()
1460 {
1461 	if (m_pwidget->backColor_->useParentValue())
1462 	{
1463 		for (int i = 0; i < m_selection.count(); ++i)
1464 			m_selection[i]->resetBackgroundColor();
1465 	}
1466 	else
1467 	{
1468 		QString col( m_pwidget->backColor_->currentText());
1469 		if (col == CommonStrings::tr_NoneColor)
1470 			col = CommonStrings::None;
1471 		for (int i = 0; i < m_selection.count(); ++i)
1472 			m_selection[i]->setBackgroundColor(col);
1473 	}
1474 
1475 	slotSelectionDirty();
1476 }
1477 
slotBackPShade()1478 void SMParagraphStyle::slotBackPShade()
1479 {
1480 	if (m_pwidget->backShade_->useParentValue())
1481 	{
1482 		for (int i = 0; i < m_selection.count(); ++i)
1483 			m_selection[i]->resetBackgroundShade();
1484 	}
1485 	else
1486 	{
1487 		int fs = m_pwidget->backShade_->getValue();
1488 		for (int i = 0; i < m_selection.count(); ++i)
1489 			m_selection[i]->setBackgroundShade(fs);
1490 	}
1491 
1492 	slotSelectionDirty();
1493 }
1494 
slotBackColor()1495 void SMParagraphStyle::slotBackColor()
1496 {
1497 	if (m_pwidget->cpage->backColor_->useParentValue())
1498 	{
1499 		for (int i = 0; i < m_selection.count(); ++i)
1500 			m_selection[i]->charStyle().resetBackColor();
1501 	}
1502 	else
1503 	{
1504 		QString col( m_pwidget->cpage->backColor_->currentText());
1505 		if (col == CommonStrings::tr_NoneColor)
1506 			col = CommonStrings::None;
1507 		for (int i = 0; i < m_selection.count(); ++i)
1508 			m_selection[i]->charStyle().setBackColor(col);
1509 	}
1510 
1511 	slotSelectionDirty();
1512 }
1513 
slotBackShade()1514 void SMParagraphStyle::slotBackShade()
1515 {
1516 	if (m_pwidget->cpage->backShade_->useParentValue())
1517 	{
1518 		for (int i = 0; i < m_selection.count(); ++i)
1519 			m_selection[i]->charStyle().resetBackShade();
1520 	}
1521 	else
1522 	{
1523 		int fs = m_pwidget->cpage->backShade_->getValue();
1524 		for (int i = 0; i < m_selection.count(); ++i)
1525 			m_selection[i]->charStyle().setBackShade(fs);
1526 	}
1527 
1528 	slotSelectionDirty();
1529 }
1530 
slotStrokeColor()1531 void SMParagraphStyle::slotStrokeColor()
1532 {
1533 	if (m_pwidget->cpage->strokeColor_->useParentValue())
1534 	{
1535 		for (int i = 0; i < m_selection.count(); ++i)
1536 			m_selection[i]->charStyle().resetStrokeColor();
1537 	}
1538 	else
1539 	{
1540 		QString col(m_pwidget->cpage->strokeColor_->currentText());
1541 		if (col == CommonStrings::tr_NoneColor)
1542 			col = CommonStrings::None;
1543 		for (int i = 0; i < m_selection.count(); ++i)
1544 			m_selection[i]->charStyle().setStrokeColor(col);
1545 	}
1546 
1547 	slotSelectionDirty();
1548 }
1549 
slotStrokeShade()1550 void SMParagraphStyle::slotStrokeShade()
1551 {
1552 	if (m_pwidget->cpage->strokeShade_->useParentValue())
1553 	{
1554 		for (int i = 0; i < m_selection.count(); ++i)
1555 			m_selection[i]->charStyle().resetStrokeShade();
1556 	}
1557 	else
1558 	{
1559 		int ss = m_pwidget->cpage->strokeShade_->getValue();
1560 		for (int i = 0; i < m_selection.count(); ++i)
1561 			m_selection[i]->charStyle().setStrokeShade(ss);
1562 	}
1563 
1564 	slotSelectionDirty();
1565 }
1566 
slotLanguage()1567 void SMParagraphStyle::slotLanguage()
1568 {
1569 	QString language = m_doc->paragraphStyle("").charStyle().language();
1570 
1571 	if (m_pwidget->cpage->language_->useParentValue())
1572 	{
1573 		for (int i = 0; i < m_selection.count(); ++i)
1574 			m_selection[i]->charStyle().resetLanguage();
1575 	}
1576 	else
1577 	{
1578 		QString la = LanguageManager::instance()->getAbbrevFromLang(m_pwidget->cpage->language_->currentText(), false);
1579 		if (!la.isEmpty())
1580 			language = la;
1581 		for (int i = 0; i < m_selection.count(); ++i)
1582 			m_selection[i]->charStyle().setLanguage(language);
1583 	}
1584 
1585 	slotSelectionDirty();
1586 }
1587 
slotWordMin()1588 void SMParagraphStyle::slotWordMin()
1589 {
1590 	if (m_pwidget->cpage->smallestWordSpinBox->useParentValue())
1591 	{
1592 		for (int i = 0; i < m_selection.count(); ++i)
1593 			m_selection[i]->charStyle().resetHyphenWordMin();
1594 	}
1595 	else
1596 	{
1597 		int wm = m_pwidget->cpage->smallestWordSpinBox->value();
1598 		for (int i = 0; i < m_selection.count(); ++i)
1599 			m_selection[i]->charStyle().setHyphenWordMin(wm);
1600 	}
1601 
1602 	slotSelectionDirty();
1603 }
1604 
slotHyphenChar()1605 void SMParagraphStyle::slotHyphenChar()
1606 {
1607 	if (m_pwidget->cpage->hyphenCharLineEdit->useParentValue())
1608 	{
1609 		for (int i = 0; i < m_selection.count(); ++i)
1610 			m_selection[i]->charStyle().resetHyphenChar();
1611 	}
1612 	else
1613 	{
1614 		QString hyphenText = m_pwidget->cpage->hyphenCharLineEdit->text();
1615 		uint ch = hyphenText.isEmpty() ? 0 : hyphenText.toUcs4()[0];
1616 		for (int i = 0; i < m_selection.count(); ++i)
1617 			m_selection[i]->charStyle().setHyphenChar(ch);
1618 	}
1619 
1620 	slotSelectionDirty();
1621 }
1622 
slotScaleH()1623 void SMParagraphStyle::slotScaleH()
1624 {
1625 	if (m_pwidget->cpage->fontHScale_->useParentValue())
1626 	{
1627 		for (int i = 0; i < m_selection.count(); ++i)
1628 			m_selection[i]->charStyle().resetScaleH();
1629 	}
1630 	else
1631 	{
1632 		double a, b, value;
1633 		int c;
1634 		m_pwidget->cpage->fontHScale_->getValues(&a, &b, &c, &value);
1635 		value = value * 10;
1636 		for (int i = 0; i < m_selection.count(); ++i)
1637 			m_selection[i]->charStyle().setScaleH(qRound(value));
1638 	}
1639 
1640 	slotSelectionDirty();
1641 }
1642 
slotScaleV()1643 void SMParagraphStyle::slotScaleV()
1644 {
1645 	if (m_pwidget->cpage->fontVScale_->useParentValue())
1646 	{
1647 		for (int i = 0; i < m_selection.count(); ++i)
1648 			m_selection[i]->charStyle().resetScaleV();
1649 	}
1650 	else
1651 	{
1652 		double a, b, value;
1653 		int c;
1654 		m_pwidget->cpage->fontVScale_->getValues(&a, &b, &c, &value);
1655 		value = value * 10;
1656 		for (int i = 0; i < m_selection.count(); ++i)
1657 			m_selection[i]->charStyle().setScaleV(qRound(value));
1658 	}
1659 
1660 	slotSelectionDirty();
1661 }
1662 
slotTracking()1663 void SMParagraphStyle::slotTracking()
1664 {
1665 	if (m_pwidget->cpage->tracking_->useParentValue())
1666 	{
1667 		for (int i = 0; i < m_selection.count(); ++i)
1668 			m_selection[i]->charStyle().resetTracking();
1669 	}
1670 	else
1671 	{
1672 		double a, b, value;
1673 		int c;
1674 		m_pwidget->cpage->tracking_->getValues(&a, &b, &c, &value);
1675 		value = value * 10;
1676 		for (int i = 0; i < m_selection.count(); ++i)
1677 			m_selection[i]->charStyle().setTracking(qRound(value));
1678 	}
1679 
1680 	slotSelectionDirty();
1681 }
1682 
slotWordTracking()1683 void SMParagraphStyle::slotWordTracking()
1684 {
1685 	if (m_pwidget->cpage->widthSpaceSpin->useParentValue())
1686 	{
1687 		for (int i = 0; i < m_selection.count(); ++i)
1688 			m_selection[i]->charStyle().resetWordTracking();
1689 	}
1690 	else
1691 	{
1692 		double a, b, value;
1693 		int c;
1694 		m_pwidget->cpage->widthSpaceSpin->getValues(&a, &b, &c, &value);
1695 		value = value / 100.0;
1696 		for (int i = 0; i < m_selection.count(); ++i)
1697 			m_selection[i]->charStyle().setWordTracking(value);
1698 	}
1699 
1700 	slotSelectionDirty();
1701 }
1702 
slotBaselineOffset()1703 void SMParagraphStyle::slotBaselineOffset()
1704 {
1705 	if (m_pwidget->cpage->baselineOffset_->useParentValue())
1706 	{
1707 		for (int i = 0; i < m_selection.count(); ++i)
1708 			m_selection[i]->charStyle().resetBaselineOffset();
1709 	}
1710 	else
1711 	{
1712 		double a, b, value;
1713 		int c;
1714 		m_pwidget->cpage->baselineOffset_->getValues(&a, &b, &c, &value);
1715 		value = value * 10;
1716 		for (int i = 0; i < m_selection.count(); ++i)
1717 			m_selection[i]->charStyle().setBaselineOffset(qRound(value));
1718 	}
1719 
1720 	slotSelectionDirty();
1721 }
1722 
slotFont(const QString & s)1723 void SMParagraphStyle::slotFont(const QString& s)
1724 {
1725 	if (m_pwidget->cpage->fontFace_->useParentFont())
1726 	{
1727 		for (int i = 0; i < m_selection.count(); ++i)
1728 			m_selection[i]->charStyle().resetFont();
1729 	}
1730 	else
1731 	{
1732 		ScFace sf = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts[s];
1733 		for (int i = 0; i < m_selection.count(); ++i)
1734 			m_selection[i]->charStyle().setFont(sf);
1735 	}
1736 
1737 	slotSelectionDirty();
1738 }
1739 
slotParentChanged(const QString & parent)1740 void SMParagraphStyle::slotParentChanged(const QString &parent)
1741 {
1742 	Q_ASSERT(!parent.isNull());
1743 
1744 	bool  loop = false, parentLoop = false;
1745 	const BaseStyle* parentStyle = (!parent.isEmpty()) ? m_tmpStyles.resolve(parent) : nullptr;
1746 	QStringList sel;
1747 
1748 	for (int i = 0; i < m_selection.count(); ++i)
1749 	{
1750 		loop = false;
1751 		// Check if setting parent won't create a loop
1752 		const BaseStyle* pStyle = parentStyle;
1753 		while (pStyle)
1754 		{
1755 			if (pStyle->hasParent() && (pStyle->parent() == m_selection[i]->name()))
1756 			{
1757 				loop = parentLoop = true;
1758 				break;
1759 			}
1760 			pStyle = pStyle->hasParent() ? pStyle->parentStyle() : nullptr;
1761 		}
1762 		if (!loop)
1763 		{
1764 			m_selection[i]->erase(); // reset everything to NOVALUE
1765 			m_selection[i]->setParent(parent);
1766 			m_selection[i]->charStyle().setParent("");
1767 		}
1768 		sel << m_selection[i]->name();
1769 	}
1770 
1771 	if (parentLoop)
1772 		ScMessageBox::warning(this->widget(), CommonStrings::trWarning, tr("Setting that style as parent would create an infinite loop."));
1773 
1774 	selected(sel);
1775 
1776 	slotSelectionDirty();
1777 }
1778 
slotCharParentChanged(const QString & parent)1779 void SMParagraphStyle::slotCharParentChanged(const QString &parent)
1780 {
1781 	Q_ASSERT(!parent.isNull());
1782 
1783 	QStringList sel;
1784 
1785 	for (int i = 0; i < m_selection.count(); ++i)
1786 	{
1787 		m_selection[i]->charStyle().erase();
1788 		if (!parent.isNull())
1789 			m_selection[i]->charStyle().setParent(parent);
1790 
1791 		sel << m_selection[i]->name();
1792 	}
1793 
1794 	selected(sel);
1795 
1796 	slotSelectionDirty();
1797 }
1798 
slotFontFeatures()1799 void SMParagraphStyle::slotFontFeatures()
1800 {
1801 	if (m_pwidget->cpage->fontfeaturesSetting->useParentValue())
1802 	{
1803 		for (int i = 0; i < m_selection.count(); ++i)
1804 			m_selection[i]->charStyle().resetFontFeatures();
1805 	}
1806 	else
1807 	{
1808 		QString fontfeatures = m_pwidget->cpage->fontfeaturesSetting->fontFeatures();
1809 		for (int i = 0; i < m_selection.count(); ++i)
1810 			m_selection[i]->charStyle().setFontFeatures(fontfeatures);
1811 	}
1812 
1813 	slotSelectionDirty();
1814 }
1815 
slotCharStylesDeleted(const QList<RemoveItem> & removeList)1816 void SMParagraphStyle::slotCharStylesDeleted(const QList<RemoveItem> &removeList)
1817 {
1818 	for (int i = 0; i < m_tmpStyles.count(); ++i)
1819 	{
1820 		ParagraphStyle& parStyle = m_tmpStyles[i];
1821 
1822 		QString charStyleName = parStyle.charStyle().parent();
1823 		if (!charStyleName.isEmpty())
1824 		{
1825 			for (int j = 0; j < removeList.count(); ++j)
1826 			{
1827 				const RemoveItem& rmItem = removeList.at(j);
1828 				if (charStyleName == rmItem.first)
1829 				{
1830 					QString replacementName = rmItem.second;
1831 					if (rmItem.second == CommonStrings::trDefaultCharacterStyle)
1832 						replacementName = CommonStrings::DefaultCharacterStyle;
1833 					parStyle.charStyle().setParent(replacementName);
1834 					break;
1835 				}
1836 			}
1837 		}
1838 
1839 		QString peCharStyleName = parStyle.peCharStyleName();
1840 		if (!peCharStyleName.isEmpty())
1841 		{
1842 			for (int j = 0; j < removeList.count(); ++j)
1843 			{
1844 				const RemoveItem& rmItem = removeList.at(j);
1845 				if (peCharStyleName == rmItem.first)
1846 				{
1847 					QString replacementName = rmItem.second;
1848 					if (rmItem.second == CommonStrings::trDefaultCharacterStyle)
1849 						replacementName = CommonStrings::DefaultCharacterStyle;
1850 					parStyle.setPeCharStyleName(replacementName);
1851 					break;
1852 				}
1853 			}
1854 		}
1855 	}
1856 }
1857 
~SMParagraphStyle()1858 SMParagraphStyle::~SMParagraphStyle()
1859 {
1860 	delete m_pwidget;
1861 	m_pwidget = nullptr;
1862 }
1863 
1864 /******************************************************************************/
1865 /******************************************************************************/
1866 
SMCharacterStyle()1867 SMCharacterStyle::SMCharacterStyle()
1868 {
1869 	m_widget = new QTabWidget();
1870 	Q_CHECK_PTR(m_widget);
1871 	m_widget->setContentsMargins(5, 5, 5, 5);//CB the SMCStylePage parent has a 0 value to fit properly onto the pstyle page, so add it here
1872 	m_page = new SMCStyleWidget();
1873 	Q_CHECK_PTR(m_page);
1874 //	m_widget->addTab(m_page, tr("Properties"));
1875 }
1876 
widget()1877 QTabWidget* SMCharacterStyle::widget()
1878 {
1879 	return m_page->tabwidget;
1880 }
1881 
typeNamePlural()1882 QString SMCharacterStyle::typeNamePlural()
1883 {
1884 	return tr("Character Styles");
1885 }
1886 
typeNameSingular()1887 QString SMCharacterStyle::typeNameSingular()
1888 {
1889 	return tr("Character Style");
1890 }
1891 
setCurrentDoc(ScribusDoc * doc)1892 void SMCharacterStyle::setCurrentDoc(ScribusDoc *doc)
1893 {
1894 	m_doc = doc;
1895 	if (m_page)
1896 		m_page->setDoc(doc);
1897 
1898 	if (!m_doc)
1899 	{
1900 		removeConnections();
1901 		m_selection.clear();
1902 		m_tmpStyles.clear();
1903 	}
1904 }
1905 
tmpStyles()1906 StyleSet<CharStyle>* SMCharacterStyle::tmpStyles()
1907 {
1908 	return &m_tmpStyles;
1909 }
1910 
styles(bool reloadFromDoc)1911 QList<StyleName> SMCharacterStyle::styles(bool reloadFromDoc)
1912 {
1913 	QList<StyleName> tmpList;
1914 
1915 	if (!m_doc)
1916 		return tmpList; // no doc available
1917 
1918 	if (reloadFromDoc)
1919 		reloadTmpStyles();
1920 
1921 	for (int i = 0; i < m_tmpStyles.count(); ++i)
1922 	{
1923 		if (m_tmpStyles[i].hasName())
1924 		{
1925 			QString styleName(m_tmpStyles[i].displayName());
1926 			QString parentName;
1927 
1928 			if (m_tmpStyles[i].hasParent())
1929 			{
1930 				const BaseStyle* parentStyle = m_tmpStyles[i].parentStyle();
1931 				if (parentStyle)
1932 					parentName = parentStyle->displayName();
1933 			}
1934 
1935 			tmpList << StyleName(styleName, parentName);
1936 		}
1937 	}
1938 
1939 	return tmpList;
1940 }
1941 
reload()1942 void SMCharacterStyle::reload()
1943 {
1944 	reloadTmpStyles();
1945 }
1946 
selected(const QStringList & styleNames)1947 void SMCharacterStyle::selected(const QStringList &styleNames)
1948 {
1949 	m_selection.clear();
1950 	m_selectionIsDirty = false;
1951 	removeConnections();
1952 	QList<CharStyle> cstyles;
1953 
1954 	m_tmpStyles.invalidate();
1955 
1956 	for (int i = 0; i < m_tmpStyles.count(); ++i)
1957 		cstyles << m_tmpStyles[i];
1958 
1959 	for (int i = 0; i < styleNames.count(); ++i)
1960 	{
1961 		int index = m_tmpStyles.find(styleNames[i]);
1962 		//FIXME: #7133: Use .isDefaultStyle() instead here rather than relying on tr text comparison
1963 		if (index<0 && styleNames[i]==CommonStrings::trDefaultCharacterStyle)
1964 			index = m_tmpStyles.find(CommonStrings::DefaultCharacterStyle);
1965 		if (index > -1)
1966 			m_selection.append(&m_tmpStyles[index]);
1967 
1968 	}
1969 	m_page->show(m_selection, cstyles, PrefsManager::instance().appPrefs.docSetupPrefs.language, m_doc->unitIndex());
1970 	setupConnections();
1971 }
1972 
fromSelection() const1973 QString SMCharacterStyle::fromSelection() const
1974 {
1975 	QString lsName;
1976 	if (!m_doc)
1977 		return lsName; // no doc available
1978 
1979 	for (int i = 0; i < m_doc->m_Selection->count(); ++i)
1980 	{
1981 		// wth is going on here
1982 		PageItem *item = m_doc->m_Selection->itemAt(i);
1983 
1984 		QString tmpName = item->itemText.defaultStyle().charStyle().parent();
1985 
1986 		if (lsName.isNull() && !tmpName.isEmpty() && tmpName != "")
1987 		{
1988 			lsName = tmpName;
1989 		}
1990 		else if (!lsName.isNull() && !tmpName.isEmpty() && tmpName != "" && lsName != tmpName)
1991 		{
1992 			lsName.clear();
1993 			break;
1994 		}
1995 	}
1996 	return lsName;
1997 }
1998 
toSelection(const QString & styleName) const1999 void SMCharacterStyle::toSelection(const QString &styleName) const
2000 {
2001 	if (!m_doc)
2002 		return; // nowhere to apply or no doc
2003 
2004 	QString realName = styleName;
2005 	int styleIndex = m_tmpStyles.find(styleName);
2006 	if (styleIndex < 0 && (styleName == CommonStrings::trDefaultCharacterStyle))
2007 	{
2008 		styleIndex = m_tmpStyles.find(CommonStrings::DefaultCharacterStyle);
2009 		if (styleIndex >= 0)
2010 			realName = CommonStrings::DefaultCharacterStyle;
2011 	}
2012 	if (styleIndex >= 0)
2013 	{
2014 		m_doc->itemSelection_SetNamedCharStyle(realName);
2015 	}
2016 }
2017 
newStyle()2018 QString SMCharacterStyle::newStyle()
2019 {
2020 	Q_ASSERT(m_doc && m_doc->paragraphStyles().count() > 0);
2021 
2022 	QString s = getUniqueName( tr("New Style"));
2023 	CharStyle c;
2024 	c.setDefaultStyle(false);
2025 	c.setName(s);
2026 	// #7360  - rather here than in CharStyle constructor as we have a pointer to doc.
2027 	c.setLanguage(m_doc->language());
2028 	m_tmpStyles.create(c);
2029 	return s;
2030 }
2031 
newStyle(const QString & fromStyle)2032 QString SMCharacterStyle::newStyle(const QString &fromStyle)
2033 {
2034 	//#7179, do our name switch yet again to handle this properly for default styles
2035 	//FIXME: use isDefaultStyle somehow
2036 	QString copiedStyleName(fromStyle);
2037 	if (fromStyle==CommonStrings::trDefaultCharacterStyle)
2038 		copiedStyleName=CommonStrings::DefaultCharacterStyle;
2039 
2040 	Q_ASSERT(m_tmpStyles.resolve(copiedStyleName));
2041 	if (!m_tmpStyles.resolve(copiedStyleName))
2042 		return QString();
2043 	//Copy the style with the original name
2044 	QString s(getUniqueName(fromStyle));
2045 	CharStyle c(m_tmpStyles.get(copiedStyleName));
2046 	c.setDefaultStyle(false);
2047 	c.setName(s);
2048 	c.setShortcut(QString());
2049 	m_tmpStyles.create(c);
2050 
2051 	return s;
2052 }
2053 
getUniqueName(const QString & name)2054 QString SMCharacterStyle::getUniqueName(const QString &name)
2055 {
2056 	return m_tmpStyles.getUniqueCopyName(name);
2057 }
2058 
apply()2059 void SMCharacterStyle::apply()
2060 {
2061 	if (!m_doc)
2062 		return;
2063 
2064 	QMap<QString, QString> replacement;
2065 	for (int i = 0; i < m_deleted.count(); ++i)
2066 	{
2067 		if (m_deleted[i].first == m_deleted[i].second)
2068 			continue;
2069 		replacement[m_deleted[i].first] = m_deleted[i].second;
2070 	}
2071 
2072 	m_doc->redefineCharStyles(m_tmpStyles, false);
2073 	m_doc->replaceCharStyles(replacement);
2074 
2075 	m_deleted.clear(); // deletion done at this point
2076 
2077 	m_doc->scMW()->requestUpdate(reqTextStylesUpdate);
2078 	// Better not call DrawNew() here, as this will cause several unnecessary calls
2079 	// m_doc->view()->DrawNew();
2080 	m_doc->changed();
2081 }
2082 
editMode(bool isOn)2083 void SMCharacterStyle::editMode(bool isOn)
2084 {
2085 	if (isOn)
2086 		reloadTmpStyles();
2087 }
2088 
isDefaultStyle(const QString & stylename) const2089 bool SMCharacterStyle::isDefaultStyle(const QString &stylename) const
2090 {
2091 	int index = m_tmpStyles.find(stylename);
2092 	bool b=false;
2093 	if (index > -1)
2094 		b = m_tmpStyles[index].isDefaultStyle();
2095 	else
2096 	{
2097 		if (CommonStrings::trDefaultCharacterStyle==stylename)
2098 		{
2099 			index = m_tmpStyles.find(CommonStrings::DefaultCharacterStyle);
2100 			if (index > -1)
2101 				b = m_tmpStyles[index].isDefaultStyle();
2102 		}
2103 	}
2104 	return b;
2105 }
2106 
setDefaultStyle(bool ids)2107 void SMCharacterStyle::setDefaultStyle(bool ids)
2108 {
2109 	Q_ASSERT(m_selection.count() == 1);
2110 	if (m_selection.count() != 1)
2111 		return;
2112 
2113 	m_selection[0]->setDefaultStyle(ids);
2114 
2115 	slotSelectionDirty();
2116 }
2117 
shortcut(const QString & stylename) const2118 QString SMCharacterStyle::shortcut(const QString &stylename) const
2119 {
2120 	QString s;
2121 	int index = m_tmpStyles.find(stylename);
2122 	if (index > -1)
2123 		s = m_tmpStyles[index].shortcut();
2124 	else
2125 	{
2126 		//FIXME: Use isDefaultStyle somehow
2127 		if (CommonStrings::trDefaultCharacterStyle==stylename)
2128 		{
2129 			index = m_tmpStyles.find(CommonStrings::DefaultCharacterStyle);
2130 			if (index > -1)
2131 				s = m_tmpStyles[index].shortcut();
2132 		}
2133 	}
2134 	return s;
2135 }
2136 
setShortcut(const QString & shortcut)2137 void SMCharacterStyle::setShortcut(const QString &shortcut)
2138 {
2139 	Q_ASSERT(m_selection.count() == 1);
2140 	if (m_selection.count() != 1)
2141 		return;
2142 
2143 	m_selection[0]->setShortcut(shortcut);
2144 
2145 	slotSelectionDirty();
2146 }
2147 
deleteStyles(const QList<RemoveItem> & removeList)2148 void SMCharacterStyle::deleteStyles(const QList<RemoveItem> &removeList)
2149 {
2150 	for (int i = 0; i < removeList.count(); ++i)
2151 	{
2152 		for (int k = 0; k < m_selection.count(); ++k)
2153 		{
2154 			if (m_selection[k]->name() == removeList[i].first)
2155 			{
2156 				m_selection.removeAt(k);
2157 				break;
2158 			}
2159 		}
2160 
2161 		int index = m_tmpStyles.find(removeList[i].first);
2162 		if (index > -1)
2163 			m_tmpStyles.remove(index);
2164 		m_deleted << removeList[i];
2165 	}
2166 
2167 	// Check other character styles and replace inherited styles if necessary
2168 	for (int i = 0; i < m_tmpStyles.count(); ++i)
2169 	{
2170 		CharStyle& charStyle = m_tmpStyles[i];
2171 		QString parentName = charStyle.parent();
2172 		if (parentName.isEmpty())
2173 			continue;
2174 
2175 		QString replacementName = parentName;
2176 		for (int j = 0; j < removeList.count(); ++j)
2177 		{
2178 			if (removeList.at(j).first == parentName)
2179 			{
2180 				replacementName = removeList.at(j).second;
2181 				break;
2182 			}
2183 		}
2184 
2185 		if (replacementName == parentName)
2186 			continue;
2187 		if (replacementName == CommonStrings::trDefaultCharacterStyle)
2188 			replacementName = CommonStrings::DefaultCharacterStyle;
2189 		if (!charStyle.canInherit(replacementName))
2190 			replacementName = QString();
2191 		if (!replacementName.isEmpty() && (m_tmpStyles.find(replacementName) < 0))
2192 			replacementName = QString();
2193 		charStyle.setParent(replacementName);
2194 	}
2195 
2196 	emit charStylesDeleted(removeList);
2197 }
2198 
nameChanged(const QString & newName)2199 void SMCharacterStyle::nameChanged(const QString &newName)
2200 {
2201 // 	for (int i = 0; i < m_selection.count(); ++i)
2202 // 		m_selection[i]->setName(newName);
2203 
2204 	QString oldName(m_selection[0]->name());
2205 	CharStyle c(*m_selection[0]);
2206 	c.setName(newName);
2207 	m_tmpStyles.create(c);
2208 	m_selection.clear();
2209 	m_selection.append(&m_tmpStyles[m_tmpStyles.find(newName)]);
2210 	for (int j = 0; j < m_tmpStyles.count(); ++j)
2211 	{
2212 		int index = m_tmpStyles.find(oldName);
2213 		if (index > -1)
2214 		{
2215 			m_tmpStyles.remove(index);
2216 			break;
2217 		}
2218 	}
2219 
2220 	for (int j = 0; j < m_tmpStyles.count(); ++j)
2221 	{
2222 		if (m_tmpStyles[j].parent() == oldName)
2223 			m_tmpStyles[j].setParent(newName);
2224 	}
2225 
2226 	QList<RemoveItem>::iterator it;
2227 	for (it = m_deleted.begin(); it != m_deleted.end(); ++it)
2228 	{
2229 		if (it->second == oldName)
2230 		{
2231 			oldName = (*it).first;
2232 			m_deleted.erase(it);
2233 			break;
2234 		}
2235 	}
2236 
2237 	if (oldName != newName)
2238 	{
2239 		m_deleted.append(RemoveItem(oldName, newName));
2240 		QList<RemoveItem> deletedStyles;
2241 		deletedStyles.append(RemoveItem(oldName, newName));
2242 		emit charStylesDeleted(deletedStyles);
2243 	}
2244 
2245 	slotSelectionDirty();
2246 }
2247 
languageChange()2248 void SMCharacterStyle::languageChange()
2249 {
2250 	if (m_page)
2251 	{
2252 		m_page->languageChange();
2253 	}
2254 }
2255 
unitChange()2256 void SMCharacterStyle::unitChange()
2257 {
2258 
2259 }
2260 
reloadTmpStyles()2261 void SMCharacterStyle::reloadTmpStyles()
2262 {
2263 	if (!m_doc)
2264 		return;
2265 
2266 	m_selection.clear();
2267 	m_tmpStyles.clear();
2268 	m_tmpStyles.redefine(m_doc->charStyles(), true);
2269 }
2270 
setupConnections()2271 void SMCharacterStyle::setupConnections()
2272 {
2273 	if (!m_page)
2274 		return;
2275 
2276 	connect(m_page->fontFace_, SIGNAL(fontSelected(QString)), this, SLOT(slotFont(QString)));
2277 	connect(m_page->effects_, SIGNAL(State(int)), this, SLOT(slotEffects(int)));
2278 	connect(m_page->effects_->ShadowVal->Xoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2279 	connect(m_page->effects_->ShadowVal->Yoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2280 	connect(m_page->effects_->OutlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2281 	connect(m_page->effects_->UnderlineVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2282 	connect(m_page->effects_->UnderlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2283 	connect(m_page->effects_->StrikeVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2284 	connect(m_page->effects_->StrikeVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2285 	connect(m_page->fillColor_, SIGNAL(activated(const QString&)), this, SLOT(slotFillColor()));
2286 	connect(m_page->fillShade_, SIGNAL(clicked()), this, SLOT(slotFillShade()));
2287 	connect(m_page->strokeColor_, SIGNAL(activated(const QString&)), this, SLOT(slotStrokeColor()));
2288 	connect(m_page->strokeShade_, SIGNAL(clicked()), this, SLOT(slotStrokeShade()));
2289 	connect(m_page->language_, SIGNAL(activated(int)), this, SLOT(slotLanguage()));
2290 	connect(m_page->fontSize_, SIGNAL(valueChanged(double)), this, SLOT(slotFontSize()));
2291 	connect(m_page->fontHScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleH()));
2292 	connect(m_page->fontVScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleV()));
2293 	connect(m_page->tracking_, SIGNAL(valueChanged(double)), this, SLOT(slotTracking()));
2294 	connect(m_page->widthSpaceSpin, SIGNAL(valueChanged(double)), this, SLOT(slotWordTracking()));
2295 	connect(m_page->baselineOffset_, SIGNAL(valueChanged(double)), this, SLOT(slotBaselineOffset()));
2296 	connect(m_page->parentCombo, SIGNAL(activated(const QString&)), this, SLOT(slotParentChanged(const QString&)));
2297 	connect(m_page->backColor_, SIGNAL(activated(const QString&)), this, SLOT(slotBackColor()));
2298 	connect(m_page->backShade_, SIGNAL(clicked()), this, SLOT(slotBackShade()));
2299 	connect(m_page->fontfeaturesSetting, SIGNAL(changed()), this, SLOT(slotFontFeatures()));
2300 	connect(m_page->smallestWordSpinBox, SIGNAL(valueChanged(int)), this, SLOT(slotSmallestWord()));
2301 	connect(m_page->hyphenCharLineEdit, SIGNAL(textChanged(QString)),this, SLOT(slotHyphenChar()));
2302 }
2303 
removeConnections()2304 void SMCharacterStyle::removeConnections()
2305 {
2306 	if (!m_page)
2307 		return;
2308 
2309 	disconnect(m_page->fontFace_, SIGNAL(fontSelected(QString)), this, SLOT(slotFont(QString)));
2310 	disconnect(m_page->effects_, SIGNAL(State(int)), this, SLOT(slotEffects(int)));
2311 	disconnect(m_page->effects_->ShadowVal->Xoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2312 	disconnect(m_page->effects_->ShadowVal->Yoffset, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2313 	disconnect(m_page->effects_->OutlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2314 	disconnect(m_page->effects_->UnderlineVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2315 	disconnect(m_page->effects_->UnderlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2316 	disconnect(m_page->effects_->StrikeVal->LPos, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2317 	disconnect(m_page->effects_->StrikeVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(slotEffectProperties()));
2318 	disconnect(m_page->fillColor_, SIGNAL(activated(const QString&)), this, SLOT(slotFillColor()));
2319 	disconnect(m_page->fillShade_, SIGNAL(clicked()), this, SLOT(slotFillShade()));
2320 	disconnect(m_page->strokeColor_, SIGNAL(activated(const QString&)), this, SLOT(slotStrokeColor()));
2321 	disconnect(m_page->strokeShade_, SIGNAL(clicked()), this, SLOT(slotStrokeShade()));
2322 	disconnect(m_page->language_, SIGNAL(activated(int)), this, SLOT(slotLanguage()));
2323 	disconnect(m_page->fontSize_, SIGNAL(valueChanged(double)), this, SLOT(slotFontSize()));
2324 	disconnect(m_page->fontHScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleH()));
2325 	disconnect(m_page->fontVScale_, SIGNAL(valueChanged(double)), this, SLOT(slotScaleV()));
2326 	disconnect(m_page->tracking_, SIGNAL(valueChanged(double)), this, SLOT(slotTracking()));
2327 	disconnect(m_page->widthSpaceSpin, SIGNAL(valueChanged(double)), this, SLOT(slotWordTracking()));
2328 	disconnect(m_page->baselineOffset_, SIGNAL(valueChanged(double)), this, SLOT(slotBaselineOffset()));
2329 	disconnect(m_page->parentCombo, SIGNAL(activated(const QString&)),  this, SLOT(slotParentChanged(const QString&)));
2330 	disconnect(m_page->backColor_, SIGNAL(activated(const QString&)), this, SLOT(slotBackColor()));
2331 	disconnect(m_page->backShade_, SIGNAL(clicked()), this, SLOT(slotBackShade()));
2332 	disconnect(m_page->fontfeaturesSetting, SIGNAL(changed()), this, SLOT(slotFontFeatures()));
2333 	disconnect(m_page->smallestWordSpinBox, SIGNAL(valueChanged(int)), this, SLOT(slotSmallestWord()));
2334 	disconnect(m_page->hyphenCharLineEdit, SIGNAL(textChanged(QString)),this, SLOT(slotHyphenChar()));
2335 }
2336 
slotFontSize()2337 void SMCharacterStyle::slotFontSize()
2338 {
2339 	if (m_page->fontSize_->useParentValue())
2340 		for (int i = 0; i < m_selection.count(); ++i)
2341 			m_selection[i]->resetFontSize();
2342 	else
2343 	{
2344 		double a, b, value;
2345 		int c;
2346 
2347 		m_page->fontSize_->getValues(&a, &b, &c, &value);
2348 		value = value * 10;
2349 		for (int i = 0; i < m_selection.count(); ++i)
2350 			m_selection[i]->setFontSize(qRound(value));
2351 	}
2352 
2353 	slotSelectionDirty();
2354 }
2355 
slotEffects(int e)2356 void SMCharacterStyle::slotEffects(int e)
2357 {
2358 	StyleFlag s = ScStyle_None;
2359 	if (m_page->effects_->useParentValue())
2360 	{
2361 		for (int i = 0; i < m_selection.count(); ++i)
2362 		{
2363 			m_selection[i]->resetFeatures();
2364 			m_selection[i]->resetShadowXOffset();
2365 			m_selection[i]->resetShadowYOffset();
2366 			m_selection[i]->resetOutlineWidth();
2367 			m_selection[i]->resetUnderlineOffset();
2368 			m_selection[i]->resetUnderlineWidth();
2369 			m_selection[i]->resetStrikethruOffset();
2370 			m_selection[i]->resetStrikethruWidth();
2371 		}
2372 	}
2373 	else
2374 	{
2375 		s = static_cast<StyleFlag>(e);
2376 		double a, b, sxo, syo, olw, ulp, ulw, slp, slw;
2377 		int c;
2378 
2379 		m_page->effects_->ShadowVal->Xoffset->getValues(&a, &b, &c, &sxo);
2380 		sxo *= 10;
2381 		m_page->effects_->ShadowVal->Yoffset->getValues(&a, &b, &c, &syo);
2382 		syo *= 10;
2383 
2384 		m_page->effects_->OutlineVal->LWidth->getValues(&a, &b, &c, &olw);
2385 		olw *= 10;
2386 
2387 		m_page->effects_->UnderlineVal->LPos->getValues(&a, &b, &c, &ulp);
2388 		ulp *= 10;
2389 		m_page->effects_->UnderlineVal->LWidth->getValues(&a, &b, &c, &ulw);
2390 		ulw *= 10;
2391 
2392 		m_page->effects_->StrikeVal->LPos->getValues(&a, &b, &c, &slp);
2393 		slp *= 10;
2394 		m_page->effects_->StrikeVal->LWidth->getValues(&a, &b, &c, &slw);
2395 		slw *= 10;
2396 
2397 		for (int i = 0; i < m_selection.count(); ++i)
2398 		{
2399 			QStringList feList = s.featureList();
2400 			feList.removeAll(CharStyle::INHERIT);
2401 			m_selection[i]->setFeatures(feList);
2402 //			m_selection[i]->setFeatures(s.featureList());
2403 			m_selection[i]->setShadowXOffset(qRound(sxo));
2404 			m_selection[i]->setShadowYOffset(qRound(syo));
2405 			m_selection[i]->setOutlineWidth(qRound(olw));
2406 			m_selection[i]->setUnderlineOffset(qRound(ulp));
2407 			m_selection[i]->setUnderlineWidth(qRound(ulw));
2408 			m_selection[i]->setStrikethruOffset(qRound(slp));
2409 			m_selection[i]->setStrikethruWidth(qRound(slw));
2410 		}
2411 	}
2412 
2413 	slotSelectionDirty();
2414 }
2415 
slotEffectProperties()2416 void SMCharacterStyle::slotEffectProperties()
2417 {
2418 	double a, b, sxo, syo, olw, ulp, ulw, slp, slw;
2419 	int c;
2420 
2421 	m_page->effects_->ShadowVal->Xoffset->getValues(&a, &b, &c, &sxo);
2422 	sxo *= 10;
2423 	m_page->effects_->ShadowVal->Yoffset->getValues(&a, &b, &c, &syo);
2424 	syo *= 10;
2425 
2426 	m_page->effects_->OutlineVal->LWidth->getValues(&a, &b, &c, &olw);
2427 	olw *= 10;
2428 
2429 	m_page->effects_->UnderlineVal->LPos->getValues(&a, &b, &c, &ulp);
2430 	ulp *= 10;
2431 	m_page->effects_->UnderlineVal->LWidth->getValues(&a, &b, &c, &ulw);
2432 	ulw *= 10;
2433 
2434 	m_page->effects_->StrikeVal->LPos->getValues(&a, &b, &c, &slp);
2435 	slp *= 10;
2436 	m_page->effects_->StrikeVal->LWidth->getValues(&a, &b, &c, &slw);
2437 	slw *= 10;
2438 
2439 	for (int i = 0; i < m_selection.count(); ++i)
2440 	{
2441 		m_selection[i]->setShadowXOffset(qRound(sxo));
2442 		m_selection[i]->setShadowYOffset(qRound(syo));
2443 		m_selection[i]->setOutlineWidth(qRound(olw));
2444 		m_selection[i]->setUnderlineOffset(qRound(ulp));
2445 		m_selection[i]->setUnderlineWidth(qRound(ulw));
2446 		m_selection[i]->setStrikethruOffset(qRound(slp));
2447 		m_selection[i]->setStrikethruWidth(qRound(slw));
2448 	}
2449 
2450 	slotSelectionDirty();
2451 }
2452 
slotFillColor()2453 void SMCharacterStyle::slotFillColor()
2454 {
2455 	if (m_page->fillColor_->useParentValue())
2456 		for (int i = 0; i < m_selection.count(); ++i)
2457 			m_selection[i]->resetFillColor();
2458 	else {
2459 		QString col(m_page->fillColor_->currentText());
2460 		if (col == CommonStrings::tr_NoneColor)
2461 			col = CommonStrings::None;
2462 		for (int i = 0; i < m_selection.count(); ++i)
2463 			m_selection[i]->setFillColor(col);
2464 	}
2465 
2466 	slotSelectionDirty();
2467 }
2468 
slotFillShade()2469 void SMCharacterStyle::slotFillShade()
2470 {
2471 	if (m_page->fillShade_->useParentValue())
2472 		for (int i = 0; i < m_selection.count(); ++i)
2473 			m_selection[i]->resetFillShade();
2474 	else {
2475 		int fs = m_page->fillShade_->getValue();
2476 
2477 		for (int i = 0; i < m_selection.count(); ++i)
2478 			m_selection[i]->setFillShade(fs);
2479 	}
2480 
2481 	slotSelectionDirty();
2482 }
2483 
slotBackColor()2484 void SMCharacterStyle::slotBackColor()
2485 {
2486 	if (m_page->backColor_->useParentValue())
2487 		for (int i = 0; i < m_selection.count(); ++i)
2488 			m_selection[i]->resetBackColor();
2489 	else {
2490 		QString col(m_page->backColor_->currentText());
2491 		if (col == CommonStrings::tr_NoneColor)
2492 			col = CommonStrings::None;
2493 		for (int i = 0; i < m_selection.count(); ++i)
2494 			m_selection[i]->setBackColor(col);
2495 	}
2496 
2497 	slotSelectionDirty();
2498 }
2499 
slotBackShade()2500 void SMCharacterStyle::slotBackShade()
2501 {
2502 	if (m_page->backShade_->useParentValue())
2503 		for (int i = 0; i < m_selection.count(); ++i)
2504 			m_selection[i]->resetBackShade();
2505 	else {
2506 		int fs = m_page->backShade_->getValue();
2507 
2508 		for (int i = 0; i < m_selection.count(); ++i)
2509 			m_selection[i]->setBackShade(fs);
2510 	}
2511 
2512 	slotSelectionDirty();
2513 }
2514 
slotStrokeColor()2515 void SMCharacterStyle::slotStrokeColor()
2516 {
2517 	if (m_page->strokeColor_->useParentValue())
2518 		for (int i = 0; i < m_selection.count(); ++i)
2519 			m_selection[i]->resetStrokeColor();
2520 	else {
2521 		QString col(m_page->strokeColor_->currentText());
2522 		if (col == CommonStrings::tr_NoneColor)
2523 			col = CommonStrings::None;
2524 		for (int i = 0; i < m_selection.count(); ++i)
2525 			m_selection[i]->setStrokeColor(col);
2526 	}
2527 
2528 	slotSelectionDirty();
2529 }
2530 
slotStrokeShade()2531 void SMCharacterStyle::slotStrokeShade()
2532 {
2533 	if (m_page->strokeShade_->useParentValue())
2534 		for (int i = 0; i < m_selection.count(); ++i)
2535 			m_selection[i]->resetStrokeShade();
2536 	else {
2537 		int ss = m_page->strokeShade_->getValue();
2538 
2539 		for (int i = 0; i < m_selection.count(); ++i)
2540 			m_selection[i]->setStrokeShade(ss);
2541 	}
2542 
2543 	slotSelectionDirty();
2544 }
2545 
slotLanguage()2546 void SMCharacterStyle::slotLanguage()
2547 {
2548 	QString language = m_doc->paragraphStyle("").charStyle().language();
2549 
2550 	if (m_page->language_->useParentValue())
2551 		for (int i = 0; i < m_selection.count(); ++i)
2552 			m_selection[i]->resetLanguage();
2553 	else
2554 	{
2555 		QString tl(LanguageManager::instance()->getAbbrevFromLang(m_page->language_->currentText(), false));
2556 		if (!tl.isEmpty())
2557 			language=tl;
2558 		for (int i = 0; i < m_selection.count(); ++i)
2559 			m_selection[i]->setLanguage(language);
2560 	}
2561 
2562 	slotSelectionDirty();
2563 }
2564 
slotScaleH()2565 void SMCharacterStyle::slotScaleH()
2566 {
2567 	if (m_page->fontHScale_->useParentValue())
2568 		for (int i = 0; i < m_selection.count(); ++i)
2569 			m_selection[i]->resetScaleH();
2570 	else
2571 	{
2572 		double a, b, value;
2573 		int c;
2574 
2575 		m_page->fontHScale_->getValues(&a, &b, &c, &value);
2576 		value = value * 10;
2577 		for (int i = 0; i < m_selection.count(); ++i)
2578 			m_selection[i]->setScaleH(qRound(value));
2579 	}
2580 
2581 	slotSelectionDirty();
2582 }
2583 
slotScaleV()2584 void SMCharacterStyle::slotScaleV()
2585 {
2586 	if (m_page->fontVScale_->useParentValue())
2587 		for (int i = 0; i < m_selection.count(); ++i)
2588 			m_selection[i]->resetScaleV();
2589 	else
2590 	{
2591 		double a, b, value;
2592 		int c;
2593 
2594 		m_page->fontVScale_->getValues(&a, &b, &c, &value);
2595 		value = value * 10;
2596 		for (int i = 0; i < m_selection.count(); ++i)
2597 			m_selection[i]->setScaleV(qRound(value));
2598 	}
2599 
2600 	slotSelectionDirty();
2601 }
2602 
slotTracking()2603 void SMCharacterStyle::slotTracking()
2604 {
2605 	if (m_page->tracking_->useParentValue())
2606 		for (int i = 0; i < m_selection.count(); ++i)
2607 			m_selection[i]->resetTracking();
2608 	else
2609 	{
2610 		double a, b, value;
2611 		int c;
2612 
2613 		m_page->tracking_->getValues(&a, &b, &c, &value);
2614 		value = value * 10;
2615 		for (int i = 0; i < m_selection.count(); ++i)
2616 			m_selection[i]->setTracking(qRound(value));
2617 	}
2618 
2619 	slotSelectionDirty();
2620 }
2621 
slotWordTracking()2622 void SMCharacterStyle::slotWordTracking()
2623 {
2624 	if (m_page->widthSpaceSpin->useParentValue())
2625 		for (int i = 0; i < m_selection.count(); ++i)
2626 			m_selection[i]->resetWordTracking();
2627 	else
2628 	{
2629 		double a, b, value;
2630 		int c;
2631 
2632 		m_page->widthSpaceSpin->getValues(&a, &b, &c, &value);
2633 		value = value / 100.0;
2634 		for (int i = 0; i < m_selection.count(); ++i)
2635 			m_selection[i]->setWordTracking(value);
2636 	}
2637 
2638 	slotSelectionDirty();
2639 }
2640 
slotBaselineOffset()2641 void SMCharacterStyle::slotBaselineOffset()
2642 {
2643 	if (m_page->baselineOffset_->useParentValue())
2644 		for (int i = 0; i < m_selection.count(); ++i)
2645 			m_selection[i]->resetBaselineOffset();
2646 	else
2647 	{
2648 		double a, b, value;
2649 		int c;
2650 
2651 		m_page->baselineOffset_->getValues(&a, &b, &c, &value);
2652 		value = value * 10;
2653 		for (int i = 0; i < m_selection.count(); ++i)
2654 			m_selection[i]->setBaselineOffset(qRound(value));
2655 	}
2656 
2657 	slotSelectionDirty();
2658 }
2659 
slotHyphenChar()2660 void SMCharacterStyle::slotHyphenChar()
2661 {
2662 	if (m_page->hyphenCharLineEdit->useParentValue())
2663 		for (int i = 0; i < m_selection.count(); ++i)
2664 			m_selection[i]->resetHyphenChar();
2665 	else
2666 	{
2667 		QString hyphenText = m_page->hyphenCharLineEdit->text();
2668 		uint ch = hyphenText.isEmpty() ? 0 : hyphenText.toUcs4()[0];
2669 		for (int i = 0; i < m_selection.count(); ++i)
2670 			m_selection[i]->setHyphenChar(ch);
2671 	}
2672 
2673 	slotSelectionDirty();
2674 }
2675 
slotSmallestWord()2676 void SMCharacterStyle::slotSmallestWord()
2677 {
2678 	if (m_page->smallestWordSpinBox->useParentValue())
2679 		for (int i = 0; i < m_selection.count(); ++i)
2680 			m_selection[i]->resetHyphenWordMin();
2681 	else
2682 	{
2683 		int sw = m_page->smallestWordSpinBox->value();
2684 		for (int i = 0; i < m_selection.count(); ++i)
2685 			m_selection[i]->setHyphenWordMin(sw);
2686 	}
2687 
2688 	slotSelectionDirty();
2689 }
2690 
slotFont(const QString & s)2691 void SMCharacterStyle::slotFont(const QString& s)
2692 {
2693 	if (m_page->fontFace_->useParentFont())
2694 		for (int i = 0; i < m_selection.count(); ++i)
2695 			m_selection[i]->resetFont();
2696 	else {
2697 		ScFace sf = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts[s];
2698 
2699 		for (int i = 0; i < m_selection.count(); ++i)
2700 			m_selection[i]->setFont(sf);
2701 	}
2702 
2703 	slotSelectionDirty();
2704 }
2705 
slotParentChanged(const QString & parent)2706 void SMCharacterStyle::slotParentChanged(const QString &parent)
2707 {
2708 	Q_ASSERT(!parent.isNull());
2709 
2710 	bool  loop = false, parentLoop = false;
2711 	const BaseStyle* parentStyle = (!parent.isEmpty()) ? m_tmpStyles.resolve(parent) : nullptr;
2712 	QStringList  sel;
2713 
2714 	for (int i = 0; i < m_selection.count(); ++i)
2715 	{
2716 		loop = false;
2717 		// Check if setting parent won't create a loop
2718 		const BaseStyle* pStyle = parentStyle;
2719 		while (pStyle)
2720 		{
2721 			if (pStyle->hasParent() && (pStyle->parent() == m_selection[i]->name()))
2722 			{
2723 				loop = parentLoop = true;
2724 				break;
2725 			}
2726 			pStyle = pStyle->hasParent() ? pStyle->parentStyle() : nullptr;
2727 		}
2728 		if (!loop)
2729 		{
2730 			m_selection[i]->erase();
2731 			m_selection[i]->setParent(parent);
2732 		}
2733 		sel << m_selection[i]->name();
2734 	}
2735 
2736 	if (parentLoop)
2737 		ScMessageBox::warning(this->widget(), CommonStrings::trWarning, tr("Setting that style as parent would create an infinite loop."));
2738 
2739 	selected(sel);
2740 
2741 	slotSelectionDirty();
2742 }
2743 
slotFontFeatures()2744 void SMCharacterStyle::slotFontFeatures()
2745 {
2746 	if (m_page->fontfeaturesSetting->useParentValue())
2747 		for (int i = 0; i < m_selection.count(); ++i)
2748 			m_selection[i]->resetFontFeatures();
2749 	else
2750 	{
2751 		QString fontfeatures = m_page->fontfeaturesSetting->fontFeatures();
2752 
2753 		for (int i = 0; i < m_selection.count(); ++i)
2754 			m_selection[i]->setFontFeatures(fontfeatures);
2755 	}
2756 
2757 	slotSelectionDirty();
2758 }
2759 
slotSelectionDirty()2760 void SMCharacterStyle::slotSelectionDirty()
2761 {
2762 	if (m_selectionIsDirty)
2763 		return;
2764 	m_selectionIsDirty = true;
2765 	emit selectionDirty();
2766 }
2767 
~SMCharacterStyle()2768 SMCharacterStyle::~SMCharacterStyle()
2769 {
2770 	delete m_page;
2771 	delete m_widget;
2772 	m_page = nullptr;
2773 	m_widget = nullptr;
2774 }
2775 
2776