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 <QLocale>
9 #include "appmodes.h"
10 #include "iconmanager.h"
11 #include "localemgr.h"
12 #include "pageitem_table.h"
13 #include "propertywidget_textcolor.h"
14 #include "scribus.h"
15 #include "scribusapp.h"
16 #include "selection.h"
17
PropertyWidget_TextColor(QWidget * parent)18 PropertyWidget_TextColor::PropertyWidget_TextColor(QWidget* parent) : QFrame(parent)
19 {
20 setupUi(this);
21
22 layout()->setAlignment(Qt::AlignLeft);
23
24 fillLayout->setAlignment(Qt::AlignLeft);
25 fillColor->setPixmapType(ColorCombo::fancyPixmaps);
26 fillIcon->setScaledContents( false );
27
28 strokeLayout->setAlignment(Qt::AlignLeft);
29 strokeColor->setPixmapType(ColorCombo::fancyPixmaps);
30 strokeIcon->setScaledContents( false );
31
32 backLayout->setAlignment(Qt::AlignLeft);
33 backColor->setPixmapType(ColorCombo::fancyPixmaps);
34 backIcon->setScaledContents( false );
35
36 effectsLayout->setAlignment(Qt::AlignLeft);
37
38 iconSetChange();
39 languageChange();
40
41 strokeIcon->setEnabled(false);
42 strokeColor->setEnabled(false);
43 strokeShade->setEnabled(false);
44
45 connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
46 connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
47
48 }
49
setMainWindow(ScribusMainWindow * mw)50 void PropertyWidget_TextColor::setMainWindow(ScribusMainWindow *mw)
51 {
52 m_ScMW = mw;
53
54 connect(m_ScMW, SIGNAL(UpdateRequest(int)), this, SLOT(handleUpdateRequest(int)));
55 }
56
setDoc(ScribusDoc * d)57 void PropertyWidget_TextColor::setDoc(ScribusDoc *d)
58 {
59 if((d == (ScribusDoc*) m_doc) || (m_ScMW && m_ScMW->scriptIsRunning()))
60 return;
61
62 if (m_doc)
63 {
64 disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
65 disconnect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
66 }
67
68 m_doc = d;
69 m_item = nullptr;
70
71 if (m_doc.isNull())
72 {
73 disconnectSignals();
74 return;
75 }
76
77 updateColorList();
78
79 connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
80 connect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
81 }
82
setCurrentItem(PageItem * item)83 void PropertyWidget_TextColor::setCurrentItem(PageItem *item)
84 {
85 if (!m_ScMW || m_ScMW->scriptIsRunning())
86 return;
87 //CB We shouldn't really need to process this if our item is the same one
88 //maybe we do if the item has been changed by scripter.. but that should probably
89 //set some status if so.
90 //FIXME: This won't work until when a canvas deselect happens, m_item must be nullptr.
91 //if (m_item == i)
92 // return;
93
94 disconnectSignals();
95
96 m_item = item;
97 if (item && m_doc.isNull())
98 setDoc(item->doc());
99
100 configureWidgets();
101
102 if (m_item == nullptr)
103 return;
104 if (!m_item->isTable() && !m_item->isTextFrame() && !m_item->isPathText())
105 return;
106
107 if (m_item->isTextFrame() || m_item->isPathText() || m_item->isTable())
108 {
109 ParagraphStyle parStyle = m_item->itemText.defaultStyle();
110 if (m_doc->appMode == modeEdit || m_doc->appMode == modeEditTable)
111 m_item->currentTextProps(parStyle);
112 updateStyle(parStyle);
113 }
114 connectSignals();
115 }
116
connectSignals()117 void PropertyWidget_TextColor::connectSignals()
118 {
119 connect(fillColor , SIGNAL(activated(int)), this, SLOT(handleTextFill()) , Qt::UniqueConnection);
120 connect(strokeColor , SIGNAL(activated(int)), this, SLOT(handleTextStroke()) , Qt::UniqueConnection);
121 connect(fillShade , SIGNAL(clicked()) , this, SLOT(handleTextShade()) , Qt::UniqueConnection);
122 connect(strokeShade , SIGNAL(clicked()) , this, SLOT(handleTextShade()) , Qt::UniqueConnection);
123 connect(backShade , SIGNAL(clicked()) , this, SLOT(handleTextShade()) , Qt::UniqueConnection);
124 connect(backColor , SIGNAL(activated(int)), this, SLOT(handleTextBackground()) , Qt::UniqueConnection);
125
126 connect(textEffects, SIGNAL(State(int)) , this, SLOT(handleTypeStyle(int)), Qt::UniqueConnection);
127 connect(textEffects->ShadowVal->Xoffset , SIGNAL(valueChanged(double)), this, SLOT(handleShadowOffs()), Qt::UniqueConnection);
128 connect(textEffects->ShadowVal->Yoffset , SIGNAL(valueChanged(double)), this, SLOT(handleShadowOffs()), Qt::UniqueConnection);
129 connect(textEffects->OutlineVal->LWidth , SIGNAL(valueChanged(double)), this, SLOT(handleOutlineWidth()), Qt::UniqueConnection);
130 connect(textEffects->UnderlineVal->LPos , SIGNAL(valueChanged(double)), this, SLOT(handleUnderline()) , Qt::UniqueConnection);
131 connect(textEffects->UnderlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(handleUnderline()) , Qt::UniqueConnection);
132 connect(textEffects->StrikeVal->LPos , SIGNAL(valueChanged(double)), this, SLOT(handleStrikeThru()), Qt::UniqueConnection);
133 connect(textEffects->StrikeVal->LWidth , SIGNAL(valueChanged(double)), this, SLOT(handleStrikeThru()), Qt::UniqueConnection);
134 }
135
disconnectSignals()136 void PropertyWidget_TextColor::disconnectSignals()
137 {
138 disconnect(fillColor , SIGNAL(activated(int)), this, SLOT(handleTextFill()));
139 disconnect(strokeColor , SIGNAL(activated(int)), this, SLOT(handleTextStroke()));
140 disconnect(fillShade , SIGNAL(clicked()) , this, SLOT(handleTextShade()));
141 disconnect(strokeShade , SIGNAL(clicked()) , this, SLOT(handleTextShade()));
142 disconnect(backShade , SIGNAL(clicked()) , this, SLOT(handleTextShade()));
143 disconnect(backColor , SIGNAL(activated(int)), this, SLOT(handleTextBackground()));
144
145 disconnect(textEffects, SIGNAL(State(int)) , this, SLOT(handleTypeStyle(int)));
146 disconnect(textEffects->ShadowVal->Xoffset , SIGNAL(valueChanged(double)), this, SLOT(handleShadowOffs()));
147 disconnect(textEffects->ShadowVal->Yoffset , SIGNAL(valueChanged(double)), this, SLOT(handleShadowOffs()));
148 disconnect(textEffects->OutlineVal->LWidth , SIGNAL(valueChanged(double)), this, SLOT(handleOutlineWidth()));
149 disconnect(textEffects->UnderlineVal->LPos , SIGNAL(valueChanged(double)), this, SLOT(handleUnderline()));
150 disconnect(textEffects->UnderlineVal->LWidth, SIGNAL(valueChanged(double)), this, SLOT(handleUnderline()));
151 disconnect(textEffects->StrikeVal->LPos , SIGNAL(valueChanged(double)), this, SLOT(handleStrikeThru()));
152 disconnect(textEffects->StrikeVal->LWidth , SIGNAL(valueChanged(double)), this, SLOT(handleStrikeThru()));
153 }
154
configureWidgets()155 void PropertyWidget_TextColor::configureWidgets()
156 {
157 bool enabled = false;
158 if (m_item && m_doc)
159 {
160 if (m_item->isPathText() || m_item->isTextFrame() || m_item->isTable())
161 enabled = true;
162 if ((m_item->isGroup()) && (!m_item->isSingleSel))
163 enabled = false;
164 if (m_item->isOSGFrame() || m_item->isSymbol())
165 enabled = false;
166 if (m_doc->m_Selection->count() > 1)
167 enabled = false;
168 }
169 setEnabled(enabled);
170 }
171
handleSelectionChanged()172 void PropertyWidget_TextColor::handleSelectionChanged()
173 {
174 if (!m_doc || !m_ScMW || m_ScMW->scriptIsRunning())
175 return;
176
177 PageItem* currItem = currentItemFromSelection();
178 setCurrentItem(currItem);
179 updateGeometry();
180 }
181
handleUpdateRequest(int updateFlags)182 void PropertyWidget_TextColor::handleUpdateRequest(int updateFlags)
183 {
184 if (updateFlags & reqColorsUpdate)
185 updateColorList();
186 }
187
updateColorList()188 void PropertyWidget_TextColor::updateColorList()
189 {
190 if (!m_doc || !m_ScMW || m_ScMW->scriptIsRunning())
191 return;
192
193 if (m_item)
194 disconnectSignals();
195
196 fillColor->setColors(m_doc->PageColors, true);
197 strokeColor->setColors(m_doc->PageColors, false);
198 backColor->setColors(m_doc->PageColors, true);
199 fillColor->view()->setMinimumWidth(fillColor->view()->maximumViewportSize().width() + 24);
200 strokeColor->view()->setMinimumWidth(strokeColor->view()->maximumViewportSize().width() + 24);
201 backColor->view()->setMinimumWidth(backColor->view()->maximumViewportSize().width() + 24);
202
203 if (m_item)
204 setCurrentItem(m_item);
205 }
206
updateCharStyle(const CharStyle & charStyle)207 void PropertyWidget_TextColor::updateCharStyle(const CharStyle& charStyle)
208 {
209 if (!m_ScMW || m_ScMW->scriptIsRunning())
210 return;
211
212 showOutlineW (charStyle.outlineWidth());
213 showShadowOffset(charStyle.shadowXOffset(), charStyle.shadowYOffset());
214 showTextColors(charStyle.strokeColor(), charStyle.fillColor(), charStyle.backColor(), charStyle.strokeShade(), charStyle.fillShade(), charStyle.backShade());
215 showTextEffects(charStyle.effects());
216 showStrikeThru(charStyle.strikethruOffset() , charStyle.strikethruWidth());
217 showUnderline (charStyle.underlineOffset(), charStyle.underlineWidth());
218 }
219
updateStyle(const ParagraphStyle & newCurrent)220 void PropertyWidget_TextColor::updateStyle(const ParagraphStyle& newCurrent)
221 {
222 if (!m_ScMW || m_ScMW->scriptIsRunning())
223 return;
224
225 const CharStyle& charStyle = newCurrent.charStyle();
226
227 showOutlineW (charStyle.outlineWidth());
228 showShadowOffset(charStyle.shadowXOffset(), charStyle.shadowYOffset());
229 showTextColors(charStyle.strokeColor(), charStyle.fillColor(), charStyle.backColor(), charStyle.strokeShade(), charStyle.fillShade(), charStyle.backShade());
230 showTextEffects(charStyle.effects());
231 showStrikeThru(charStyle.strikethruOffset() , charStyle.strikethruWidth());
232 showUnderline (charStyle.underlineOffset(), charStyle.underlineWidth());
233 }
234
showOutlineW(double x)235 void PropertyWidget_TextColor::showOutlineW(double x)
236 {
237 if (!m_ScMW || m_ScMW->scriptIsRunning())
238 return;
239 textEffects->OutlineVal->LWidth->showValue(x / 10.0);
240 }
241
showShadowOffset(double x,double y)242 void PropertyWidget_TextColor::showShadowOffset(double x, double y)
243 {
244 if (!m_ScMW || m_ScMW->scriptIsRunning())
245 return;
246 textEffects->ShadowVal->Xoffset->showValue(x / 10.0);
247 textEffects->ShadowVal->Yoffset->showValue(y / 10.0);
248 }
249
showStrikeThru(double p,double w)250 void PropertyWidget_TextColor::showStrikeThru(double p, double w)
251 {
252 if (!m_ScMW || m_ScMW->scriptIsRunning())
253 return;
254 textEffects->StrikeVal->LPos->showValue(p / 10.0);
255 textEffects->StrikeVal->LWidth->showValue(w / 10.0);
256 }
257
showTextColors(const QString & strokeCol,const QString & fillCol,const QString & backCol,double strokeShd,double fillShd,double backShd)258 void PropertyWidget_TextColor::showTextColors(const QString& strokeCol, const QString& fillCol, const QString& backCol, double strokeShd, double fillShd, double backShd)
259 {
260 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
261 return;
262
263 QSignalBlocker fillShadeBlocker(fillShade);
264 QSignalBlocker strokeShadeBlocker(strokeShade);
265 QSignalBlocker backShadeBlocker(backShade);
266 QSignalBlocker fillColorBlocker(fillColor);
267 QSignalBlocker strokeColorBlocker(strokeColor);
268 QSignalBlocker backColorBlocker(backColor);
269
270 fillShade->setValue(qRound(fillShd));
271 strokeShade->setValue(qRound(strokeShd));
272 backShade->setValue(qRound(backShd));
273
274 if (!fillCol.isEmpty())
275 fillColor->setCurrentColor(fillCol);
276 if (!strokeCol.isEmpty())
277 strokeColor->setCurrentColor(strokeCol);
278 if (!backCol.isEmpty())
279 backColor->setCurrentColor(backCol);
280 }
281
showTextEffects(int s)282 void PropertyWidget_TextColor::showTextEffects(int s)
283 {
284 if (!m_ScMW || m_ScMW->scriptIsRunning())
285 return;
286 strokeIcon->setEnabled(false);
287 strokeColor->setEnabled(false);
288 strokeShade->setEnabled(false);
289 textEffects->setStyle(s);
290 if ((s & 4) || (s & 256))
291 {
292 strokeIcon->setEnabled(true);
293 strokeColor->setEnabled(true);
294 strokeShade->setEnabled(true);
295 }
296 }
297
handleOutlineWidth()298 void PropertyWidget_TextColor::handleOutlineWidth()
299 {
300 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
301 return;
302 int x = qRound(textEffects->OutlineVal->LWidth->value() * 10.0);
303 PageItem *i2 = m_item;
304 if (m_doc->appMode == modeEditTable)
305 i2 = m_item->asTable()->activeCell().textFrame();
306 if (i2 != nullptr)
307 {
308 Selection tempSelection(this, false);
309 tempSelection.addItem(i2, true);
310 m_doc->itemSelection_SetOutlineWidth(x, &tempSelection);
311 }
312 }
313
handleShadowOffs()314 void PropertyWidget_TextColor::handleShadowOffs()
315 {
316 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
317 return;
318 int x = qRound(textEffects->ShadowVal->Xoffset->value() * 10.0);
319 int y = qRound(textEffects->ShadowVal->Yoffset->value() * 10.0);
320 PageItem *i2 = m_item;
321 if (m_doc->appMode == modeEditTable)
322 i2 = m_item->asTable()->activeCell().textFrame();
323 if (i2 != nullptr)
324 {
325 Selection tempSelection(this, false);
326 tempSelection.addItem(i2, true);
327 m_doc->itemSelection_SetShadowOffsets(x, y, &tempSelection);
328 }
329 }
330
handleStrikeThru()331 void PropertyWidget_TextColor::handleStrikeThru()
332 {
333 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
334 return;
335 int x = qRound(textEffects->StrikeVal->LPos->value() * 10.0);
336 int y = qRound(textEffects->StrikeVal->LWidth->value() * 10.0);
337 PageItem *i2 = m_item;
338 if (m_doc->appMode == modeEditTable)
339 i2 = m_item->asTable()->activeCell().textFrame();
340 if (i2 != nullptr)
341 {
342 Selection tempSelection(this, false);
343 tempSelection.addItem(i2, true);
344 m_doc->itemSelection_SetStrikethru(x, y, &tempSelection);
345 }
346 }
347
handleTextFill()348 void PropertyWidget_TextColor::handleTextFill()
349 {
350 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
351 return;
352 PageItem *i2 = m_item;
353 if (m_doc->appMode == modeEditTable)
354 i2 = m_item->asTable()->activeCell().textFrame();
355 if (i2 != nullptr)
356 {
357 Selection tempSelection(this, false);
358 tempSelection.addItem(i2, true);
359 m_doc->itemSelection_SetFillColor(fillColor->currentColor(), &tempSelection);
360 }
361 }
362
handleTextStroke()363 void PropertyWidget_TextColor::handleTextStroke()
364 {
365 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
366 return;
367 PageItem *i2 = m_item;
368 if (m_doc->appMode == modeEditTable)
369 i2 = m_item->asTable()->activeCell().textFrame();
370 if (i2 != nullptr)
371 {
372 Selection tempSelection(this, false);
373 tempSelection.addItem(i2, true);
374 m_doc->itemSelection_SetStrokeColor(strokeColor->currentColor(), &tempSelection);
375 }
376 }
377
handleTextBackground()378 void PropertyWidget_TextColor::handleTextBackground()
379 {
380 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
381 return;
382 PageItem *i2 = m_item;
383 if (m_doc->appMode == modeEditTable)
384 i2 = m_item->asTable()->activeCell().textFrame();
385 if (i2 != nullptr)
386 {
387 Selection tempSelection(this, false);
388 tempSelection.addItem(i2, true);
389 m_doc->itemSelection_SetBackgroundColor(backColor->currentColor(), &tempSelection);
390 }
391 }
392
handleTextShade()393 void PropertyWidget_TextColor::handleTextShade()
394 {
395 if (!m_doc || !m_item || !m_ScMW || m_ScMW->scriptIsRunning())
396 return;
397 if (strokeShade == sender())
398 {
399 int b = strokeShade->getValue();
400 PageItem *i2 = m_item;
401 if (m_doc->appMode == modeEditTable)
402 i2 = m_item->asTable()->activeCell().textFrame();
403 if (i2 != nullptr)
404 {
405 Selection tempSelection(this, false);
406 tempSelection.addItem(i2, true);
407 m_doc->itemSelection_SetStrokeShade(b, &tempSelection);
408 }
409 }
410 else if (fillShade == sender())
411 {
412 int b = fillShade->getValue();
413 PageItem *i2 = m_item;
414 if (m_doc->appMode == modeEditTable)
415 i2 = m_item->asTable()->activeCell().textFrame();
416 if (i2 != nullptr)
417 {
418 Selection tempSelection(this, false);
419 tempSelection.addItem(i2, true);
420 m_doc->itemSelection_SetFillShade(b, &tempSelection);
421 }
422 }
423 else if (backShade == sender())
424 {
425 int b = backShade->getValue();
426 PageItem *i2 = m_item;
427 if (m_doc->appMode == modeEditTable)
428 i2 = m_item->asTable()->activeCell().textFrame();
429 if (i2 != nullptr)
430 {
431 Selection tempSelection(this, false);
432 tempSelection.addItem(i2, true);
433 m_doc->itemSelection_SetBackgroundShade(b, &tempSelection);
434 }
435 }
436 }
437
handleTypeStyle(int s)438 void PropertyWidget_TextColor::handleTypeStyle(int s)
439 {
440 if (!m_ScMW || m_ScMW->scriptIsRunning())
441 return;
442 PageItem *i2 = m_item;
443 if (m_doc->appMode == modeEditTable)
444 i2 = m_item->asTable()->activeCell().textFrame();
445 if (i2 != nullptr)
446 {
447 Selection tempSelection(this, false);
448 tempSelection.addItem(i2, true);
449 m_doc->itemSelection_SetEffects(s, &tempSelection);
450 m_ScMW->setStyleEffects(s);
451 }
452 }
453
showUnderline(double p,double w)454 void PropertyWidget_TextColor::showUnderline(double p, double w)
455 {
456 if (!m_ScMW || m_ScMW->scriptIsRunning())
457 return;
458 textEffects->UnderlineVal->LPos->showValue(p / 10.0);
459 textEffects->UnderlineVal->LWidth->showValue(w / 10.0);
460 }
461
handleUnderline()462 void PropertyWidget_TextColor::handleUnderline()
463 {
464 if ((m_doc) && (m_item))
465 {
466 int x = qRound(textEffects->UnderlineVal->LPos->value() * 10.0);
467 int y = qRound(textEffects->UnderlineVal->LWidth->value() * 10.0);
468 PageItem *i2 = m_item;
469 if (m_doc->appMode == modeEditTable)
470 i2 = m_item->asTable()->activeCell().textFrame();
471 if (i2 != nullptr)
472 {
473 Selection tempSelection(this, false);
474 tempSelection.addItem(i2, true);
475 m_doc->itemSelection_SetUnderline(x, y, &tempSelection);
476 }
477 }
478 }
479
changeEvent(QEvent * e)480 void PropertyWidget_TextColor::changeEvent(QEvent *e)
481 {
482 if (e->type() == QEvent::LanguageChange)
483 {
484 languageChange();
485 return;
486 }
487 QWidget::changeEvent(e);
488 }
489
iconSetChange()490 void PropertyWidget_TextColor::iconSetChange()
491 {
492 IconManager& iconManager = IconManager::instance();
493
494 fillIcon->setPixmap(iconManager.loadPixmap("16/color-fill.png"));
495 fillShadeLabel->setPixmap(iconManager.loadPixmap("shade.png"));
496
497 strokeIcon->setPixmap(iconManager.loadPixmap("16/color-stroke.png"));
498 strokeShadeLabel->setPixmap(iconManager.loadPixmap("shade.png"));
499
500 backIcon->setPixmap(iconManager.loadPixmap("16/color-fill.png"));
501 backShadeLabel->setPixmap(iconManager.loadPixmap("shade.png"));
502 }
503
languageChange()504 void PropertyWidget_TextColor::languageChange()
505 {
506 retranslateUi(this);
507 textEffects->languageChange();
508 }
509
localeChange()510 void PropertyWidget_TextColor::localeChange()
511 {
512 const QLocale& l(LocaleManager::instance().userPreferredLocale());
513 textEffects->ShadowVal->Xoffset->setLocale(l);
514 textEffects->ShadowVal->Yoffset->setLocale(l);
515 textEffects->OutlineVal->LWidth->setLocale(l);
516 textEffects->UnderlineVal->LPos->setLocale(l);
517 textEffects->UnderlineVal->LWidth->setLocale(l);
518 textEffects->StrikeVal->LPos->setLocale(l);
519 textEffects->StrikeVal->LWidth->setLocale(l);
520 }
521