33
44#include " OptionsWidget.h"
55
6+ #include < ColorSchemeManager.h>
67#include < UnitsProvider.h>
78#include < core/IconProvider.h>
89
10+ #include < QIntValidator>
11+ #include < QLineEdit>
912#include < QSettings>
1013#include < utility>
1114
1215#include " ../../Utils.h"
1316#include " ApplyDialog.h"
1417#include " ApplyMarginsDialog.h"
18+ #include " ProjectPages.h"
1519#include " Settings.h"
1620
1721using namespace core ;
1822
1923namespace page_layout {
20- OptionsWidget::OptionsWidget (std::shared_ptr<Settings> settings, const PageSelectionAccessor& pageSelectionAccessor)
24+ OptionsWidget::OptionsWidget (std::shared_ptr<Settings> settings,
25+ std::shared_ptr<ProjectPages> pages,
26+ const PageSelectionAccessor& pageSelectionAccessor)
2127 : m_settings(std::move(settings)),
28+ m_pages (std::move(pages)),
2229 m_pageSelectionAccessor(pageSelectionAccessor),
2330 m_leftRightLinked(true ),
2431 m_topBottomLinked(true ),
25- m_connectionManager(std::bind(&OptionsWidget::setupUiConnections, this )) {
32+ m_connectionManager(std::bind(&OptionsWidget::setupUiConnections, this )),
33+ m_sourceDpiFocusWidget(nullptr ) {
2634 {
2735 QSettings appSettings;
2836 m_leftRightLinked = appSettings.value (" margins/leftRightLinked" , true ).toBool ();
@@ -31,6 +39,7 @@ OptionsWidget::OptionsWidget(std::shared_ptr<Settings> settings, const PageSelec
3139
3240 setupUi (this );
3341 setupIcons ();
42+ setupSourceDpiControls ();
3443
3544 updateLinkDisplay (topBottomLink, m_topBottomLinked);
3645 updateLinkDisplay (leftRightLink, m_leftRightLinked);
@@ -57,10 +66,14 @@ OptionsWidget::OptionsWidget(std::shared_ptr<Settings> settings, const PageSelec
5766OptionsWidget::~OptionsWidget () = default ;
5867
5968void OptionsWidget::preUpdateUI (const PageInfo& pageInfo, const Margins& marginsMm, const Alignment& alignment) {
69+ commitSourceDpiIfValid ();
70+ m_sourceDpiFocusWidget = isSourceDpiFieldFocused () ? focusWidget () : nullptr ;
71+
6072 auto block = m_connectionManager.getScopedBlock ();
6173
6274 m_pageId = pageInfo.id ();
6375 m_dpi = pageInfo.metadata ().dpi ();
76+ m_sourceImagePixelSize = pageInfo.metadata ().size ();
6477 m_marginsMM = marginsMm;
6578 m_alignment = alignment;
6679
@@ -112,6 +125,7 @@ void OptionsWidget::preUpdateUI(const PageInfo& pageInfo, const Margins& margins
112125
113126 marginsGroup->setEnabled (false );
114127 alignmentGroup->setEnabled (false );
128+ keepSourceDpiFieldsEnabled ();
115129
116130 onUnitsChanged (UnitsProvider::getInstance ().getUnits ());
117131} // OptionsWidget::preUpdateUI
@@ -124,6 +138,12 @@ void OptionsWidget::postUpdateUI() {
124138
125139 m_marginsMM = m_settings->getHardMarginsMM (m_pageId);
126140 updateMarginsDisplay ();
141+ updateSourceDpiDisplay ();
142+
143+ if (m_sourceDpiFocusWidget) {
144+ m_sourceDpiFocusWidget->setFocus (Qt::OtherFocusReason);
145+ m_sourceDpiFocusWidget = nullptr ;
146+ }
127147}
128148
129149void OptionsWidget::marginsSetExternally (const Margins& marginsMm) {
@@ -447,6 +467,9 @@ void OptionsWidget::setupUiConnections() {
447467 CONNECT (leftRightLink, SIGNAL (clicked ()), this , SLOT (leftRightLinkClicked ()));
448468 CONNECT (applyMarginsBtn, SIGNAL (clicked ()), this , SLOT (showApplyMarginsDialog ()));
449469 CONNECT (fixDpiBtn, SIGNAL (clicked ()), this , SLOT (onFixDpiClicked ()));
470+ CONNECT (sourceDpiCombo, SIGNAL (activated (int )), this , SLOT (sourceDpiComboActivated (int )));
471+ CONNECT (sourceXDpi, SIGNAL (editingFinished ()), this , SLOT (sourceDpiEditingFinished ()));
472+ CONNECT (sourceYDpi, SIGNAL (editingFinished ()), this , SLOT (sourceDpiEditingFinished ()));
450473 CONNECT (alignWithOthersCB, SIGNAL (toggled (bool )), this , SLOT (alignWithOthersToggled ()));
451474 CONNECT (applyAlignmentBtn, SIGNAL (clicked ()), this , SLOT (showApplyAlignmentDialog ()));
452475 CONNECT (matchSizeToAllBtn, SIGNAL (clicked ()), this , SLOT (matchSizeToAllPages ()));
@@ -539,6 +562,160 @@ void OptionsWidget::setupIcons() {
539562}
540563
541564void OptionsWidget::onFixDpiClicked () {
542- emit fixDpiRequested (); // MainWindow opens FixDpiDialog (issue #93).
565+ emit fixDpiRequested ();
566+ }
567+
568+ void OptionsWidget::setupSourceDpiControls () {
569+ sourceDpiCombo->addItem (tr (" Custom" ), QVariant ());
570+ sourceDpiCombo->addItem (QStringLiteral (" 300 x 300" ), QSize (300 , 300 ));
571+ sourceDpiCombo->addItem (QStringLiteral (" 400 x 400" ), QSize (400 , 400 ));
572+ sourceDpiCombo->addItem (QStringLiteral (" 600 x 600" ), QSize (600 , 600 ));
573+ sourceDpiCombo->addItem (QStringLiteral (" 1200 x 1200" ), QSize (1200 , 1200 ));
574+
575+ sourceXDpi->setMaxLength (4 );
576+ sourceYDpi->setMaxLength (4 );
577+ sourceXDpi->setValidator (new QIntValidator (sourceXDpi));
578+ sourceYDpi->setValidator (new QIntValidator (sourceYDpi));
579+
580+ m_sourceDpiNormalPalette = sourceXDpi->palette ();
581+ m_sourceDpiErrorPalette = m_sourceDpiNormalPalette;
582+ const QColor errorColor (ColorSchemeManager::instance ().getColorParam (" FixDpiDialogErrorText" , QColor (Qt::red)));
583+ m_sourceDpiErrorPalette.setColor (QPalette::Text, errorColor);
584+ }
585+
586+ void OptionsWidget::updateSourceDpiDisplay () {
587+ auto block = m_connectionManager.getScopedBlock ();
588+
589+ if (m_dpi.isNull ()) {
590+ sourceXDpi->clear ();
591+ sourceYDpi->clear ();
592+ } else {
593+ sourceXDpi->setText (QString::number (m_dpi.horizontal ()));
594+ sourceYDpi->setText (QString::number (m_dpi.vertical ()));
595+ }
596+
597+ updateSourceDpiComboFromFields ();
598+
599+ const ImageMetadata metadata (m_sourceImagePixelSize, m_dpi);
600+ decorateSourceDpiField (sourceXDpi, metadata.horizontalDpiStatus ());
601+ decorateSourceDpiField (sourceYDpi, metadata.verticalDpiStatus ());
602+ }
603+
604+ void OptionsWidget::commitSourceDpiIfValid () {
605+ if (m_pageId.isNull () || !m_pages) {
606+ return ;
607+ }
608+
609+ bool xOk = false ;
610+ bool yOk = false ;
611+ const int horizontalDpi = sourceXDpi->text ().toInt (&xOk);
612+ const int verticalDpi = sourceYDpi->text ().toInt (&yOk);
613+ if (!xOk || !yOk) {
614+ return ;
615+ }
616+
617+ const Dpi dpi (horizontalDpi, verticalDpi);
618+ if (dpi == m_dpi) {
619+ return ;
620+ }
621+
622+ const ImageMetadata updated (m_sourceImagePixelSize, dpi);
623+ if (!updated.isDpiOK ()) {
624+ return ;
625+ }
626+
627+ m_pages->updateImageMetadata (m_pageId.imageId (), updated);
628+ m_dpi = dpi;
629+ emit invalidateAllThumbnails ();
630+ emit reloadRequested ();
631+ updateMarginsDisplay ();
632+ }
633+
634+ void OptionsWidget::decorateSourceDpiField (QLineEdit* field, const ImageMetadata::DpiStatus dpiStatus) {
635+ if (dpiStatus == ImageMetadata::DPI_OK ) {
636+ field->setPalette (m_sourceDpiNormalPalette);
637+ field->setToolTip (QString ());
638+ return ;
639+ }
640+
641+ field->setPalette (m_sourceDpiErrorPalette);
642+ switch (dpiStatus) {
643+ case ImageMetadata::DPI_TOO_LARGE :
644+ field->setToolTip (tr (" DPI is too large and most likely wrong." ));
645+ break ;
646+ case ImageMetadata::DPI_TOO_SMALL :
647+ field->setToolTip (
648+ tr (" DPI is too small. Even if it's correct, you are not going to get acceptable results with it." ));
649+ break ;
650+ case ImageMetadata::DPI_TOO_SMALL_FOR_THIS_PIXEL_SIZE :
651+ field->setToolTip (
652+ tr (" An extremely low DPI value. That might correspond to a very large paper size for the pixel size in "
653+ " question." ));
654+ break ;
655+ default :
656+ field->setToolTip (QString ());
657+ break ;
658+ }
659+ }
660+
661+ void OptionsWidget::updateSourceDpiComboFromFields () {
662+ bool xOk = false ;
663+ bool yOk = false ;
664+ const QSize dpi (sourceXDpi->text ().toInt (&xOk), sourceYDpi->text ().toInt (&yOk));
665+
666+ if (xOk && yOk) {
667+ const int count = sourceDpiCombo->count ();
668+ for (int i = 0 ; i < count; ++i) {
669+ const QVariant data (sourceDpiCombo->itemData (i));
670+ if (data.isValid () && (dpi == data.toSize ())) {
671+ sourceDpiCombo->setCurrentIndex (i);
672+ return ;
673+ }
674+ }
675+ }
676+
677+ sourceDpiCombo->setCurrentIndex (0 );
678+ }
679+
680+ void OptionsWidget::keepSourceDpiFieldsEnabled () {
681+ sourceDpiLabel->setEnabled (true );
682+ sourceDpiCombo->setEnabled (true );
683+ sourceDpiTimesLabel->setEnabled (true );
684+ sourceXDpi->setEnabled (true );
685+ sourceYDpi->setEnabled (true );
686+ fixDpiBtn->setEnabled (true );
687+ }
688+
689+ bool OptionsWidget::isSourceDpiFieldFocused () const {
690+ const QWidget* const focused = focusWidget ();
691+ return (focused == sourceXDpi) || (focused == sourceYDpi) || (focused == sourceDpiCombo);
692+ }
693+
694+ void OptionsWidget::sourceDpiComboActivated (const int index) {
695+ const QVariant data (sourceDpiCombo->itemData (index));
696+ if (!data.isValid ()) {
697+ return ;
698+ }
699+
700+ const QSize dpi (data.toSize ());
701+ sourceXDpi->setText (QString::number (dpi.width ()));
702+ sourceYDpi->setText (QString::number (dpi.height ()));
703+ sourceDpiEditingFinished ();
704+ }
705+
706+ void OptionsWidget::sourceDpiEditingFinished () {
707+ updateSourceDpiComboFromFields ();
708+
709+ bool xOk = false ;
710+ bool yOk = false ;
711+ const int horizontalDpi = sourceXDpi->text ().toInt (&xOk);
712+ const int verticalDpi = sourceYDpi->text ().toInt (&yOk);
713+ if (xOk && yOk) {
714+ const ImageMetadata metadata (m_sourceImagePixelSize, Dpi (horizontalDpi, verticalDpi));
715+ decorateSourceDpiField (sourceXDpi, metadata.horizontalDpiStatus ());
716+ decorateSourceDpiField (sourceYDpi, metadata.verticalDpiStatus ());
717+ }
718+
719+ commitSourceDpiIfValid ();
543720}
544721} // namespace page_layout
0 commit comments