diff --git a/lib/crop/croptool.cpp b/lib/crop/croptool.cpp
--- a/lib/crop/croptool.cpp
+++ b/lib/crop/croptool.cpp
@@ -201,6 +201,9 @@
q, SLOT(slotCropRequested()));
QObject::connect(mCropWidget, SIGNAL(done()),
q, SIGNAL(done()));
+
+ // This is needed when crop ratio set to Current Image, and the image is rotated
+ QObject::connect(view, &RasterImageView::imageRectUpdated, mCropWidget, &CropWidget::updateCropRatio);
}
QRect computeVisibleImageRect() const
diff --git a/lib/crop/cropwidget.h b/lib/crop/cropwidget.h
--- a/lib/crop/cropwidget.h
+++ b/lib/crop/cropwidget.h
@@ -52,13 +52,16 @@
void cropRequested();
void done();
+public Q_SLOTS:
+ void updateCropRatio();
+
private Q_SLOTS:
void slotPositionChanged();
void slotWidthChanged();
void slotHeightChanged();
void setCropRect(const QRect& rect);
- void slotRatioComboBoxEditTextChanged();
+ void slotAdvancedCheckBoxToggled(bool checked);
void applyRatioConstraint();
private:
diff --git a/lib/crop/cropwidget.cpp b/lib/crop/cropwidget.cpp
--- a/lib/crop/cropwidget.cpp
+++ b/lib/crop/cropwidget.cpp
@@ -50,13 +50,10 @@
return b == 0 ? a : gcd(b, a % b);
}
-static QSize screenRatio()
+static QSize ratio(const QSize &size)
{
- const QRect rect = QApplication::desktop()->screenGeometry();
- const int width = rect.width();
- const int height = rect.height();
- const int divisor = gcd(width, height);
- return QSize(width / divisor, height / divisor);
+ const int divisor = gcd(size.width(), size.height());
+ return size / divisor;
}
struct CropWidgetPrivate : public Ui_CropWidget
@@ -66,40 +63,50 @@
Document::Ptr mDocument;
CropTool* mCropTool;
bool mUpdatingFromCropTool;
+ int mCurrentImageComboBoxIndex;
bool ratioIsConstrained() const
{
return cropRatio() > 0;
}
double cropRatio() const
{
- int index = ratioComboBox->currentIndex();
- if (index != -1 && ratioComboBox->currentText() == ratioComboBox->itemText(index)) {
- // Get ratio from predefined value
- // Note: We check currentText is itemText(currentIndex) because
- // currentIndex is not reset to -1 when text is edited by hand.
- QSizeF size = ratioComboBox->itemData(index).toSizeF();
- return size.height() / size.width();
- }
-
- // Not a predefined value, extract ratio from the combobox text
- const QStringList lst = ratioComboBox->currentText().split(':');
- if (lst.size() != 2) {
- return 0;
+ if (q->advancedSettingsEnabled()) {
+ int index = ratioComboBox->currentIndex();
+ if (index != -1 && ratioComboBox->currentText() == ratioComboBox->itemText(index)) {
+ // Get ratio from predefined value
+ // Note: We check currentText is itemText(currentIndex) because
+ // currentIndex is not reset to -1 when text is edited by hand.
+ QSizeF size = ratioComboBox->itemData(index).toSizeF();
+ return size.height() / size.width();
+ }
+
+ // Not a predefined value, extract ratio from the combobox text
+ const QStringList lst = ratioComboBox->currentText().split(':');
+ if (lst.size() != 2) {
+ return 0;
+ }
+
+ bool ok;
+ const double width = lst[0].toDouble(&ok);
+ if (!ok) {
+ return 0;
+ }
+ const double height = lst[1].toDouble(&ok);
+ if (!ok) {
+ return 0;
+ }
+
+ return height / width;
}
- bool ok;
- const double width = lst[0].toDouble(&ok);
- if (!ok) {
- return 0;
- }
- const double height = lst[1].toDouble(&ok);
- if (!ok) {
- return 0;
+ if (restrictToImageRatioCheckBox->isChecked()) {
+ QSizeF size = ratio(mDocument->size());
+ return size.height() / size.width();
}
- return height / width;
+ return 0;
}
void addRatioToComboBox(const QSizeF& size, const QString& label = QString())
@@ -137,8 +144,11 @@
<< QSizeF(4, 3)
<< QSizeF(5, 4);
+ addRatioToComboBox(ratio(mDocument->size()), i18n("Current Image"));
+ mCurrentImageComboBoxIndex = ratioComboBox->count() - 1; // We need to refer to this ratio later
+
addRatioToComboBox(QSizeF(1, 1), i18n("Square"));
- addRatioToComboBox(screenRatio(), i18n("This Screen"));
+ addRatioToComboBox(ratio(QApplication::desktop()->screenGeometry().size()), i18n("This Screen"));
addSectionHeaderToComboBox(i18n("Landscape"));
Q_FOREACH(const QSizeF& size, ratioList) {
@@ -162,6 +172,15 @@
// Do not use i18n("%1:%2") because ':' should not be translated, it is
// used to parse the ratio string.
edit->setPlaceholderText(QString("%1:%2").arg(i18n("Width")).arg(i18n("Height")));
+
+ // Enable clear button
+ edit->setClearButtonEnabled(true);
+ // Must manually adjust minimum width because the auto size adjustment doesn't take the
+ // clear button into account
+ const int width = ratioComboBox->minimumSizeHint().width();
+ ratioComboBox->setMinimumWidth(width + 24);
+
+ ratioComboBox->setCurrentIndex(-1);
}
QRect cropRect() const
@@ -208,11 +227,12 @@
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
layout()->setSizeConstraint(QLayout::SetFixedSize);
- connect(d->advancedCheckBox, SIGNAL(toggled(bool)),
- d->advancedWidget, SLOT(setVisible(bool)));
+ connect(d->advancedCheckBox, &QCheckBox::toggled, this, &CropWidget::slotAdvancedCheckBoxToggled);
d->advancedWidget->setVisible(false);
d->advancedWidget->layout()->setMargin(0);
+ connect(d->restrictToImageRatioCheckBox, &QCheckBox::toggled, this, &CropWidget::applyRatioConstraint);
+
d->initRatioComboBox();
connect(d->mCropTool, &CropTool::rectUpdated, this, &CropWidget::setCropRect);
@@ -224,7 +244,7 @@
d->initDialogButtonBox();
- connect(d->ratioComboBox, &QComboBox::editTextChanged, this, &CropWidget::slotRatioComboBoxEditTextChanged);
+ connect(d->ratioComboBox, &QComboBox::editTextChanged, this, &CropWidget::applyRatioConstraint);
// Don't do this before signals are connected, otherwise the tool won't get
// initialized
@@ -311,9 +331,24 @@
d->mCropTool->setRect(rect);
}
-void CropWidget::slotRatioComboBoxEditTextChanged()
+void CropWidget::slotAdvancedCheckBoxToggled(bool checked)
{
+ d->advancedWidget->setVisible(checked);
+ d->restrictToImageRatioCheckBox->setVisible(!checked);
+ applyRatioConstraint();
+}
+
+void CropWidget::updateCropRatio()
+{
+ // First we need to re-calculate the "Current Image" ratio in case the user rotated the image
+ d->ratioComboBox->setItemData(d->mCurrentImageComboBoxIndex, QVariant(ratio(d->mDocument->size())));
+
+ // Always re-apply the constraint, even though we only need to when the user has "Current Image"
+ // selected or the "Restrict to current image" checked, since there's no harm
applyRatioConstraint();
+ // If the ratio is unrestricted, calling applyRatioConstraint doesn't update the rect, so we call
+ // this manually to make sure the rect is adjusted to fit within the image
+ d->mCropTool->setRect(d->mCropTool->rect());
}
} // namespace
diff --git a/lib/crop/cropwidget.ui b/lib/crop/cropwidget.ui
--- a/lib/crop/cropwidget.ui
+++ b/lib/crop/cropwidget.ui
@@ -6,7 +6,7 @@
0
0
- 824
+ 1006
66
@@ -160,6 +160,13 @@
+ -
+
+
+ Restrict to image ratio
+
+
+
-
diff --git a/lib/documentview/rasterimageview.h b/lib/documentview/rasterimageview.h
--- a/lib/documentview/rasterimageview.h
+++ b/lib/documentview/rasterimageview.h
@@ -60,6 +60,7 @@
Q_SIGNALS:
void currentToolChanged(AbstractRasterImageViewTool*);
+ void imageRectUpdated();
protected:
void loadFromDocument() Q_DECL_OVERRIDE;
diff --git a/lib/documentview/rasterimageview.cpp b/lib/documentview/rasterimageview.cpp
--- a/lib/documentview/rasterimageview.cpp
+++ b/lib/documentview/rasterimageview.cpp
@@ -320,6 +320,7 @@
d->setScalerRegionToVisibleRect();
update();
+ emit imageRectUpdated();
}
void RasterImageView::slotDocumentIsAnimatedUpdated()