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 "propertiespalette_shadow.h"
9 
10 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
11 #define _USE_MATH_DEFINES
12 #endif
13 #include <cmath>
14 
15 #include "commonstrings.h"
16 #include "localemgr.h"
17 #include "pageitem.h"
18 #include "propertiespalette_utils.h"
19 #include "sccolorengine.h"
20 #include "scraction.h"
21 #include "scribusapp.h"
22 #include "scribuscore.h"
23 #include "selection.h"
24 #include "undomanager.h"
25 #include "units.h"
26 #include "util.h"
27 #include "util_math.h"
28 
PropertiesPalette_Shadow(QWidget * parent)29 PropertiesPalette_Shadow::PropertiesPalette_Shadow( QWidget* parent) : PropTreeWidget(parent)
30 {
31 	hasSoftShadow = new PropTreeItem(this, PropTreeItem::CheckBox, tr( "Has Drop Shadow"));
32 	hasSoftShadow->setBoolValue(false);
33 
34 	softShadowXOffset = new PropTreeItem(this, PropTreeItem::DoubleSpinBox, tr( "X-Offset:"));
35 	softShadowXOffset->setUnitValue(0);
36 	softShadowXOffset->setDecimalsValue(2);
37 	softShadowXOffset->setMinMaxValues(-200.0, 200.0);
38 	softShadowXOffset->setDoubleValue(5.0);
39 
40 	softShadowYOffset = new PropTreeItem(this, PropTreeItem::DoubleSpinBox, tr( "Y-Offset:"));
41 	softShadowYOffset->setUnitValue(0);
42 	softShadowYOffset->setDecimalsValue(2);
43 	softShadowYOffset->setMinMaxValues(-200.0, 200.0);
44 	softShadowYOffset->setDoubleValue(5.0);
45 
46 	softShadowBlurRadius = new PropTreeItem(this, PropTreeItem::DoubleSpinBox, tr( "Blur:"));
47 	softShadowBlurRadius->setUnitValue(0);
48 	softShadowBlurRadius->setDecimalsValue(2);
49 	softShadowBlurRadius->setMinMaxValues(-200.0, 200.0);
50 	softShadowBlurRadius->setDoubleValue(2.0);
51 
52 	softShadowColor = new PropTreeItem(this, PropTreeItem::ColorComboBox, tr( "Color:"));
53 	softShadowColor->setStringValue( tr( "Black"));
54 
55 	softShadowShade = new PropTreeItem(this, PropTreeItem::IntSpinBox, tr( "Shade:"));
56 	softShadowShade->setUnitValue(7);
57 	softShadowShade->setDecimalsValue(0);
58 	softShadowShade->setMinMaxValues(0, 100);
59 	softShadowShade->setIntValue(100);
60 
61 	softShadowOpacity = new PropTreeItem(this, PropTreeItem::DoubleSpinBox, tr( "Opacity:"));
62 	softShadowOpacity->setUnitValue(7);
63 	softShadowOpacity->setDecimalsValue(1);
64 	softShadowOpacity->setMinMaxValues(0.0, 100.0);
65 	softShadowOpacity->setDoubleValue(100.0);
66 
67 	softShadowBlendMode = new PropTreeItem(this, PropTreeItem::ComboBox, tr( "Blendmode:"));
68 	QStringList modes;
69 	softShadowBlendMode->setComboStrings(modes);
70 	softShadowBlendMode->setStringValue( tr( "Normal"));
71 
72 	softShadowErase = new PropTreeItem(this, PropTreeItem::CheckBox, tr( "Content covers\nDrop Shadow"));
73 	softShadowErase->setBoolValue(false);
74 
75 	softShadowObjTrans = new PropTreeItem(this, PropTreeItem::CheckBox, tr( "Inherit Object\nTransparency"));
76 	softShadowObjTrans->setBoolValue(false);
77 
78 	languageChange();
79 	setSizePolicy( QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum));
80 	connect(this->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(handleNewValues()));
81 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
82 }
83 
setMainWindow(ScribusMainWindow * mw)84 void PropertiesPalette_Shadow::setMainWindow(ScribusMainWindow* mw)
85 {
86 	m_ScMW = mw;
87 	connect(m_ScMW, SIGNAL(UpdateRequest(int)), this, SLOT(handleUpdateRequest(int)));
88 }
89 
setDoc(ScribusDoc * d)90 void PropertiesPalette_Shadow::setDoc(ScribusDoc *d)
91 {
92 	if((d == (ScribusDoc*) m_doc) || (m_ScMW && m_ScMW->scriptIsRunning()))
93 		return;
94 
95 	if (m_doc)
96 	{
97 		disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
98 		disconnect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
99 	}
100 
101 	m_doc  = d;
102 	m_item = nullptr;
103 	m_unitRatio   = m_doc->unitRatio();
104 	m_unitIndex   = m_doc->unitIndex();
105 	int precision = unitGetPrecisionFromIndex(m_unitIndex);
106 	double maxXYWHVal =  200 * m_unitRatio;
107 	double minXYVal   = -200 * m_unitRatio;
108 
109 	m_haveDoc = true;
110 	m_haveItem = false;
111 	softShadowXOffset->setUnitValue(m_unitIndex);
112 	softShadowXOffset->setDecimalsValue(precision);
113 	softShadowXOffset->setMinMaxValues(minXYVal, maxXYWHVal);
114 	softShadowXOffset->setDoubleValue(minXYVal);
115 
116 	softShadowYOffset->setUnitValue(m_unitIndex);
117 	softShadowYOffset->setDecimalsValue(precision);
118 	softShadowYOffset->setMinMaxValues(minXYVal, maxXYWHVal);
119 	softShadowYOffset->setDoubleValue(minXYVal);
120 
121 	softShadowBlurRadius->setUnitValue(m_unitIndex);
122 	softShadowBlurRadius->setDecimalsValue(precision);
123 	softShadowBlurRadius->setMinMaxValues(0.0, 200.0);
124 	softShadowBlurRadius->setDoubleValue(5);
125 
126 	softShadowShade->setDecimalsValue(0);
127 	softShadowShade->setMinMaxValues(0, 100);
128 	softShadowShade->setIntValue(100);
129 
130 	softShadowOpacity->setDecimalsValue(0);
131 	softShadowOpacity->setMinMaxValues(0, 100);
132 	softShadowOpacity->setIntValue(100);
133 	updateColorList();
134 
135 	connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
136 	connect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
137 }
138 
unsetDoc()139 void PropertiesPalette_Shadow::unsetDoc()
140 {
141 	if (m_doc)
142 	{
143 		disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
144 		disconnect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
145 	}
146 	m_haveDoc  = false;
147 	m_haveItem = false;
148 	m_doc   = nullptr;
149 	m_item  = nullptr;
150 	setEnabled(false);
151 }
152 
unsetItem()153 void PropertiesPalette_Shadow::unsetItem()
154 {
155 	m_haveItem = false;
156 	m_item     = nullptr;
157 	handleSelectionChanged();
158 }
159 
handleUpdateRequest(int updateFlags)160 void PropertiesPalette_Shadow::handleUpdateRequest(int updateFlags)
161 {
162 	if (updateFlags & reqColorsUpdate)
163 		updateColorList();
164 }
165 
currentItemFromSelection()166 PageItem* PropertiesPalette_Shadow::currentItemFromSelection()
167 {
168 	PageItem *currentItem = nullptr;
169 	if (m_doc)
170 	{
171 		if (m_doc->m_Selection->count() > 1)
172 			currentItem = m_doc->m_Selection->itemAt(0);
173 		else if (m_doc->m_Selection->count() == 1)
174 			currentItem = m_doc->m_Selection->itemAt(0);
175 	}
176 	return currentItem;
177 }
178 
setCurrentItem(PageItem * item)179 void PropertiesPalette_Shadow::setCurrentItem(PageItem *item)
180 {
181 	if (!m_ScMW || m_ScMW->scriptIsRunning())
182 		return;
183 	if (!m_doc)
184 		setDoc(item->doc());
185 	m_haveItem = false;
186 	m_item = item;
187 	hasSoftShadow->setBoolValue(item->hasSoftShadow());
188 	softShadowXOffset->setDoubleValue(item->softShadowXOffset() * m_unitRatio);
189 	softShadowYOffset->setDoubleValue(item->softShadowYOffset() * m_unitRatio);
190 	softShadowBlurRadius->setDoubleValue(item->softShadowBlurRadius() * m_unitRatio);
191 	softShadowColor->setStringValue(item->softShadowColor());
192 	softShadowShade->setIntValue(item->softShadowShade());
193 	softShadowOpacity->setDoubleValue(qRound(100 - (item->softShadowOpacity() * 100)));
194 	softShadowBlendMode->setIntValue(item->softShadowBlendMode());
195 	softShadowErase->setBoolValue(item->softShadowErasedByObject());
196 	softShadowObjTrans->setBoolValue(item->softShadowHasObjectTransparency());
197 	m_haveItem = true;
198 	updateSpinBoxConstants();
199 }
200 
handleSelectionChanged()201 void PropertiesPalette_Shadow::handleSelectionChanged()
202 {
203 	if (!m_haveDoc || !m_ScMW || m_ScMW->scriptIsRunning())
204 		return;
205 
206 	PageItem* currItem = currentItemFromSelection();
207 	if (currItem)
208 		setCurrentItem(currItem);
209 	updateGeometry();
210 }
211 
unitChange()212 void PropertiesPalette_Shadow::unitChange()
213 {
214 	if (!m_haveDoc)
215 		return;
216 	m_unitRatio = m_doc->unitRatio();
217 	m_unitIndex = m_doc->unitIndex();
218 
219 	bool sigBlocked1 = softShadowXOffset->blockSignals(true);
220 	bool sigBlocked2 = softShadowYOffset->blockSignals(true);
221 	bool sigBlocked3 = softShadowBlurRadius->blockSignals(true);
222 	bool sigBlocked4 = this->model()->blockSignals(true);
223 
224 	softShadowXOffset->setUnitValue(m_unitIndex);
225 	softShadowYOffset->setUnitValue(m_unitIndex);
226 	softShadowBlurRadius->setUnitValue(m_unitIndex);
227 
228 	softShadowXOffset->blockSignals(sigBlocked1);
229 	softShadowYOffset->blockSignals(sigBlocked2);
230 	softShadowBlurRadius->blockSignals(sigBlocked3);
231 	this->model()->blockSignals(sigBlocked4);
232 }
233 
localeChange()234 void PropertiesPalette_Shadow::localeChange()
235 {
236 	softShadowXOffset->localeChange();
237 	softShadowYOffset->localeChange();
238 	softShadowBlurRadius->localeChange();
239 }
240 
updateColorList()241 void PropertiesPalette_Shadow::updateColorList()
242 {
243 	if (!m_haveDoc || !m_ScMW || m_ScMW->scriptIsRunning())
244 		return;
245 	softShadowColor->setColorList(m_doc->PageColors);
246 }
247 
handleNewValues()248 void PropertiesPalette_Shadow::handleNewValues()
249 {
250 	if (!m_haveItem)
251 		return;
252 	double x = softShadowXOffset->valueAsDouble() / m_unitRatio;
253 	double y = softShadowYOffset->valueAsDouble() / m_unitRatio;
254 	double r = softShadowBlurRadius->valueAsDouble() / m_unitRatio;
255 	QString color = softShadowColor->valueAsString();
256 	if (color == CommonStrings::tr_NoneColor)
257 		color = CommonStrings::None;
258 	int b = softShadowBlendMode->valueAsInt();
259 	double o = (100 - softShadowOpacity->valueAsDouble()) / 100.0;
260 	int s = softShadowShade->valueAsInt();
261 	if (m_haveDoc)
262 	{
263 		m_doc->itemSelection_SetSoftShadow(hasSoftShadow->valueAsBool(), color, x, y, r, s, o, b, softShadowErase->valueAsBool(), softShadowObjTrans->valueAsBool());
264 	}
265 }
266 
changeEvent(QEvent * e)267 void PropertiesPalette_Shadow::changeEvent(QEvent *e)
268 {
269 	if (e->type() == QEvent::LanguageChange)
270 	{
271 		languageChange();
272 	}
273 	else
274 		QWidget::changeEvent(e);
275 }
276 
languageChange()277 void PropertiesPalette_Shadow::languageChange()
278 {
279 	disconnect(this->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(handleNewValues()));
280 
281 	hasSoftShadow->setText(0, tr( "Has Drop Shadow"));
282 	softShadowXOffset->setText(0, tr( "X-Offset:"));
283 	softShadowYOffset->setText(0, tr( "Y-Offset:"));
284 	softShadowBlurRadius->setText(0, tr( "Blur:"));
285 	softShadowColor->setText(0, tr( "Color:"));
286 	softShadowShade->setText(0, tr( "Shade:"));
287 	softShadowOpacity->setText(0, tr( "Opacity:"));
288 	softShadowErase->setText(0, tr( "Content covers\nDrop Shadow"));
289 	softShadowObjTrans->setText(0, tr( "Inherit Object\nTransparency"));
290 	QStringList modes;
291 	modes.append( tr("Normal"));
292 	modes.append( tr("Darken"));
293 	modes.append( tr("Lighten"));
294 	modes.append( tr("Multiply"));
295 	modes.append( tr("Screen"));
296 	modes.append( tr("Overlay"));
297 	modes.append( tr("Hard Light"));
298 	modes.append( tr("Soft Light"));
299 	modes.append( tr("Difference"));
300 	modes.append( tr("Exclusion"));
301 	modes.append( tr("Color Dodge"));
302 	modes.append( tr("Color Burn"));
303 	modes.append( tr("Hue"));
304 	modes.append( tr("Saturation"));
305 	modes.append( tr("Color"));
306 	modes.append( tr("Luminosity"));
307 	softShadowBlendMode->setComboStrings(modes);
308 	softShadowBlendMode->setStringValue( tr("Normal"));
309 	softShadowBlendMode->setText(0, tr( "Blendmode:"));
310 
311 	connect(this->model(), SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(handleNewValues()));
312 }
313 
updateSpinBoxConstants()314 void PropertiesPalette_Shadow::updateSpinBoxConstants()
315 {
316 	if (!m_haveDoc)
317 		return;
318 	if(m_doc->m_Selection->count()==0)
319 		return;
320 }
321