33#include <QRadioButton>
35#include <QDoubleSpinBox>
51 , m_savedUniformScaling(false)
59 aspectButton->setKeepAspectRatio(
false);
98 SIGNAL(canvasResourceChanged(
int,QVariant)),
106 cmbPaintOrder->setIconSize(QSize(22, 22));
107 cmbPaintOrder->addItem(
KisIconUtils::loadIcon(
"paint-order-fill-stroke-marker"), i18n(
"Fill, Stroke, Markers"));
108 cmbPaintOrder->addItem(
KisIconUtils::loadIcon(
"paint-order-fill-marker-stroke"), i18n(
"Fill, Markers, Stroke"));
109 cmbPaintOrder->addItem(
KisIconUtils::loadIcon(
"paint-order-stroke-fill-marker"), i18n(
"Stroke, Fill, Markers"));
110 cmbPaintOrder->addItem(
KisIconUtils::loadIcon(
"paint-order-stroke-marker-fill"), i18n(
"Stroke, Markers, Fill"));
111 cmbPaintOrder->addItem(
KisIconUtils::loadIcon(
"paint-order-marker-fill-stroke"), i18n(
"Markers, Fill, Stroke"));
112 cmbPaintOrder->addItem(
KisIconUtils::loadIcon(
"paint-order-marker-stroke-fill"), i18n(
"Markers, Stroke, Fill"));
116 dblOpacity->setRange(0.0, 1.0, 2);
117 dblOpacity->setSingleStep(0.01);
118 dblOpacity->setFastSliderStep(0.1);
119 dblOpacity->setTextTemplates(i18nc(
"{n} is the number value, % is the percent sign",
"Opacity: {n}"),
120 i18nc(
"{n} is the number value, % is the percent sign",
"Opacity [*varies*]: {n}"));
122 dblOpacity->setValueGetter(
146 *position = anchoredPosition;
150QRectF calculateSelectionBounds(
KoSelection *selection,
157 KoShape *shape = shapes.size() == 1 ? shapes.first() : selection;
161 QPointF resultPoint = resultRect.topLeft();
162 tryAnchorPosition(anchor, resultRect, &resultPoint);
174 resultRect = matrix.scaleTransform().mapRect(resultRect);
183 return QRectF(resultPoint, resultRect.size());
190 if (!isVisible())
return;
192 QVariant newValue(positionSelector->value());
199 if (!isVisible())
return;
206 if (shapes.size() == 1) {
207 onlyGroupShape =
dynamic_cast<KoShapeGroup*
>(shapes.first());
210 const bool uniformScalingAvailable = shapes.size() <= 1 && !onlyGroupShape;
212 if (uniformScalingAvailable && !chkUniformScaling->isEnabled()) {
214 chkUniformScaling->setEnabled(uniformScalingAvailable);
215 }
else if (!uniformScalingAvailable && chkUniformScaling->isEnabled()) {
217 chkUniformScaling->setChecked(
true);
218 chkUniformScaling->setEnabled(uniformScalingAvailable);
222 chkAnchorLock->setEnabled(
false);
238 if (!isVisible())
return;
243 bool hasKeepAspectRatio =
false;
244 bool hasNotKeepAspectRatio =
false;
246 Q_FOREACH (
KoShape *shape, shapes) {
248 hasKeepAspectRatio =
true;
250 hasNotKeepAspectRatio =
true;
253 if (hasKeepAspectRatio && hasNotKeepAspectRatio)
break;
256 Q_UNUSED(hasNotKeepAspectRatio);
258 const bool useGlobalSize = chkGlobalCoordinates->isChecked();
260 const QRectF
bounds = calculateSelectionBounds(selection, anchor, useGlobalSize);
261 const bool hasNullDimensions =
bounds.isEmpty();
263 aspectButton->setKeepAspectRatio(hasKeepAspectRatio && !hasNullDimensions);
264 aspectButton->setEnabled(!hasNullDimensions);
289 if (shapes.isEmpty())
return;
299 if (!isVisible())
return;
304 dblOpacity->setSelection(shapes);
311 if (shapes.isEmpty())
return;
316 switch(cmbPaintOrder->currentIndex()) {
349 if (!isVisible())
return;
354 if (!shapes.isEmpty()) {
355 KoShape *shape = shapes.first();
365 cmbPaintOrder->setCurrentIndex(index);
371 if (!isVisible())
return;
373 const bool useGlobalSize = chkGlobalCoordinates->isChecked();
377 const QRectF
bounds = calculateSelectionBounds(selection, anchor, useGlobalSize);
379 const bool hasSizeConfiguration = !
bounds.isNull();
381 widthSpinBox->setEnabled(hasSizeConfiguration &&
bounds.width() > 0);
382 heightSpinBox->setEnabled(hasSizeConfiguration &&
bounds.height() > 0);
384 if (hasSizeConfiguration) {
386 widthSpinBox->changeValue(
bounds.width());
387 heightSpinBox->changeValue(
bounds.height());
402 if (!isVisible())
return;
404 const bool useGlobalSize = chkGlobalCoordinates->isChecked();
408 QRectF
bounds = calculateSelectionBounds(selection, anchor, useGlobalSize);
410 const bool hasSizeConfiguration = !
bounds.isNull();
412 positionXSpinBox->setEnabled(hasSizeConfiguration);
413 positionYSpinBox->setEnabled(hasSizeConfiguration);
415 if (hasSizeConfiguration) {
417 positionXSpinBox->changeValue(
bounds.x());
418 positionYSpinBox->changeValue(
bounds.y());
424 static const qreal
eps = 1e-6;
426 const bool useGlobalSize = chkGlobalCoordinates->isChecked();
431 QRectF
bounds = calculateSelectionBounds(selection, anchor, useGlobalSize, &shapes);
433 if (
bounds.isNull())
return;
435 const QPointF oldPosition =
bounds.topLeft();
436 const QPointF newPosition(positionXSpinBox->value(), positionYSpinBox->value());
437 const QPointF diff = newPosition - oldPosition;
439 if (diff.manhattanLength() <
eps)
return;
444 Q_FOREACH (
KoShape *shape, shapes) {
448 newPositions << oldShapePosition + diff;
457 static const qreal
eps = 1e-4;
459 const bool useGlobalSize = chkGlobalCoordinates->isChecked();
464 QRectF
bounds = calculateSelectionBounds(selection, anchor, useGlobalSize, &shapes);
466 if (
bounds.isNull())
return;
468 const QSizeF oldSize(
bounds.size());
470 QSizeF newSize(widthSpinBox->value(), heightSpinBox->value());
473 const qreal scaleX = oldSize.width() > 0 ? newSize.width() / oldSize.width() : 1.0;
474 const qreal scaleY = oldSize.height() > 0 ? newSize.height() / oldSize.height() : 1.0;
476 if (qAbs(scaleX - 1.0) <
eps && qAbs(scaleY - 1.0) <
eps)
return;
478 const bool usePostScaling =
479 shapes.size() > 1 || chkUniformScaling->isChecked();
492 positionXSpinBox->setUnit(unit);
493 positionYSpinBox->setUnit(unit);
494 widthSpinBox->setUnit(unit);
495 heightSpinBox->setUnit(unit);
497 positionXSpinBox->setDecimals(2);
498 positionYSpinBox->setDecimals(2);
499 widthSpinBox->setDecimals(2);
500 heightSpinBox->setDecimals(2);
503 positionXSpinBox->preventDecimalsChangeFromUnitManager(
true);
504 positionYSpinBox->preventDecimalsChangeFromUnitManager(
true);
505 widthSpinBox->preventDecimalsChangeFromUnitManager(
true);
506 heightSpinBox->preventDecimalsChangeFromUnitManager(
true);
508 positionXSpinBox->setLineStep(1.0);
509 positionYSpinBox->setLineStep(1.0);
510 widthSpinBox->setLineStep(1.0);
511 heightSpinBox->setLineStep(1.0);
519 return chkUniformScaling->isChecked();
524 QWidget::showEvent(event);
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KisAcyclicSignalConnector * createCoordinatedConnector()
create a coordinated connector that can be used for extending the number of self-locking connection.
void connectBackwardVoid(QObject *sender, const char *signal, QObject *receiver, const char *method)
void connectForwardVoid(QObject *sender, const char *signal, QObject *receiver, const char *method)
virtual void addCommand(KUndo2Command *command)=0
QPointer< KoCanvasResourceProvider > resourceManager
virtual KoSelectedShapesProxy * selectedShapesProxy() const =0
selectedShapesProxy() is a special interface for keeping a persistent connections to selectionChanged...
QVariant resource(int key) const
void setResource(int key, const QVariant &value)
The KoSelectedShapesProxy class is a special interface of KoCanvasBase to have a stable connection to...
virtual KoSelection * selection()=0
const QList< KoShape * > selectedEditableShapes() const
The undo / redo command for shape moving.
The undo / redo command for setting the shape transparency.
virtual QRectF outlineRect() const
virtual QVector< PaintOrder > paintOrder() const
paintOrder
QPointF absolutePosition(KoFlake::AnchorPosition anchor=KoFlake::Center) const
QTransform absoluteTransformation() const
QTransform transformation() const
Returns the shapes local transformation matrix.
bool keepAspectRatio() const
qreal transparency(bool recursive=false) const
@ Point
Postscript point, 1/72th of an Inco.
Size ensureSizeNotSmaller(const Size &size, const Size &bounds)
QIcon loadIcon(const QString &name)
@ Unit
The unit of this canvas.
KRITAFLAKE_EXPORT QPointF anchorToPoint(AnchorPosition anchor, const QRectF rect, bool *valid=0)