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
9 #include "propertiespalette_text.h"
10
11 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
12 #define _USE_MATH_DEFINES
13 #endif
14 #include <cmath>
15 #include <QSignalBlocker>
16
17 #include "appmodes.h"
18 #include "colorcombo.h"
19 #include "colorlistbox.h"
20 #include "commonstrings.h"
21 #include "fontcombo.h"
22 #include "iconmanager.h"
23 #include "localemgr.h"
24 #include "pageitem.h"
25 #include "pageitem_table.h"
26 #include "pageitem_textframe.h"
27 #include "propertiespalette_utils.h"
28 #include "propertywidget_advanced.h"
29 #include "propertywidget_distance.h"
30 #include "propertywidget_flop.h"
31 #include "propertywidget_fontfeatures.h"
32 #include "propertywidget_hyphenation.h"
33 #include "propertywidget_optmargins.h"
34 #include "propertywidget_orphans.h"
35 #include "propertywidget_pareffect.h"
36 #include "propertywidget_pathtext.h"
37 #include "propertywidget_textcolor.h"
38 #include "scfonts.h"
39 #include "scraction.h"
40 #include "scribusapp.h"
41 #include "scribuscore.h"
42 #include "selection.h"
43 #include "stylecombos.h"
44 #include "styleselect.h"
45 #include "tabmanager.h"
46 #include "undomanager.h"
47 #include "units.h"
48 #include "util.h"
49 #include "util_math.h"
50 #include "langmgr.h"
51
52 //using namespace std;
53
PropertiesPalette_Text(QWidget * parent)54 PropertiesPalette_Text::PropertiesPalette_Text( QWidget* parent) : QWidget(parent)
55 {
56 setupUi(this);
57
58 fontSize->setPrefix( "" );
59
60 iconSetChange();
61
62 colorWidgets = new PropertyWidget_TextColor(textTree);
63 colorWidgetsItem = textTree->addItem( colorWidgets, tr("Color && Effects") );
64
65 flopBox = new PropertyWidget_Flop(textTree);
66 flopItem = textTree->addItem( flopBox, tr("First Line Offset"));
67
68 orphanBox = new PropertyWidget_Orphans(textTree);
69 orphanItem = textTree->addItem(orphanBox, tr("Orphans and Widows"));
70
71 parEffectWidgets = new PropertyWidget_ParEffect(textTree);
72 parEffectItem = textTree->addItem(parEffectWidgets, tr("Paragraph Effects"));
73
74 distanceWidgets = new PropertyWidget_Distance(textTree);
75 distanceItem = textTree->addItem(distanceWidgets, tr("Columns && Text Distances"));
76
77 //<< Optical Margins
78 optMargins = new PropertyWidget_OptMargins(textTree);
79 optMarginsItem = textTree->addItem(optMargins, tr("Optical Margins"));
80 //>> Optical Margins
81
82 hyphenationWidget = new PropertyWidget_Hyphenation(textTree);
83 hyphenationWidgetItem = textTree->addItem(hyphenationWidget, tr("Hyphenation"));
84
85 //<<Advanced Settings
86 advancedWidgets = new PropertyWidget_Advanced(textTree);
87 advancedWidgetsItem = textTree->addItem(advancedWidgets, tr("Advanced Settings"));
88
89 //>>Advanced Settings
90 fontfeaturesWidget = new PropertyWidget_FontFeatures(textTree);
91 fontfeaturesWidgetItem = textTree->addItem(fontfeaturesWidget, tr("Font Features"));
92
93 pathTextWidgets = new PropertyWidget_PathText(textTree);
94 pathTextItem = textTree->addItem(pathTextWidgets, tr("Path Text Properties"));
95
96 languageChange();
97
98 connect(lineSpacing , SIGNAL(valueChanged(double)), this, SLOT(handleLineSpacing()));
99 connect(fonts , SIGNAL(fontSelected(QString)), this, SLOT(handleTextFont(QString)));
100 connect(fontSize , SIGNAL(valueChanged(double)), this, SLOT(handleFontSize()));
101 connect(textAlignment , SIGNAL(State(int)) , this, SLOT(handleAlignment(int)));
102 connect(textDirection , SIGNAL(State(int)) , this, SLOT(handleDirection(int)));
103 connect(charStyleClear, SIGNAL(clicked()), this, SLOT(doClearCStyle()));
104 connect(paraStyleClear, SIGNAL(clicked()), this, SLOT(doClearPStyle()));
105
106 connect(flopBox->flopGroup, SIGNAL(buttonClicked( int )), this, SLOT(handleFirstLinePolicy(int)));
107
108 connect(lineSpacingModeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(handleLineSpacingMode(int)));
109 connect(langCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changeLang(int)));
110
111 connect(fontfeaturesWidget, SIGNAL(needsRelayout()), this, SLOT(updateTreeLayout()));
112 connect(parEffectWidgets, SIGNAL(needsRelayout()), this, SLOT(updateTreeLayout()));
113
114 connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
115 connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
116
117 setEnabled(false);
118 }
119
setMainWindow(ScribusMainWindow * mw)120 void PropertiesPalette_Text::setMainWindow(ScribusMainWindow* mw)
121 {
122 m_ScMW = mw;
123
124 advancedWidgets->setMainWindow(mw);
125 fontfeaturesWidget->setMainWindow(mw);
126 colorWidgets->setMainWindow(mw);
127 distanceWidgets->setMainWindow(mw);
128 hyphenationWidget->setMainWindow(mw);
129 parEffectWidgets->setMainWindow(mw);
130 optMargins->setMainWindow(mw);
131 pathTextWidgets->setMainWindow(mw);
132
133 connect(m_ScMW, SIGNAL(UpdateRequest(int)) , this , SLOT(handleUpdateRequest(int)));
134
135 connect(paraStyleCombo, SIGNAL(newStyle(const QString&)), m_ScMW, SLOT(setNewParStyle(const QString&)), Qt::UniqueConnection);
136 connect(charStyleCombo, SIGNAL(newStyle(const QString&)), m_ScMW, SLOT(setNewCharStyle(const QString&)), Qt::UniqueConnection);
137 }
138
setDoc(ScribusDoc * d)139 void PropertiesPalette_Text::setDoc(ScribusDoc *d)
140 {
141 if((d == (ScribusDoc*) m_doc) || (m_ScMW && m_ScMW->scriptIsRunning()))
142 return;
143
144 if (m_doc)
145 {
146 disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
147 disconnect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
148 }
149
150 m_doc = d;
151 m_item = nullptr;
152
153 m_unitRatio = m_doc->unitRatio();
154 m_unitIndex = m_doc->unitIndex();
155
156 m_haveDoc = true;
157 m_haveItem = false;
158
159 fontSize->setValues(0.5, 2048, 2, 1);
160 lineSpacing->setValues(1, 2048, 2, 1);
161
162 advancedWidgets->setDoc(m_doc);
163 fontfeaturesWidget->setDoc(m_doc);
164 colorWidgets->setDoc(m_doc);
165 distanceWidgets->setDoc(m_doc);
166 parEffectWidgets->setDoc(m_doc);
167 flopBox->setDoc(m_doc);
168 hyphenationWidget->setDoc(m_doc);
169 optMargins->setDoc(m_doc);
170 orphanBox->setDoc(m_doc);
171 pathTextWidgets->setDoc(m_doc);
172
173 fonts->rebuildList(m_doc);
174 paraStyleCombo->setDoc(m_doc);
175 charStyleCombo->setDoc(m_doc);
176
177 connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
178 connect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
179 }
180
unsetDoc()181 void PropertiesPalette_Text::unsetDoc()
182 {
183 if (m_doc)
184 {
185 disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
186 disconnect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
187 }
188
189 m_haveDoc = false;
190 m_haveItem = false;
191 m_doc = nullptr;
192 m_item = nullptr;
193
194 paraStyleCombo->setDoc(nullptr);
195 charStyleCombo->setDoc(nullptr);
196
197 advancedWidgets->setDoc(nullptr);
198 fontfeaturesWidget->setDoc(nullptr);
199 colorWidgets->setDoc(nullptr);
200 distanceWidgets->setDoc(nullptr);
201 flopBox->setDoc(nullptr);
202 hyphenationWidget->setDoc(nullptr);
203 optMargins->setDoc(nullptr);
204 orphanBox->setDoc(nullptr);
205 parEffectWidgets->setDoc(nullptr);
206 pathTextWidgets->setDoc(nullptr);
207
208 m_haveItem = false;
209
210 setEnabled(false);
211 }
212
unsetItem()213 void PropertiesPalette_Text::unsetItem()
214 {
215 m_haveItem = false;
216 m_item = nullptr;
217 colorWidgets->setCurrentItem(m_item);
218 handleSelectionChanged();
219 }
220
currentItemFromSelection()221 PageItem* PropertiesPalette_Text::currentItemFromSelection()
222 {
223 PageItem *currentItem = nullptr;
224
225 if (m_doc)
226 {
227 if (m_doc->m_Selection->count() > 1)
228 currentItem = m_doc->m_Selection->itemAt(0);
229 else if (m_doc->m_Selection->count() == 1)
230 currentItem = m_doc->m_Selection->itemAt(0);
231 if (currentItem && currentItem->isTable() && m_doc->appMode == modeEditTable)
232 currentItem = currentItem->asTable()->activeCell().textFrame();
233 }
234
235 return currentItem;
236 }
237
handleSelectionChanged()238 void PropertiesPalette_Text::handleSelectionChanged()
239 {
240 if (!m_haveDoc || !m_ScMW || m_ScMW->scriptIsRunning())
241 return;
242
243 PageItem* currItem = currentItemFromSelection();
244 if (m_doc->m_Selection->count() > 1)
245 {
246 setEnabled(false);
247 flopBox->flopRealHeight->setChecked(true);
248 }
249 else
250 {
251 int itemType = currItem ? (int) currItem->itemType() : -1;
252 m_haveItem = (itemType != -1);
253
254 switch (itemType)
255 {
256 case -1:
257 m_haveItem = false;
258 m_item = nullptr;
259 setEnabled(false);
260 break;
261 case PageItem::TextFrame:
262 case PageItem::PathText:
263 setEnabled(true);
264 break;
265 case PageItem::Table:
266 setEnabled(m_doc->appMode == modeEditTable);
267 break;
268 default:
269 setEnabled(false);
270 break;
271 }
272 }
273 if (currItem)
274 {
275 setCurrentItem(currItem);
276 }
277 updateGeometry();
278 //repaint();
279 }
280
handleUpdateRequest(int updateFlags)281 void PropertiesPalette_Text::handleUpdateRequest(int updateFlags)
282 {
283 // ColorWidget will handle its update itself
284 /*if (updateFlags & reqColorsUpdate)
285 updateColorList();*/
286 if (updateFlags & reqCharStylesUpdate)
287 {
288 charStyleCombo->updateStyleList();
289 parEffectWidgets->updateCharStyles();
290 }
291 if (updateFlags & reqParaStylesUpdate)
292 paraStyleCombo->updateStyleList();
293 if (updateFlags & reqDefFontListUpdate)
294 fonts->rebuildList(nullptr);
295 if (updateFlags & reqDocFontListUpdate)
296 fonts->rebuildList(m_haveDoc ? m_doc : nullptr);
297 if (updateFlags & reqStyleComboDocUpdate)
298 {
299 paraStyleCombo->setDoc(m_haveDoc ? m_doc : nullptr);
300 charStyleCombo->setDoc(m_haveDoc ? m_doc : nullptr);
301 parEffectWidgets->setDoc(m_haveDoc ? m_doc : nullptr);
302 }
303 }
304
setCurrentItem(PageItem * item)305 void PropertiesPalette_Text::setCurrentItem(PageItem *item)
306 {
307 if (!m_ScMW || m_ScMW->scriptIsRunning())
308 return;
309 //CB We shouldn't really need to process this if our item is the same one
310 //maybe we do if the item has been changed by scripter.. but that should probably
311 //set some status if so.
312 //FIXME: This won't work until when a canvas deselect happens, m_item must be nullptr.
313 //if (m_item == i)
314 // return;
315
316 if (!m_doc)
317 setDoc(item->doc());
318
319 m_haveItem = false;
320 m_item = item;
321
322 showFirstLinePolicy(m_item->firstLineOffset());
323
324 if ((m_item->isGroup()) && (!m_item->isSingleSel))
325 {
326 setEnabled(false);
327 }
328
329 m_haveItem = true;
330
331 if (!sender())
332 {
333 colorWidgets->handleSelectionChanged();
334 distanceWidgets->handleSelectionChanged();
335 parEffectWidgets->handleSelectionChanged();
336 }
337
338 if (m_item->isTextFrame() || m_item->isPathText() || m_item->isTable())
339 {
340 ParagraphStyle parStyle = m_item->itemText.defaultStyle();
341 if (m_doc->appMode == modeEdit || m_doc->appMode == modeEditTable)
342 m_item->currentTextProps(parStyle);
343 updateStyle(parStyle);
344 }
345 if (m_item->isOSGFrame())
346 {
347 setEnabled(false);
348 }
349 if (m_item->asSymbol())
350 {
351 setEnabled(false);
352 }
353 }
354
iconSetChange()355 void PropertiesPalette_Text::iconSetChange()
356 {
357 IconManager& iconManager = IconManager::instance();
358
359 fontSizeLabel->setPixmap(iconManager.loadPixmap("zeichen.png"));
360 lineSpacingLabel->setPixmap(iconManager.loadPixmap("linespacing2.png"));
361 textAlignmentLabel->setPixmap(iconManager.loadPixmap("22/text-align.png"));
362 langLabel->setPixmap(iconManager.loadPixmap("22/language.png"));
363 paraStyleLabel->setPixmap(iconManager.loadPixmap("22/paragraph-style.png"));
364 charStyleLabel->setPixmap(iconManager.loadPixmap("22/character-style.png"));
365
366 paraStyleClear->setIcon(iconManager.loadPixmap("16/edit-clear.png"));
367 charStyleClear->setIcon(iconManager.loadPixmap("16/edit-clear.png"));
368 }
369
unitChange()370 void PropertiesPalette_Text::unitChange()
371 {
372 if (!m_haveDoc)
373 return;
374 bool tmp = m_haveItem;
375 m_haveItem = false;
376
377 advancedWidgets->unitChange();
378 fontfeaturesWidget->unitChange();
379 colorWidgets->unitChange();
380 distanceWidgets->unitChange();
381 flopBox->unitChange();
382 optMargins->unitChange();
383 pathTextWidgets->unitChange();
384 parEffectWidgets->unitChange();
385
386 m_haveItem = tmp;
387 }
388
localeChange()389 void PropertiesPalette_Text::localeChange()
390 {
391 const QLocale& l(LocaleManager::instance().userPreferredLocale());
392 fontSize->setLocale(l);
393 lineSpacing->setLocale(l);
394 advancedWidgets->localeChange();
395 colorWidgets->localeChange();
396 distanceWidgets->localeChange();
397 parEffectWidgets->localeChange();
398 pathTextWidgets->localeChange();
399 }
400
handleLineSpacingMode(int id)401 void PropertiesPalette_Text::handleLineSpacingMode(int id)
402 {
403 if (!m_haveDoc || !m_haveItem)
404 return;
405 Selection tempSelection(this, false);
406 tempSelection.addItem(m_item, true);
407 m_doc->itemSelection_SetLineSpacingMode(id, &tempSelection);
408 // updateStyle(((m_doc->appMode == modeEdit) || (m_doc->appMode == modeEditTable)) ? m_item->currentStyle() : m_item->itemText.defaultStyle());
409 m_doc->regionsChanged()->update(QRect());
410 }
411
changeLang(int id)412 void PropertiesPalette_Text::changeLang(int id)
413 {
414 if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
415 return;
416 QStringList languageList;
417 LanguageManager::instance()->fillInstalledStringList(&languageList);
418 QString abrv = LanguageManager::instance()->getAbbrevFromLang(languageList.value(id),false);
419 Selection tempSelection(this, false);
420 tempSelection.addItem(m_item, true);
421 m_doc->itemSelection_SetLanguage(abrv, &tempSelection);
422 }
423
showLineSpacing(double r)424 void PropertiesPalette_Text::showLineSpacing(double r)
425 {
426 if (!m_ScMW || m_ScMW->scriptIsRunning())
427 return;
428 bool inEditMode = (m_doc->appMode == modeEdit || m_doc->appMode == modeEditTable);
429 bool tmp = m_haveItem;
430 m_haveItem = false;
431 lineSpacing->showValue(r);
432 const ParagraphStyle& curStyle(m_haveItem && inEditMode ? m_item->currentStyle() : m_item->itemText.defaultStyle());
433 if (tmp)
434 {
435 setupLineSpacingSpinbox(curStyle.lineSpacingMode(), r);
436 lineSpacingModeCombo->setCurrentIndex(curStyle.lineSpacingMode());
437 }
438 m_haveItem = tmp;
439 }
440
showFontFace(const QString & newFont)441 void PropertiesPalette_Text::showFontFace(const QString& newFont)
442 {
443 if (!m_ScMW || m_ScMW->scriptIsRunning())
444 return;
445 bool tmp = m_haveItem;
446 m_haveItem = false;
447 if (m_item != nullptr)
448 fonts->rebuildList(m_doc, m_item->isAnnotation());
449 fonts->setCurrentFont(newFont);
450 m_haveItem = tmp;
451 }
452
showFontSize(double s)453 void PropertiesPalette_Text::showFontSize(double s)
454 {
455 if (!m_ScMW || m_ScMW->scriptIsRunning())
456 return;
457 fontSize->showValue(s / 10.0);
458 }
459
showLanguage(const QString & w)460 void PropertiesPalette_Text::showLanguage(const QString& w)
461 {
462 if (!m_ScMW || m_ScMW->scriptIsRunning())
463 return;
464 QStringList lang;
465 LanguageManager::instance()->fillInstalledStringList(&lang);
466 QString langName = LanguageManager::instance()->getLangFromAbbrev(w, true);
467
468 bool sigBlocked = langCombo->blockSignals(true);
469 langCombo->setCurrentIndex(lang.indexOf(langName));
470 langCombo->blockSignals(sigBlocked);
471 }
472
showFirstLinePolicy(FirstLineOffsetPolicy f)473 void PropertiesPalette_Text::showFirstLinePolicy( FirstLineOffsetPolicy f )
474 {
475 if(f == FLOPFontAscent)
476 flopBox->flopFontAscent->setChecked(true);
477 else if(f == FLOPLineSpacing)
478 flopBox->flopLineSpacing->setChecked(true);
479 else if (f == FLOPRealGlyphHeight)
480 flopBox->flopRealHeight->setChecked(true); //It’s historical behaviour.
481 else // if (f == FLOPBaseline)
482 flopBox->flopBaselineGrid->setChecked(true);
483 }
484
setupLineSpacingSpinbox(int mode,double value)485 void PropertiesPalette_Text::setupLineSpacingSpinbox(int mode, double value)
486 {
487 bool blocked = lineSpacing->blockSignals(true);
488 if (mode > 0)
489 {
490 if (mode == 1)
491 lineSpacing->setSpecialValueText( tr( "Auto" ) );
492 if (mode == 2)
493 lineSpacing->setSpecialValueText( tr( "Baseline" ) );
494 lineSpacing->setMinimum(0);
495 lineSpacing->setValue(0);
496 lineSpacing->setEnabled(false);
497 }
498 else
499 {
500 lineSpacing->setSpecialValueText("");
501 lineSpacing->setMinimum(1);
502 lineSpacing->setValue(value);
503 lineSpacing->setEnabled(true);
504 }
505 lineSpacing->blockSignals(blocked);
506 }
507
updateCharStyle(const CharStyle & charStyle)508 void PropertiesPalette_Text::updateCharStyle(const CharStyle& charStyle)
509 {
510 if (!m_ScMW || m_ScMW->scriptIsRunning())
511 return;
512
513 advancedWidgets->updateCharStyle(charStyle);
514 fontfeaturesWidget->updateCharStyle(charStyle);
515 colorWidgets->updateCharStyle(charStyle);
516 hyphenationWidget->updateCharStyle(charStyle);
517
518 showFontFace(charStyle.font().scName());
519 showFontSize(charStyle.fontSize());
520 showLanguage(charStyle.language());
521 }
522
updateStyle(const ParagraphStyle & newCurrent)523 void PropertiesPalette_Text::updateStyle(const ParagraphStyle& newCurrent)
524 {
525 if (!m_ScMW || m_ScMW->scriptIsRunning())
526 return;
527
528 const CharStyle& charStyle = newCurrent.charStyle();
529
530 advancedWidgets->updateStyle(newCurrent);
531 fontfeaturesWidget->updateStyle(newCurrent);
532 colorWidgets->updateStyle(newCurrent);
533 optMargins->updateStyle(newCurrent);
534 orphanBox->updateStyle (newCurrent);
535 parEffectWidgets->updateStyle(newCurrent);
536 hyphenationWidget->updateStyle(newCurrent);
537
538 showFontFace(charStyle.font().scName());
539 showFontSize(charStyle.fontSize());
540 showLanguage(charStyle.language());
541
542 if (m_item)
543 {
544 QString defaultParStyle = m_item->itemText.defaultStyle().parent();
545 if (defaultParStyle.isEmpty())
546 defaultParStyle = CommonStrings::DefaultParagraphStyle;
547 paraStyleCombo->setDefaultStyle(defaultParStyle);
548 }
549 showParStyle(newCurrent.parent());
550
551 if (m_item)
552 {
553 QString defaultCharStyle;
554 if (!newCurrent.parent().isEmpty())
555 {
556 const ParagraphStyle& paraStyle = m_doc->paragraphStyles().get(newCurrent.parent());
557 defaultCharStyle = paraStyle.charStyle().parent();
558 if (defaultCharStyle.isEmpty())
559 defaultCharStyle = CommonStrings::DefaultCharacterStyle;
560 }
561 if (defaultCharStyle.isEmpty())
562 defaultCharStyle = m_item->itemText.defaultStyle().charStyle().parent();
563 if (defaultCharStyle.isEmpty())
564 defaultCharStyle = CommonStrings::DefaultCharacterStyle;
565 charStyleCombo->setDefaultStyle(defaultCharStyle);
566 }
567 showCharStyle(charStyle.parent());
568
569 bool tmp = m_haveItem;
570 m_haveItem = false;
571
572 setupLineSpacingSpinbox(newCurrent.lineSpacingMode(), newCurrent.lineSpacing());
573 lineSpacingModeCombo->setCurrentIndex(newCurrent.lineSpacingMode());
574 textAlignment->setStyle(newCurrent.alignment(), newCurrent.direction());
575 textDirection->setStyle(newCurrent.direction());
576
577 m_haveItem = tmp;
578 }
579
updateCharStyles()580 void PropertiesPalette_Text::updateCharStyles()
581 {
582 charStyleCombo->updateStyleList();
583 parEffectWidgets->updateCharStyles();
584 }
585
updateParagraphStyles()586 void PropertiesPalette_Text::updateParagraphStyles()
587 {
588 paraStyleCombo->updateStyleList();
589 charStyleCombo->updateStyleList();
590 parEffectWidgets->updateCharStyles();
591 }
592
updateTextStyles()593 void PropertiesPalette_Text::updateTextStyles()
594 {
595 paraStyleCombo->updateStyleList();
596 charStyleCombo->updateStyleList();
597 }
598
updateTreeLayout()599 void PropertiesPalette_Text::updateTreeLayout()
600 {
601 textTree->doItemsLayout();
602 }
603
showAlignment(int e)604 void PropertiesPalette_Text::showAlignment(int e)
605 {
606 if (!m_ScMW || m_ScMW->scriptIsRunning())
607 return;
608 bool tmp = m_haveItem;
609 m_haveItem = false;
610 textAlignment->setEnabled(true);
611 textAlignment->setStyle(e, textDirection->getStyle());
612 m_haveItem = tmp;
613 }
614
showDirection(int e)615 void PropertiesPalette_Text::showDirection(int e)
616 {
617 if (!m_ScMW || m_ScMW->scriptIsRunning())
618 return;
619 bool tmp = m_haveItem;
620 m_haveItem = false;
621 textDirection->setEnabled(true);
622 textDirection->setStyle(e);
623 m_haveItem = tmp;
624 }
625
showCharStyle(const QString & name)626 void PropertiesPalette_Text::showCharStyle(const QString& name)
627 {
628 if (!m_ScMW || m_ScMW->scriptIsRunning())
629 return;
630 bool blocked = charStyleCombo->blockSignals(true);
631 charStyleCombo->setStyle(name);
632 charStyleCombo->blockSignals(blocked);
633 }
634
showParStyle(const QString & name)635 void PropertiesPalette_Text::showParStyle(const QString& name)
636 {
637 if (!m_ScMW || m_ScMW->scriptIsRunning())
638 return;
639 bool blocked = paraStyleCombo->blockSignals(true);
640 paraStyleCombo->setStyle(name);
641 paraStyleCombo->blockSignals(blocked);
642 }
643
handleLineSpacing()644 void PropertiesPalette_Text::handleLineSpacing()
645 {
646 if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
647 return;
648 Selection tempSelection(this, false);
649 tempSelection.addItem(m_item, true);
650 m_doc->itemSelection_SetLineSpacing(lineSpacing->value(), &tempSelection);
651 }
652
handleFontSize()653 void PropertiesPalette_Text::handleFontSize()
654 {
655 if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
656 return;
657 Selection tempSelection(this, false);
658 tempSelection.addItem(m_item, true);
659 m_doc->itemSelection_SetFontSize(qRound(fontSize->value()*10.0), &tempSelection);
660 }
661
handleAlignment(int a)662 void PropertiesPalette_Text::handleAlignment(int a)
663 {
664 if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
665 return;
666 Selection tempSelection(this, false);
667 tempSelection.addItem(m_item, true);
668 m_doc->itemSelection_SetAlignment(a, &tempSelection);
669 if (m_item->isPathText())
670 pathTextWidgets->handleSelectionChanged();
671 }
672
handleDirection(int d)673 void PropertiesPalette_Text::handleDirection(int d)
674 {
675 if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
676 return;
677 Selection tempSelection(this, false);
678 tempSelection.addItem(m_item, true);
679 m_doc->itemSelection_SetDirection(d, &tempSelection);
680 // If current text alignment is left or right, change it to match direction
681 if (d == ParagraphStyle::RTL && textAlignment->selectedId() == ParagraphStyle::LeftAligned)
682 {
683 m_doc->itemSelection_SetAlignment(ParagraphStyle::RightAligned, &tempSelection);
684 textAlignment->setTypeStyle(ParagraphStyle::RightAligned);
685 }
686 else if (d == ParagraphStyle::LTR && textAlignment->selectedId() == ParagraphStyle::RightAligned)
687 {
688 m_doc->itemSelection_SetAlignment(ParagraphStyle::LeftAligned, &tempSelection);
689 textAlignment->setTypeStyle(ParagraphStyle::LeftAligned);
690 }
691 }
692
handleTextFont(const QString & font)693 void PropertiesPalette_Text::handleTextFont(const QString& font)
694 {
695 if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
696 return;
697 Selection tempSelection(this, false);
698 tempSelection.addItem(m_item, true);
699 m_doc->itemSelection_SetFont(font, &tempSelection);
700 }
701
doClearCStyle()702 void PropertiesPalette_Text::doClearCStyle()
703 {
704 if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveDoc || !m_haveItem)
705 return;
706 Selection tempSelection(this, false);
707 tempSelection.addItem(m_item, true);
708 m_doc->itemSelection_EraseCharStyle(&tempSelection);
709 }
710
711
doClearPStyle()712 void PropertiesPalette_Text::doClearPStyle()
713 {
714 if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveDoc || !m_haveItem)
715 return;
716
717 UndoTransaction activeTransaction;
718 if (UndoManager::undoEnabled())
719 activeTransaction = UndoManager::instance()->beginTransaction(Um::SelectionGroup, Um::IGroup, Um::RemoveTextStyle, tr( "remove direct paragraph formatting" ), Um::IFont);
720
721 Selection tempSelection(this, false);
722 tempSelection.addItem(m_item, true);
723 m_doc->itemSelection_ClearBulNumStrings(&tempSelection);
724 m_doc->itemSelection_EraseParagraphStyle(&tempSelection);
725 CharStyle emptyCStyle;
726 m_doc->itemSelection_SetCharStyle(emptyCStyle, &tempSelection);
727
728 if (activeTransaction)
729 activeTransaction.commit();
730 }
731
updateColorList()732 void PropertiesPalette_Text::updateColorList()
733 {
734 if (!m_haveDoc || !m_ScMW || m_ScMW->scriptIsRunning())
735 return;
736
737 colorWidgets->updateColorList();
738 }
739
changeEvent(QEvent * e)740 void PropertiesPalette_Text::changeEvent(QEvent *e)
741 {
742 if (e->type() == QEvent::LanguageChange)
743 {
744 languageChange();
745 return;
746 }
747 QWidget::changeEvent(e);
748 }
749
languageChange()750 void PropertiesPalette_Text::languageChange()
751 {
752 retranslateUi(this);
753
754 textTree->setItemText(colorWidgetsItem, tr("Color && Effects"));
755 textTree->setItemText(flopItem, tr("First Line Offset"));
756 textTree->setItemText(hyphenationWidgetItem, tr("Hyphenation"));
757 textTree->setItemText(orphanItem, tr("Orphans and Widows"));
758 textTree->setItemText(parEffectItem, tr("Paragraph Effects"));
759 textTree->setItemText(distanceItem, tr("Columns && Text Distances"));
760 textTree->setItemText(optMarginsItem, tr("Optical Margins"));
761 textTree->setItemText(advancedWidgetsItem, tr("Advanced Settings"));
762 textTree->setItemText(fontfeaturesWidgetItem, tr("Font Features"));
763 textTree->setItemText(pathTextItem, tr("Path Text Properties"));
764
765 QSignalBlocker lineSpacingModeBlocker(lineSpacingModeCombo);
766 int oldLineSpacingMode = lineSpacingModeCombo->currentIndex();
767 lineSpacingModeCombo->clear();
768 lineSpacingModeCombo->addItem( tr("Fixed Linespacing"));
769 lineSpacingModeCombo->addItem( tr("Automatic Linespacing"));
770 lineSpacingModeCombo->addItem( tr("Align to Baseline Grid"));
771 lineSpacingModeCombo->setCurrentIndex(oldLineSpacingMode);
772
773 QSignalBlocker langComboBlocker(langCombo);
774 QStringList languageList;
775 LanguageManager::instance()->fillInstalledStringList(&languageList);
776 int oldLang = langCombo->currentIndex();
777 langCombo->clear();
778 langCombo->addItems(languageList);
779 langCombo->setCurrentIndex(oldLang);
780
781 colorWidgets->languageChange();
782 flopBox->languageChange();
783 orphanBox->languageChange();
784 distanceWidgets->languageChange();
785 optMargins->languageChange();
786 advancedWidgets->languageChange();
787 pathTextWidgets->languageChange();
788 fontfeaturesWidget->languageChange();
789 hyphenationWidget->languageChange();
790
791 textAlignment->languageChange();
792 textDirection->languageChange();
793 }
794
handleFirstLinePolicy(int radioFlop)795 void PropertiesPalette_Text::handleFirstLinePolicy(int radioFlop)
796 {
797 if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveDoc || !m_haveItem)
798 return;
799 if( radioFlop == PropertyWidget_Flop::RealHeightID)
800 m_item->setFirstLineOffset(FLOPRealGlyphHeight);
801 else if( radioFlop == PropertyWidget_Flop::FontAscentID)
802 m_item->setFirstLineOffset(FLOPFontAscent);
803 else if( radioFlop == PropertyWidget_Flop::LineSpacingID)
804 m_item->setFirstLineOffset(FLOPLineSpacing);
805 else if( radioFlop == PropertyWidget_Flop::BaselineGridID)
806 m_item->setFirstLineOffset(FLOPBaselineGrid);
807 m_item->update();
808 if (m_doc->appMode == modeEditTable)
809 m_item->parentTable()->update();
810 else
811 m_item->update();
812 m_doc->regionsChanged()->update(QRect());
813 }
814