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_image.h"
10 
11 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
12 #define _USE_MATH_DEFINES
13 #endif
14 #include <cmath>
15 #include <QLocale>
16 #include <QSignalBlocker>
17 
18 #include "commonstrings.h"
19 #include "localemgr.h"
20 #include "pageitem.h"
21 #include "propertiespalette_utils.h"
22 #include "sccolorengine.h"
23 #include "scribuscore.h"
24 #include "scraction.h"
25 #include "scribusapp.h"
26 #include "scribusview.h"
27 #include "selection.h"
28 #include "units.h"
29 #include "undomanager.h"
30 #include "util.h"
31 #include "util_math.h"
32 
PropertiesPalette_Image(QWidget * parent)33 PropertiesPalette_Image::PropertiesPalette_Image( QWidget* parent) : QWidget(parent)
34 {
35 	userActionSniffer = new UserActionSniffer(this);
36 	connect(userActionSniffer, SIGNAL(actionStart()), this, SLOT(spinboxStartUserAction()));
37 	connect(userActionSniffer, SIGNAL(actionEnd()), this, SLOT(spinboxFinishUserAction()));
38 
39 	setupUi(this);
40 	setSizePolicy( QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum));
41 
42 	imagePageNumber->setMinimum(0);
43 	imagePageNumber->setSpecialValueText( tr( "Auto" ));
44 	imagePageNumber->setDecimals(0);
45 	imagePageNumber->setSuffix("");
46 	imagePageNumberLabel->setBuddy(imagePageNumber);
47 	installSniffer(imagePageNumber);
48 
49 //	freeScale = new QRadioButton( "&Free Scaling", this );
50 //	freeScale->setChecked( true );
51 //	pageLayout_4->addWidget( freeScale );
52 
53 	xposImgLabel->setBuddy(imageXOffsetSpinBox);
54 	yposImgLabel->setBuddy(imageYOffsetSpinBox);
55 
56 	imageRotation->setWrapping( true );
57 	imageRotation->setNewUnit(6);
58 	installSniffer(imageRotation);
59 	imageRotationLabel->setBuddy(imageRotation);
60 
61 	freeScale->setChecked( true );
62 
63 	installSniffer(imageXScaleSpinBox);
64 	xscaleLabel->setBuddy(imageXScaleSpinBox);
65 	installSniffer(imageYScaleSpinBox);
66 	yscaleLabel->setBuddy(imageYScaleSpinBox);
67 
68 	keepImageWHRatioButton->setCheckable( true );
69 	keepImageWHRatioButton->setAutoRaise( true );
70 
71 	imgDpiX->setSuffix("");
72 	installSniffer(imgDpiX);
73 	imgDPIXLabel->setBuddy(imgDpiX);
74 
75 	imgDpiY->setSuffix("");
76 	installSniffer(imgDpiY);
77 	imgDPIYLabel->setBuddy(imgDpiY);
78 
79 	keepImageDPIRatioButton->setCheckable( true );
80 	keepImageDPIRatioButton->setAutoRaise( true );
81 
82 	frameScale->setText( tr("&To Frame Size"));
83 
84 	cbProportional->setEnabled( false );
85 	cbProportional->setText( "P&roportional" );
86 	cbProportional->setChecked( true );
87 
88 	languageChange();
89 
90 	connect(imagePageNumber    , SIGNAL(valueChanged(double)), this, SLOT(handleImagePageNumber()));
91 	connect(imageXScaleSpinBox , SIGNAL(valueChanged(double)), this, SLOT(handleXScale()));
92 	connect(imageYScaleSpinBox , SIGNAL(valueChanged(double)), this, SLOT(handleYScale()));
93 	connect(imageXOffsetSpinBox, SIGNAL(valueChanged(double)), this, SLOT(handleLocalXY()));
94 	connect(imageYOffsetSpinBox, SIGNAL(valueChanged(double)), this, SLOT(handleLocalXY()));
95 	connect(imageRotation      , SIGNAL(valueChanged(double)), this, SLOT(handleLocalRotation()));
96 	connect(imgDpiX            , SIGNAL(valueChanged(double)), this, SLOT(handleDpiX()));
97 	connect(imgDpiY            , SIGNAL(valueChanged(double)), this, SLOT(handleDpiY()));
98 	connect(keepImageWHRatioButton , SIGNAL(clicked())       , this, SLOT(handleImageWHRatio()));
99 	connect(keepImageDPIRatioButton, SIGNAL(clicked())       , this, SLOT(handleImageDPIRatio()));
100 	connect(freeScale          , SIGNAL(clicked())           , this, SLOT(handleScaling()));
101 	connect(frameScale         , SIGNAL(clicked())           , this, SLOT(handleScaling()));
102 	connect(cbProportional     , SIGNAL(stateChanged(int))   , this, SLOT(handleScaling()));
103 	connect(imgEffectsButton   , SIGNAL(clicked())           , this, SLOT(handleImageEffects()));
104 	connect(imgExtProperties   , SIGNAL(clicked())           , this, SLOT(handleExtImgProperties()));
105 	connect(inputProfiles      , SIGNAL(activated(const QString&)), this, SLOT(handleProfile(const QString&)));
106 	connect(renderIntent       , SIGNAL(activated(int))      , this, SLOT(handleIntent()));
107 	connect(compressionMethod  , SIGNAL(activated(int))      , this, SLOT(handleCompressionMethod()));
108 	connect(compressionQuality , SIGNAL(activated(int))      , this, SLOT(handleCompressionQuality()));
109 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
110 
111 }
112 
updateSpinBoxConstants()113 void PropertiesPalette_Image::updateSpinBoxConstants()
114 {
115 	if (!m_haveDoc)
116 		return;
117 	if(m_doc->m_Selection->count()==0)
118 		return;
119 	imageXOffsetSpinBox->setConstants(&m_doc->constants());
120 	imageYOffsetSpinBox->setConstants(&m_doc->constants());
121 }
122 
changeEvent(QEvent * e)123 void PropertiesPalette_Image::changeEvent(QEvent *e)
124 {
125 	if (e->type() == QEvent::LanguageChange)
126 	{
127 		languageChange();
128 		return;
129 	}
130 	QWidget::changeEvent(e);
131 }
132 
setMainWindow(ScribusMainWindow * mw)133 void PropertiesPalette_Image::setMainWindow(ScribusMainWindow* mw)
134 {
135 	m_ScMW = mw;
136 
137 	connect(m_ScMW, SIGNAL(UpdateRequest(int)), this  , SLOT(handleUpdateRequest(int)));
138 }
139 
setDoc(ScribusDoc * d)140 void PropertiesPalette_Image::setDoc(ScribusDoc *d)
141 {
142 	if((d == (ScribusDoc*) m_doc) || (m_ScMW && m_ScMW->scriptIsRunning()))
143 		return;
144 
145 	if (m_doc)
146 	{
147 		disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
148 		disconnect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
149 	}
150 
151 	m_doc  = d;
152 	m_item = nullptr;
153 	m_unitRatio   = m_doc->unitRatio();
154 	m_unitIndex   = m_doc->unitIndex();
155 	int precision = unitGetPrecisionFromIndex(m_unitIndex);
156 	double maxXYWHVal =  16777215 * m_unitRatio;
157 
158 	m_haveDoc  = true;
159 	m_haveItem = false;
160 
161 	imageXOffsetSpinBox->setValues( -16777215, maxXYWHVal, precision, 0);
162 	imageYOffsetSpinBox->setValues( -16777215, maxXYWHVal, precision, 0);
163 
164 	imageRotation->setValues( 0, 359.99, 1, 0);
165 
166 	imageXScaleSpinBox->setValues( 1, 30000, 2, 1);
167 	imageYScaleSpinBox->setValues( 1, 30000, 2, 1);
168 	imgDpiX->setValues( 1, 30000, 2, 1);
169 	imgDpiY->setValues( 1, 30000, 2, 1);
170 	updateSpinBoxConstants();
171 
172 	connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
173 	connect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
174 }
175 
unsetDoc()176 void PropertiesPalette_Image::unsetDoc()
177 {
178 	if (m_doc)
179 	{
180 		disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
181 		disconnect(m_doc             , SIGNAL(docChanged())      , this, SLOT(handleSelectionChanged()));
182 	}
183 
184 	m_haveDoc  = false;
185 	m_haveItem = false;
186 	m_doc   = nullptr;
187 	m_item  = nullptr;
188 
189 	setEnabled(false);
190 }
191 
unsetItem()192 void PropertiesPalette_Image::unsetItem()
193 {
194 	m_haveItem = false;
195 	m_item     = nullptr;
196 	handleSelectionChanged();
197 }
198 
currentItemFromSelection()199 PageItem* PropertiesPalette_Image::currentItemFromSelection()
200 {
201 	PageItem *currentItem = nullptr;
202 
203 	if (m_doc)
204 	{
205 		if (m_doc->m_Selection->count() > 1)
206 		{
207 			currentItem = m_doc->m_Selection->itemAt(0);
208 		}
209 		else if (m_doc->m_Selection->count() == 1)
210 		{
211 			currentItem = m_doc->m_Selection->itemAt(0);
212 		}
213 	}
214 
215 	return currentItem;
216 }
217 
installSniffer(ScrSpinBox * spinBox)218 void PropertiesPalette_Image::installSniffer(ScrSpinBox *spinBox)
219 {
220 	const QList<QObject*>& list = spinBox->children();
221 	if (!list.isEmpty())
222 	{
223 		QListIterator<QObject*> it(list);
224 		QObject *obj;
225 		while (it.hasNext())
226 		{
227 			obj = it.next();
228 			obj->installEventFilter(userActionSniffer);
229 		}
230 	}
231 }
232 
installSniffer(QSpinBox * spinBox)233 void PropertiesPalette_Image::installSniffer(QSpinBox *spinBox)
234 {
235 	const QList<QObject*>& list = spinBox->children();
236 	if (!list.isEmpty())
237 	{
238 		QListIterator<QObject*> it(list);
239 		QObject *obj;
240 		while (it.hasNext())
241 		{
242 			obj = it.next();
243 			obj->installEventFilter(userActionSniffer);
244 		}
245 	}
246 }
247 
updateProfileList()248 void PropertiesPalette_Image::updateProfileList()
249 {
250 	if (!m_ScMW || m_ScMW->scriptIsRunning())
251 		return;
252 	if (m_haveDoc)
253 	{
254 		if (ScCore->haveCMS() && m_doc->cmsSettings().CMSinUse)
255 			colorMgmtGroup->show();
256 		else
257 		{
258 			colorMgmtGroup->hide();
259 			return;
260 		}
261 
262 		inputProfiles->blockSignals(true);
263 		renderIntent->blockSignals(true);
264 
265 		inputProfiles->clear();
266 		if (m_haveItem)
267 		{
268 			if (m_item->pixm.imgInfo.colorspace == ColorSpaceCMYK)
269 			{
270 				ProfilesL::Iterator itPend = ScCore->InputProfilesCMYK.end();
271 				for (auto itP = ScCore->InputProfilesCMYK.begin(); itP != itPend; ++itP)
272 				{
273 					inputProfiles->addItem(itP.key());
274 					if (itP.key() == m_item->ImageProfile)
275 						inputProfiles->setCurrentIndex(inputProfiles->count() - 1);
276 				}
277 				if (!ScCore->InputProfilesCMYK.contains(m_item->ImageProfile))
278 				{
279 					inputProfiles->addItem(m_item->ImageProfile);
280 					inputProfiles->setCurrentIndex(inputProfiles->count() - 1);
281 				}
282 				else
283 				{
284 					if (!m_item->EmbeddedProfile.isEmpty())
285 						inputProfiles->addItem(m_item->EmbeddedProfile);
286 				}
287 			}
288 			else
289 			{
290 				ProfilesL::Iterator itPend = ScCore->InputProfiles.end();
291 				for (auto itP = ScCore->InputProfiles.begin(); itP != itPend; ++itP)
292 				{
293 					inputProfiles->addItem(itP.key());
294 					if (itP.key() == m_item->ImageProfile)
295 						inputProfiles->setCurrentIndex(inputProfiles->count() - 1);
296 				}
297 				if (!ScCore->InputProfiles.contains(m_item->ImageProfile))
298 				{
299 					inputProfiles->addItem(m_item->ImageProfile);
300 					inputProfiles->setCurrentIndex(inputProfiles->count() - 1);
301 				}
302 				else
303 				{
304 					if (!m_item->EmbeddedProfile.isEmpty())
305 						inputProfiles->addItem(m_item->EmbeddedProfile);
306 				}
307 			}
308 			renderIntent->setCurrentIndex(m_item->ImageIntent);
309 		}
310 
311 		inputProfiles->blockSignals(false);
312 		renderIntent->blockSignals(false);
313 	}
314 }
315 
showCMSOptions()316 void PropertiesPalette_Image::showCMSOptions()
317 {
318 	if (!m_ScMW || m_ScMW->scriptIsRunning())
319 		return;
320 	if (m_haveItem)
321 		updateProfileList();
322 	else if (m_doc)
323 		colorMgmtGroup->setVisible(ScCore->haveCMS() && m_doc->cmsSettings().CMSinUse);
324 }
325 
showImageRotation(double rot)326 void PropertiesPalette_Image::showImageRotation(double rot)
327 {
328 	if (!m_ScMW || m_ScMW->scriptIsRunning())
329 		return;
330 	double rrR = rot;
331 	if (rot > 0)
332 		rrR = 360 - rrR;
333 	imageRotation->showValue(fabs(rrR));
334 }
335 
showScaleAndOffset(double scx,double scy,double x,double y)336 void PropertiesPalette_Image::showScaleAndOffset(double scx, double scy, double x, double y)
337 {
338 	if (!m_ScMW || m_ScMW->scriptIsRunning())
339 		return;
340 	bool whRatioBlocked = keepImageWHRatioButton->blockSignals(true);
341 	bool dpiRatioBlocked = keepImageDPIRatioButton->blockSignals(true);
342 	if (fabs(scx - scy) > 0.0002)
343 	{
344 		keepImageWHRatioButton->setChecked(false);
345 		keepImageDPIRatioButton->setChecked(false);
346 	}
347 	if (m_haveItem)
348 	{
349 		imageXOffsetSpinBox->showValue(x * m_unitRatio * m_item->imageXScale());
350 		imageYOffsetSpinBox->showValue(y * m_unitRatio * m_item->imageYScale());
351 		imageXScaleSpinBox->showValue(scx * 100 / 72.0 * m_item->pixm.imgInfo.xres);
352 		imageYScaleSpinBox->showValue(scy * 100 / 72.0 * m_item->pixm.imgInfo.yres);
353 		imgDpiX->showValue(qRound(720.0 / m_item->imageXScale()) / 10.0);
354 		imgDpiY->showValue(qRound(720.0 / m_item->imageYScale()) / 10.0);
355 	}
356 	else
357 	{
358 		imageXOffsetSpinBox->showValue(x * m_unitRatio);
359 		imageYOffsetSpinBox->showValue(y * m_unitRatio);
360 		imageXScaleSpinBox->showValue(scx * 100);
361 		imageYScaleSpinBox->showValue(scy * 100);
362 		imgDpiX->showValue(72);
363 		imgDpiY->showValue(72);
364 	}
365 	keepImageWHRatioButton->blockSignals(whRatioBlocked);
366 	keepImageDPIRatioButton->blockSignals(dpiRatioBlocked);
367 }
368 
handleSelectionChanged()369 void PropertiesPalette_Image::handleSelectionChanged()
370 {
371 	if (!m_haveDoc || !m_ScMW || m_ScMW->scriptIsRunning())
372 		return;
373 
374 	PageItem* currItem = currentItemFromSelection();
375 	if (m_doc->m_Selection->count() > 1)
376 	{
377 		setEnabled(false);
378 	}
379 	else
380 	{
381 		int itemType = currItem ? (int) currItem->itemType() : -1;
382 		m_haveItem = (itemType != -1);
383 
384 		switch (itemType)
385 		{
386 		case -1:
387 			setEnabled(false);
388 			break;
389 		case PageItem::ImageFrame:
390 		case PageItem::LatexFrame:
391 		case PageItem::OSGFrame:
392 			setEnabled(currItem->asOSGFrame() == nullptr);
393 			break;
394 		case PageItem::TextFrame:
395 			setEnabled(false);
396 			break;
397 		case PageItem::Line:
398 			setEnabled(false);
399 			break;
400 		case PageItem::Arc:
401 		case PageItem::ItemType1:
402 		case PageItem::ItemType3:
403 		case PageItem::Polygon:
404 		case PageItem::RegularPolygon:
405 			setEnabled(false);
406 			break;
407 		case PageItem::PolyLine:
408 			setEnabled(false);
409 			break;
410 		case PageItem::PathText:
411 			setEnabled(false);
412 			break;
413 		case PageItem::Symbol:
414 			setEnabled(false);
415 			break;
416 		}
417 	}
418 	if (currItem)
419 	{
420 		setCurrentItem(currItem);
421 	}
422 	updateGeometry();
423 	//repaint();
424 }
425 
handleUpdateRequest(int updateFlags)426 void PropertiesPalette_Image::handleUpdateRequest(int updateFlags)
427 {
428 	if (updateFlags & reqCmsOptionsUpdate)
429 		showCMSOptions();
430 }
431 
setCurrentItem(PageItem * item)432 void PropertiesPalette_Image::setCurrentItem(PageItem *item)
433 {
434 	if (!m_ScMW || m_ScMW->scriptIsRunning())
435 		return;
436 	//CB We shouldn't really need to process this if our item is the same one
437 	//maybe we do if the item has been changed by scripter.. but that should probably
438 	//set some status if so.
439 	//FIXME: This won't work until when a canvas deselect happens, m_item must be nullptr.
440 	//if (m_item == i)
441 	//	return;
442 
443 	if (!m_doc)
444 		setDoc(item->doc());
445 
446 	m_haveItem = false;
447 	m_item = item;
448 
449 	if (m_item->isImageFrame())
450 	{
451 		imagePageNumber->blockSignals(true);
452 		if(m_item->imageIsAvailable)
453 		{
454 			imagePageNumber->setMaximum(m_item->pixm.imgInfo.numberOfPages);
455 			imagePageNumber->setEnabled(true);
456 		}
457 		else
458 			imagePageNumber->setEnabled(false);
459 		imagePageNumber->setValue(m_item->pixm.imgInfo.actualPageNumber);
460 
461 		compressionMethod->setCurrentIndex(m_item->OverrideCompressionMethod ? m_item->CompressionMethodIndex + 1 : 0);
462 		compressionQuality->setCurrentIndex(m_item->OverrideCompressionQuality ? m_item->CompressionQualityIndex + 1 : 0);
463 		imagePageNumber->blockSignals(false);
464 
465 		imageXScaleSpinBox->blockSignals(true);
466 		imageYScaleSpinBox->blockSignals(true);
467 		imageXOffsetSpinBox->blockSignals(true);
468 		imageYOffsetSpinBox->blockSignals(true);
469 		imageRotation->blockSignals(true);
470 
471 		imgEffectsButton->setVisible(m_item->imageIsAvailable && m_item->isRaster);
472 		imgExtProperties->setVisible(m_item->imageIsAvailable && m_item->pixm.imgInfo.valid);
473 		bool setter = m_item->ScaleType;
474 		freeScale->setChecked(setter);
475 		frameScale->setChecked(!setter);
476 		if ((m_item->isLatexFrame()) || (m_item->isOSGFrame()))
477 		{
478 			freeScale->setEnabled(false);
479 			frameScale->setEnabled(false);
480 			cbProportional->setEnabled(false);
481 			imageXScaleSpinBox->setEnabled(false);
482 			imageYScaleSpinBox->setEnabled(false);
483 			imgDpiX->setEnabled(false);
484 			imgDpiY->setEnabled(false);
485 		}
486 		else
487 		{
488 			imageXScaleSpinBox->setEnabled(setter);
489 			imageYScaleSpinBox->setEnabled(setter);
490 			imgDpiX->setEnabled(setter);
491 			imgDpiY->setEnabled(setter);
492 			cbProportional->setEnabled(!setter);
493 			cbProportional->setChecked(m_item->AspectRatio);
494 			freeScale->setEnabled(true);
495 			frameScale->setEnabled(true);
496 			//Necessary for undo action
497 			keepImageWHRatioButton->setEnabled(setter);
498 			keepImageDPIRatioButton->setEnabled(setter);
499 			keepImageWHRatioButton->setChecked(m_item->AspectRatio);
500 			keepImageDPIRatioButton->setChecked(m_item->AspectRatio);
501 		}
502 //CB Why do we need this? Setting it too much here
503 // 		if (setter == true)
504 // 		{
505 // 			keepImageWHRatioButton->setChecked(setter);
506 // 			keepImageDPIRatioButton->setChecked(setter);
507 // 		}
508 		//imageXOffsetSpinBox->setEnabled(setter);
509 		//imageYOffsetSpinBox->setEnabled(setter);
510 		//imageRotation->setEnabled(setter);
511 
512 		imageXScaleSpinBox->blockSignals(false);
513 		imageYScaleSpinBox->blockSignals(false);
514 		imageXOffsetSpinBox->blockSignals(false);
515 		imageYOffsetSpinBox->blockSignals(false);
516 		imageRotation->blockSignals(false);
517 	}
518 	m_haveItem = true;
519 
520 	showScaleAndOffset(m_item->imageXScale(), m_item->imageYScale(), m_item->imageXOffset(), m_item->imageYOffset());
521 	double rrR = m_item->imageRotation();
522 	if (m_item->imageRotation() > 0)
523 		rrR = 360 - rrR;
524 	imageRotation->showValue(fabs(rrR));
525 
526 	if (m_item->isImageFrame())
527 	{
528 		updateProfileList();
529 	}
530 	if (m_item->isOSGFrame())
531 	{
532 		setEnabled(false);
533 	}
534 	if (m_item->isSymbol())
535 	{
536 		setEnabled(false);
537 	}
538 	updateSpinBoxConstants();
539 }
540 
handleLocalXY()541 void PropertiesPalette_Image::handleLocalXY()
542 {
543 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
544 		return;
545 	m_doc->itemSelection_SetImageOffset(imageXOffsetSpinBox->value() / m_unitRatio / m_item->imageXScale(), imageYOffsetSpinBox->value() / m_unitRatio / m_item->imageYScale());
546 }
547 
handleLocalScale()548 void PropertiesPalette_Image::handleLocalScale()
549 {
550 	if (!m_ScMW || m_ScMW->scriptIsRunning())
551 		return;
552 	if ((m_haveDoc) && (m_haveItem))
553 	{
554 		//CB Don't pass in the scale to the offset change as its taken from the new scale
555 		m_doc->itemSelection_SetImageScaleAndOffset(imageXScaleSpinBox->value() / 100.0 / m_item->pixm.imgInfo.xres * 72.0, imageYScaleSpinBox->value() / 100.0 / m_item->pixm.imgInfo.yres * 72.0, imageXOffsetSpinBox->value() / m_unitRatio, imageYOffsetSpinBox->value() / m_unitRatio);
556 		imgDpiX->showValue(qRound(720.0 / m_item->imageXScale()) / 10.0);
557 		imgDpiY->showValue(qRound(720.0 / m_item->imageYScale()) / 10.0);
558 	}
559 }
560 
handleLocalDpi()561 void PropertiesPalette_Image::handleLocalDpi()
562 {
563 	if (!m_ScMW || m_ScMW->scriptIsRunning())
564 		return;
565 	if ((m_haveDoc) && (m_haveItem))
566 	{
567 		//CB Don't pass in the scale to the offset change as its taken from the new scale
568 		m_doc->itemSelection_SetImageScaleAndOffset(72.0 / imgDpiX->value(), 72.0 / imgDpiY->value(), imageXOffsetSpinBox->value() / m_unitRatio, imageYOffsetSpinBox->value() / m_unitRatio);
569 
570 		imageXScaleSpinBox->showValue(m_item->imageXScale() * 100 / 72.0 * m_item->pixm.imgInfo.xres);
571 		imageYScaleSpinBox->showValue(m_item->imageYScale() * 100 / 72.0 * m_item->pixm.imgInfo.yres);
572 	}
573 }
574 
handleLocalRotation()575 void PropertiesPalette_Image::handleLocalRotation()
576 {
577 	if (!m_ScMW || m_ScMW->scriptIsRunning())
578 		return;
579 	if ((m_haveDoc) && (m_haveItem))
580 	{
581 		m_doc->itemSelection_SetImageRotation(360 - imageRotation->value());
582 		if (frameScale->isChecked())
583 		{
584 			m_item->adjustPictScale();
585 			m_item->update();
586 		}
587 	}
588 }
589 
handleScaling()590 void PropertiesPalette_Image::handleScaling()
591 {
592 	if (!m_ScMW || m_ScMW->scriptIsRunning())
593 		return;
594 
595 	if (freeScale == sender())
596 	{
597 		frameScale->setChecked(false);
598 		freeScale->setChecked(true);
599 		cbProportional->setEnabled(false);
600 //		imageXOffsetSpinBox->setEnabled(true);
601 //		imageYOffsetSpinBox->setEnabled(true);
602 		imageXScaleSpinBox->setEnabled(true);
603 		imageYScaleSpinBox->setEnabled(true);
604 		imgDpiX->setEnabled(true);
605 		imgDpiY->setEnabled(true);
606 //		imageRotation->setEnabled(true);
607 		keepImageWHRatioButton->setEnabled(true);
608 		keepImageDPIRatioButton->setEnabled(true);
609 	}
610 	if (frameScale == sender())
611 	{
612 		frameScale->setChecked(true);
613 		freeScale->setChecked(false);
614 		cbProportional->setEnabled(true);
615 //		imageXOffsetSpinBox->setEnabled(false);
616 //		imageYOffsetSpinBox->setEnabled(false);
617 		imageXScaleSpinBox->setEnabled(false);
618 		imageYScaleSpinBox->setEnabled(false);
619 		imgDpiX->setEnabled(false);
620 		imgDpiY->setEnabled(false);
621 //		imageRotation->setEnabled(false);
622 		keepImageWHRatioButton->setEnabled(false);
623 		keepImageDPIRatioButton->setEnabled(false);
624 	}
625 
626 	if ((m_haveDoc) && (m_haveItem))
627 	{
628 		m_item->setImageScalingMode(freeScale->isChecked(), cbProportional->isChecked());
629 		m_doc->changed();
630 		emit UpdtGui(PageItem::ImageFrame);
631 	}
632 }
633 
handleXScale()634 void PropertiesPalette_Image::handleXScale()
635 {
636 	bool xscaleBlocked = imageXScaleSpinBox->blockSignals(true);
637 	bool yscaleBlocked = imageYScaleSpinBox->blockSignals(true);
638 	if (keepImageWHRatioButton->isChecked())
639 		imageYScaleSpinBox->setValue(imageXScaleSpinBox->value());
640 	handleLocalScale();
641 	imageXScaleSpinBox->blockSignals(xscaleBlocked);
642 	imageYScaleSpinBox->blockSignals(yscaleBlocked);
643 }
644 
handleYScale()645 void PropertiesPalette_Image::handleYScale()
646 {
647 	bool xscaleBlocked = imageXScaleSpinBox->blockSignals(true);
648 	bool yscaleBlocked = imageYScaleSpinBox->blockSignals(true);
649 	if (keepImageWHRatioButton->isChecked())
650 		imageXScaleSpinBox->setValue(imageYScaleSpinBox->value());
651 	handleLocalScale();
652 	imageXScaleSpinBox->blockSignals(xscaleBlocked);
653 	imageYScaleSpinBox->blockSignals(yscaleBlocked);
654 }
655 
handleDpiX()656 void PropertiesPalette_Image::handleDpiX()
657 {
658 	bool dpiXBlocked = imgDpiX->blockSignals(true);
659 	bool dpiYBlocked = imgDpiY->blockSignals(true);
660 	if (keepImageDPIRatioButton->isChecked())
661 		imgDpiY->setValue(imgDpiX->value());
662 	handleLocalDpi();
663 	imgDpiX->blockSignals(dpiXBlocked);
664 	imgDpiY->blockSignals(dpiYBlocked);
665 }
666 
handleDpiY()667 void PropertiesPalette_Image::handleDpiY()
668 {
669 	bool dpiXBlocked = imgDpiX->blockSignals(true);
670 	bool dpiYBlocked = imgDpiY->blockSignals(true);
671 	if (keepImageDPIRatioButton->isChecked())
672 		imgDpiX->setValue(imgDpiY->value());
673 	handleLocalDpi();
674 	imgDpiX->blockSignals(dpiXBlocked);
675 	imgDpiY->blockSignals(dpiYBlocked);
676 }
677 
handleImageDPIRatio()678 void PropertiesPalette_Image::handleImageDPIRatio()
679 {
680 	if (!m_ScMW || m_ScMW->scriptIsRunning())
681 		return;
682 	bool dpiXBlocked = imgDpiX->blockSignals(true);
683 	bool dpiYBlocked = imgDpiY->blockSignals(true);
684 	if (keepImageDPIRatioButton->isChecked())
685 	{
686 		double minXY = qMin(imgDpiX->value(), imgDpiY->value());
687 		imgDpiX->setValue(minXY);
688 		imgDpiY->setValue(minXY);
689 		handleLocalDpi();
690 		keepImageWHRatioButton->setChecked(true);
691 		cbProportional->setChecked(true);
692 	}
693 	else
694 	{
695 		keepImageWHRatioButton->setChecked(false);
696 		cbProportional->setChecked(false);
697 	}
698 	imgDpiX->blockSignals(dpiXBlocked);
699 	imgDpiY->blockSignals(dpiYBlocked);
700 }
701 
handleImageWHRatio()702 void PropertiesPalette_Image::handleImageWHRatio()
703 {
704 	if (!m_ScMW || m_ScMW->scriptIsRunning())
705 		return;
706 	bool xscaleBlocked = imageXScaleSpinBox->blockSignals(true);
707 	bool yscaleBlocked = imageYScaleSpinBox->blockSignals(true);
708 	if (keepImageWHRatioButton->isChecked())
709 	{
710 		double maxXY = qMax(imageXScaleSpinBox->value(), imageYScaleSpinBox->value());
711 		imageXScaleSpinBox->setValue(maxXY);
712 		imageYScaleSpinBox->setValue(maxXY);
713 		handleLocalScale();
714 		keepImageDPIRatioButton->setChecked(true);
715 		cbProportional->setChecked(true);
716 	}
717 	else
718 	{
719 		keepImageDPIRatioButton->setChecked(false);
720 		cbProportional->setChecked(false);
721 	}
722 	imageXScaleSpinBox->blockSignals(xscaleBlocked);
723 	imageYScaleSpinBox->blockSignals(yscaleBlocked);
724 }
725 
handleImageEffects()726 void PropertiesPalette_Image::handleImageEffects()
727 {
728 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
729 		return;
730 	m_ScMW->ImageEffects();
731 }
732 
handleExtImgProperties()733 void PropertiesPalette_Image::handleExtImgProperties()
734 {
735 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
736 		return;
737 	m_ScMW->view->editExtendedImageProperties();
738 	m_doc->changed();
739 }
740 
handleImagePageNumber()741 void PropertiesPalette_Image::handleImagePageNumber()
742 {
743 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
744 		return;
745 	bool reallynew = (m_item->pixm.imgInfo.actualPageNumber != imagePageNumber->value());
746 	if(UndoManager::undoEnabled())
747 	{
748 		SimpleState *ss = new SimpleState(Um::PageNmbr.arg(static_cast<int>(imagePageNumber->value())),"",Um::IImageFrame);
749 		ss->set("IMAGE_NBR");
750 		ss->set("OLD", m_item->pixm.imgInfo.actualPageNumber);
751 		ss->set("NEW", imagePageNumber->value());
752 		UndoManager::instance()->action(m_item,ss);
753 	}
754 	m_item->pixm.imgInfo.actualPageNumber = static_cast<int>(imagePageNumber->value());
755 	if (reallynew)
756 		m_item->loadImage(m_item->externalFile(), true);
757 	m_item->update();
758 }
759 
handleProfile(const QString & prn)760 void PropertiesPalette_Image::handleProfile(const QString& prn)
761 {
762 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
763 		return;
764 	m_doc->itemSelection_SetColorProfile(inputProfiles->currentText());
765 }
766 
handleIntent()767 void PropertiesPalette_Image::handleIntent()
768 {
769 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
770 		return;
771 	m_doc->itemSelection_SetRenderIntent(renderIntent->currentIndex());
772 }
773 
handleCompressionMethod()774 void PropertiesPalette_Image::handleCompressionMethod()
775 {
776 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
777 		return;
778 	m_doc->itemSelection_SetCompressionMethod(compressionMethod->currentIndex() - 1);
779 }
780 
handleCompressionQuality()781 void PropertiesPalette_Image::handleCompressionQuality()
782 {
783 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
784 		return;
785 	m_doc->itemSelection_SetCompressionQuality(compressionQuality->currentIndex() - 1);
786 }
787 
languageChange()788 void PropertiesPalette_Image::languageChange()
789 {
790 	retranslateUi(this);
791 
792 	imagePageNumber->setSpecialValueText( tr( "Auto" ));
793 
794 	QSignalBlocker renderIntentBlocker(renderIntent);
795 	int oldRenderI = renderIntent->currentIndex();
796 	renderIntent->clear();
797 	renderIntent->addItem( tr("Perceptual"));
798 	renderIntent->addItem( tr("Relative Colorimetric"));
799 	renderIntent->addItem( tr("Saturation"));
800 	renderIntent->addItem( tr("Absolute Colorimetric"));
801 	renderIntent->setCurrentIndex(oldRenderI);
802 
803 	QSignalBlocker compressionMethodBlocker(compressionMethod);
804 	int oldCompressionMethod = compressionMethod->currentIndex();
805 	compressionMethod->clear();
806 	compressionMethod->addItem( tr( "Global" ) );
807 	compressionMethod->addItem( tr( "Automatic" ) );
808 	compressionMethod->addItem( tr( "Lossy - JPEG" ) );
809 	compressionMethod->addItem( tr( "Lossless - Zip" ) );
810 	compressionMethod->addItem( tr( "None" ) );
811 	compressionMethod->setCurrentIndex(oldCompressionMethod);
812 
813 	QSignalBlocker compressionQualityBlocker(compressionQuality);
814 	int oldCompressionQuality = compressionQuality->currentIndex();
815 	compressionQuality->clear();
816 	compressionQuality->addItem( tr( "Global" ) );
817 	compressionQuality->addItem( tr( "Maximum" ) );
818 	compressionQuality->addItem( tr( "High" ) );
819 	compressionQuality->addItem( tr( "Medium" ) );
820 	compressionQuality->addItem( tr( "Low" ) );
821 	compressionQuality->addItem( tr( "Minimum" ) );
822 	compressionQuality->setCurrentIndex(oldCompressionQuality);
823 
824 	QString pctSuffix = tr(" %");
825 	imageXScaleSpinBox->setSuffix(pctSuffix);
826 	imageYScaleSpinBox->setSuffix(pctSuffix);
827 
828 	QString ptSuffix = tr(" pt");
829 	QString suffix   = (m_haveDoc) ? unitGetSuffixFromIndex(m_doc->unitIndex()) : ptSuffix;
830 
831 	imageXOffsetSpinBox->setSuffix(suffix);
832 	imageYOffsetSpinBox->setSuffix(suffix);
833 }
834 
unitChange()835 void PropertiesPalette_Image::unitChange()
836 {
837 	if (!m_doc)
838 		return;
839 
840 	QSignalBlocker imageXOffsetSpinBoxBlocker(imageXOffsetSpinBox);
841 	QSignalBlocker imageYOffsetSpinBoxBlocker(imageYOffsetSpinBox);
842 
843 	m_unitRatio = m_doc->unitRatio();
844 	m_unitIndex = m_doc->unitIndex();
845 
846 	imageXOffsetSpinBox->setNewUnit(m_unitIndex);
847 	imageYOffsetSpinBox->setNewUnit(m_unitIndex);
848 }
849 
localeChange()850 void PropertiesPalette_Image::localeChange()
851 {
852 	const QLocale& l(LocaleManager::instance().userPreferredLocale());
853 	imagePageNumber->setLocale(l);
854 	imageXScaleSpinBox->setLocale(l);
855 	imageYScaleSpinBox->setLocale(l);
856 	imageXOffsetSpinBox->setLocale(l);
857 	imageYOffsetSpinBox->setLocale(l);
858 	imageRotation->setLocale(l);
859 	imgDpiX->setLocale(l);
860 	imgDpiY->setLocale(l);
861 }
862 
userActionOn()863 bool PropertiesPalette_Image::userActionOn()
864 {
865 	return m_userActionOn;
866 }
867 
spinboxStartUserAction()868 void PropertiesPalette_Image::spinboxStartUserAction()
869 {
870 	m_userActionOn = true;
871 }
872 
spinboxFinishUserAction()873 void PropertiesPalette_Image::spinboxFinishUserAction()
874 {
875 	m_userActionOn = false;
876 
877 	for (int i = 0; i < m_doc->m_Selection->count(); ++i)
878 		m_doc->m_Selection->itemAt(i)->checkChanges(true);
879 	if (m_ScMW->view->groupTransactionStarted())
880 	{
881 		m_ScMW->view->endGroupTransaction();
882 	}
883 }
884 
885 
886