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
@@ -111,6 +124,7 @@ void OptionsWidget::preUpdateUI(const PageInfo& pageInfo, const Margins& margins
111124
112125 marginsGroup->setEnabled (false );
113126 alignmentGroup->setEnabled (false );
127+ keepSourceDpiFieldsEnabled ();
114128
115129 onUnitsChanged (UnitsProvider::getInstance ().getUnits ());
116130} // OptionsWidget::preUpdateUI
@@ -123,6 +137,12 @@ void OptionsWidget::postUpdateUI() {
123137
124138 m_marginsMM = m_settings->getHardMarginsMM (m_pageId);
125139 updateMarginsDisplay ();
140+ updateSourceDpiDisplay ();
141+
142+ if (m_sourceDpiFocusWidget) {
143+ m_sourceDpiFocusWidget->setFocus (Qt::OtherFocusReason);
144+ m_sourceDpiFocusWidget = nullptr ;
145+ }
126146}
127147
128148void OptionsWidget::marginsSetExternally (const Margins& marginsMm) {
@@ -441,6 +461,9 @@ void OptionsWidget::setupUiConnections() {
441461 CONNECT (leftRightLink, SIGNAL (clicked ()), this , SLOT (leftRightLinkClicked ()));
442462 CONNECT (applyMarginsBtn, SIGNAL (clicked ()), this , SLOT (showApplyMarginsDialog ()));
443463 CONNECT (fixDpiBtn, SIGNAL (clicked ()), this , SLOT (onFixDpiClicked ()));
464+ CONNECT (sourceDpiCombo, SIGNAL (activated (int )), this , SLOT (sourceDpiComboActivated (int )));
465+ CONNECT (sourceXDpi, SIGNAL (editingFinished ()), this , SLOT (sourceDpiEditingFinished ()));
466+ CONNECT (sourceYDpi, SIGNAL (editingFinished ()), this , SLOT (sourceDpiEditingFinished ()));
444467 CONNECT (alignWithOthersCB, SIGNAL (toggled (bool )), this , SLOT (alignWithOthersToggled ()));
445468 CONNECT (applyAlignmentBtn, SIGNAL (clicked ()), this , SLOT (showApplyAlignmentDialog ()));
446469 CONNECT (matchSizeToAllBtn, SIGNAL (clicked ()), this , SLOT (matchSizeToAllPages ()));
@@ -532,6 +555,160 @@ void OptionsWidget::setupIcons() {
532555}
533556
534557void OptionsWidget::onFixDpiClicked () {
535- emit fixDpiRequested (); // MainWindow opens FixDpiDialog (issue #93).
558+ emit fixDpiRequested ();
559+ }
560+
561+ void OptionsWidget::setupSourceDpiControls () {
562+ sourceDpiCombo->addItem (tr (" Custom" ), QVariant ());
563+ sourceDpiCombo->addItem (QStringLiteral (" 300 x 300" ), QSize (300 , 300 ));
564+ sourceDpiCombo->addItem (QStringLiteral (" 400 x 400" ), QSize (400 , 400 ));
565+ sourceDpiCombo->addItem (QStringLiteral (" 600 x 600" ), QSize (600 , 600 ));
566+ sourceDpiCombo->addItem (QStringLiteral (" 1200 x 1200" ), QSize (1200 , 1200 ));
567+
568+ sourceXDpi->setMaxLength (4 );
569+ sourceYDpi->setMaxLength (4 );
570+ sourceXDpi->setValidator (new QIntValidator (sourceXDpi));
571+ sourceYDpi->setValidator (new QIntValidator (sourceYDpi));
572+
573+ m_sourceDpiNormalPalette = sourceXDpi->palette ();
574+ m_sourceDpiErrorPalette = m_sourceDpiNormalPalette;
575+ const QColor errorColor (ColorSchemeManager::instance ().getColorParam (" FixDpiDialogErrorText" , QColor (Qt::red)));
576+ m_sourceDpiErrorPalette.setColor (QPalette::Text, errorColor);
577+ }
578+
579+ void OptionsWidget::updateSourceDpiDisplay () {
580+ auto block = m_connectionManager.getScopedBlock ();
581+
582+ if (m_dpi.isNull ()) {
583+ sourceXDpi->clear ();
584+ sourceYDpi->clear ();
585+ } else {
586+ sourceXDpi->setText (QString::number (m_dpi.horizontal ()));
587+ sourceYDpi->setText (QString::number (m_dpi.vertical ()));
588+ }
589+
590+ updateSourceDpiComboFromFields ();
591+
592+ const ImageMetadata metadata (m_sourceImagePixelSize, m_dpi);
593+ decorateSourceDpiField (sourceXDpi, metadata.horizontalDpiStatus ());
594+ decorateSourceDpiField (sourceYDpi, metadata.verticalDpiStatus ());
595+ }
596+
597+ void OptionsWidget::commitSourceDpiIfValid () {
598+ if (m_pageId.isNull () || !m_pages) {
599+ return ;
600+ }
601+
602+ bool xOk = false ;
603+ bool yOk = false ;
604+ const int horizontalDpi = sourceXDpi->text ().toInt (&xOk);
605+ const int verticalDpi = sourceYDpi->text ().toInt (&yOk);
606+ if (!xOk || !yOk) {
607+ return ;
608+ }
609+
610+ const Dpi dpi (horizontalDpi, verticalDpi);
611+ if (dpi == m_dpi) {
612+ return ;
613+ }
614+
615+ const ImageMetadata updated (m_sourceImagePixelSize, dpi);
616+ if (!updated.isDpiOK ()) {
617+ return ;
618+ }
619+
620+ m_pages->updateImageMetadata (m_pageId.imageId (), updated);
621+ m_dpi = dpi;
622+ emit invalidateAllThumbnails ();
623+ emit reloadRequested ();
624+ updateMarginsDisplay ();
625+ }
626+
627+ void OptionsWidget::decorateSourceDpiField (QLineEdit* field, const ImageMetadata::DpiStatus dpiStatus) {
628+ if (dpiStatus == ImageMetadata::DPI_OK ) {
629+ field->setPalette (m_sourceDpiNormalPalette);
630+ field->setToolTip (QString ());
631+ return ;
632+ }
633+
634+ field->setPalette (m_sourceDpiErrorPalette);
635+ switch (dpiStatus) {
636+ case ImageMetadata::DPI_TOO_LARGE :
637+ field->setToolTip (tr (" DPI is too large and most likely wrong." ));
638+ break ;
639+ case ImageMetadata::DPI_TOO_SMALL :
640+ field->setToolTip (
641+ tr (" DPI is too small. Even if it's correct, you are not going to get acceptable results with it." ));
642+ break ;
643+ case ImageMetadata::DPI_TOO_SMALL_FOR_THIS_PIXEL_SIZE :
644+ field->setToolTip (
645+ tr (" An extremely low DPI value. That might correspond to a very large paper size for the pixel size in "
646+ " question." ));
647+ break ;
648+ default :
649+ field->setToolTip (QString ());
650+ break ;
651+ }
652+ }
653+
654+ void OptionsWidget::updateSourceDpiComboFromFields () {
655+ bool xOk = false ;
656+ bool yOk = false ;
657+ const QSize dpi (sourceXDpi->text ().toInt (&xOk), sourceYDpi->text ().toInt (&yOk));
658+
659+ if (xOk && yOk) {
660+ const int count = sourceDpiCombo->count ();
661+ for (int i = 0 ; i < count; ++i) {
662+ const QVariant data (sourceDpiCombo->itemData (i));
663+ if (data.isValid () && (dpi == data.toSize ())) {
664+ sourceDpiCombo->setCurrentIndex (i);
665+ return ;
666+ }
667+ }
668+ }
669+
670+ sourceDpiCombo->setCurrentIndex (0 );
671+ }
672+
673+ void OptionsWidget::keepSourceDpiFieldsEnabled () {
674+ sourceDpiLabel->setEnabled (true );
675+ sourceDpiCombo->setEnabled (true );
676+ sourceDpiTimesLabel->setEnabled (true );
677+ sourceXDpi->setEnabled (true );
678+ sourceYDpi->setEnabled (true );
679+ fixDpiBtn->setEnabled (true );
680+ }
681+
682+ bool OptionsWidget::isSourceDpiFieldFocused () const {
683+ const QWidget* const focused = focusWidget ();
684+ return (focused == sourceXDpi) || (focused == sourceYDpi) || (focused == sourceDpiCombo);
685+ }
686+
687+ void OptionsWidget::sourceDpiComboActivated (const int index) {
688+ const QVariant data (sourceDpiCombo->itemData (index));
689+ if (!data.isValid ()) {
690+ return ;
691+ }
692+
693+ const QSize dpi (data.toSize ());
694+ sourceXDpi->setText (QString::number (dpi.width ()));
695+ sourceYDpi->setText (QString::number (dpi.height ()));
696+ sourceDpiEditingFinished ();
697+ }
698+
699+ void OptionsWidget::sourceDpiEditingFinished () {
700+ updateSourceDpiComboFromFields ();
701+
702+ bool xOk = false ;
703+ bool yOk = false ;
704+ const int horizontalDpi = sourceXDpi->text ().toInt (&xOk);
705+ const int verticalDpi = sourceYDpi->text ().toInt (&yOk);
706+ if (xOk && yOk) {
707+ const ImageMetadata metadata (m_sourceImagePixelSize, Dpi (horizontalDpi, verticalDpi));
708+ decorateSourceDpiField (sourceXDpi, metadata.horizontalDpiStatus ());
709+ decorateSourceDpiField (sourceYDpi, metadata.verticalDpiStatus ());
710+ }
711+
712+ commitSourceDpiIfValid ();
536713}
537714} // namespace page_layout
0 commit comments