1 /******************************************************************************************************
2  * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released      *
3  * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4  * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission.     *
5  ******************************************************************************************************/
6 
7 #include "DlgImportCroppingNonPdf.h"
8 #include "EngaugeAssert.h"
9 #include "Logger.h"
10 #include "MainWindow.h"
11 #include "NonPdfCropping.h"
12 #include <QApplication>
13 #include <QGraphicsPixmapItem>
14 #include <QGraphicsScene>
15 #include <QImage>
16 #include <QLabel>
17 #include <QLayout>
18 #include <QPushButton>
19 #include <QSettings>
20 #include <QSpinBox>
21 #include <QTimer>
22 #include "Settings.h"
23 #include "ViewPreview.h"
24 
25 int DlgImportCroppingNonPdf::MINIMUM_DIALOG_WIDTH = 350;
26 int DlgImportCroppingNonPdf::MINIMUM_PREVIEW_HEIGHT = 200;
27 
DlgImportCroppingNonPdf(const QString & fileName)28 DlgImportCroppingNonPdf::DlgImportCroppingNonPdf(const QString &fileName) :
29   m_fileName (fileName),
30   m_pixmap (nullptr),
31   m_nonPdfCropping (nullptr)
32 {
33   LOG4CPP_INFO_S ((*mainCat)) << "DlgImportCroppingNonPdf::DlgImportCroppingNonPdf";
34 
35   setWindowTitle (tr ("Image File Import Cropping"));
36   setModal (true);
37 
38   QWidget *subPanel = new QWidget ();
39   QGridLayout *layout = new QGridLayout (subPanel);
40   subPanel->setLayout (layout);
41 
42   int row = 0;
43 
44   createPreview (layout, row);
45   finishPanel (subPanel);
46   updatePreview ();
47 
48   // Bring the two middle columns together
49   layout->setColumnStretch (0, 1);
50   layout->setColumnStretch (1, 0);
51   layout->setColumnStretch (2, 0);
52   layout->setColumnStretch (3, 1);
53 }
54 
~DlgImportCroppingNonPdf()55 DlgImportCroppingNonPdf::~DlgImportCroppingNonPdf()
56 {
57   LOG4CPP_INFO_S ((*mainCat)) << "DlgImportCroppingNonPdf::~DlgImportCroppingNonPdf";
58 
59   delete m_nonPdfCropping;
60 }
61 
createNonPdfCropping()62 void DlgImportCroppingNonPdf::createNonPdfCropping ()
63 {
64   // Create frame that shows what will be included, and what will be excluded, during the import
65   m_nonPdfCropping = new NonPdfCropping (*m_scenePreview,
66                                          *m_viewPreview);
67 }
68 
createPreview(QGridLayout * layout,int & row)69 void DlgImportCroppingNonPdf::createPreview (QGridLayout *layout,
70                                              int &row)
71 {
72   LOG4CPP_INFO_S ((*mainCat)) << "DlgImportCroppingNonPdf::createPreview";
73 
74   QLabel *labelPreview = new QLabel (tr ("Preview"));
75   layout->addWidget (labelPreview, row++, 0, 1, 1, Qt::AlignLeft);
76 
77   m_scenePreview = new QGraphicsScene (this);
78   m_viewPreview = new ViewPreview (m_scenePreview,
79                                    ViewPreview::VIEW_ASPECT_RATIO_ONE_TO_ONE,
80                                    this);
81   m_viewPreview->setWhatsThis (tr ("Preview window that shows what part of the image will be imported. "
82                                    "The image portion inside the rectangular frame will be imported from the currently selected page. "
83                                    "The frame can be moved and resized by dragging the corner handles."));
84   m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
85   m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
86   m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
87   layout->addWidget (m_viewPreview, row++, 0, 1, 4);
88 
89   // More preview initialization
90   initializeFrameGeometryAndPixmap (); // Before first call to updatePreview
91   createNonPdfCropping ();
92 }
93 
finishPanel(QWidget * subPanel)94 void DlgImportCroppingNonPdf::finishPanel (QWidget *subPanel)
95 {
96   const int STRETCH_OFF = 0, STRETCH_ON = 1;
97 
98   QVBoxLayout *panelLayout = new QVBoxLayout (this);
99 
100   setMinimumWidth (MINIMUM_DIALOG_WIDTH);
101   setLayout (panelLayout);
102 
103   panelLayout->addWidget (subPanel);
104   panelLayout->setStretch (panelLayout->count () - 1, STRETCH_ON);
105 
106   QWidget *panelButtons = new QWidget (this);
107   QHBoxLayout *buttonLayout = new QHBoxLayout (panelButtons);
108 
109   QHBoxLayout *layoutRightSide = new QHBoxLayout;
110 
111   QWidget *widgetRightSide = new QWidget;
112   widgetRightSide->setLayout (layoutRightSide);
113   buttonLayout->addWidget (widgetRightSide);
114 
115   QSpacerItem *spacerExpanding = new QSpacerItem (40, 5, QSizePolicy::Expanding, QSizePolicy::Expanding);
116   layoutRightSide->addItem (spacerExpanding);
117 
118   m_btnOk = new QPushButton (tr ("Ok"));
119   layoutRightSide->addWidget (m_btnOk, 0, Qt::AlignRight);
120   connect (m_btnOk, SIGNAL (released ()), this, SLOT (slotOk ()));
121 
122   QSpacerItem *spacerFixed = new QSpacerItem (40, 5, QSizePolicy::Fixed, QSizePolicy::Fixed);
123   layoutRightSide->addItem (spacerFixed);
124 
125   m_btnCancel = new QPushButton (tr ("Cancel"));
126   layoutRightSide->addWidget (m_btnCancel, 0, Qt::AlignRight);
127   connect (m_btnCancel, SIGNAL (released ()), this, SLOT (slotCancel ()));
128 
129   panelLayout->addWidget (panelButtons, STRETCH_ON);
130   panelLayout->setStretch (panelLayout->count () - 1, STRETCH_OFF);
131 }
132 
image() const133 QImage DlgImportCroppingNonPdf::image () const
134 {
135   // If the entire page was to be returned, then this method would simply return m_image. However, only the framed
136   // portion is to be returned
137   ENGAUGE_CHECK_PTR (m_nonPdfCropping);
138   QRectF rectFramePixels = m_nonPdfCropping->frameRect ();
139 
140   return m_image.copy (rectFramePixels.toRect ());
141 }
142 
initializeFrameGeometryAndPixmap()143 void DlgImportCroppingNonPdf::initializeFrameGeometryAndPixmap ()
144 {
145   m_image = loadImage ();
146   QGraphicsPixmapItem *pixmap = new QGraphicsPixmapItem (QPixmap::fromImage (m_image));
147   m_scenePreview->addItem (pixmap);
148 
149   // Force resize so image fills preview area. We do this only once initially for speed
150   m_viewPreview->setSceneRect (pixmap->boundingRect ());
151 }
152 
loadImage() const153 QImage DlgImportCroppingNonPdf::loadImage () const
154 {
155   QImage image;
156   image.load (m_fileName);
157 
158   return image;
159 }
160 
saveGeometryToSettings()161 void DlgImportCroppingNonPdf::saveGeometryToSettings()
162 {
163   // Store the settings for use by showEvent
164   QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
165   settings.beginGroup (SETTINGS_GROUP_IMPORT_CROPPING);
166   settings.setValue (SETTINGS_IMPORT_CROPPING_POS, saveGeometry ());
167   settings.endGroup();
168 }
169 
showEvent(QShowEvent *)170 void DlgImportCroppingNonPdf::showEvent (QShowEvent * /* event */)
171 {
172   QSettings settings (SETTINGS_ENGAUGE, SETTINGS_DIGITIZER);
173   settings.beginGroup (SETTINGS_GROUP_IMPORT_CROPPING);
174   if (settings.contains (SETTINGS_IMPORT_CROPPING_POS)) {
175 
176     // Restore the settings that were stored by the last call to saveGeometryToSettings
177     restoreGeometry (settings.value (SETTINGS_IMPORT_CROPPING_POS).toByteArray ());
178   }
179   settings.endGroup ();
180 }
181 
slotCancel()182 void DlgImportCroppingNonPdf::slotCancel ()
183 {
184   LOG4CPP_INFO_S ((*mainCat)) << "DlgImportCroppingNonPdf::slotCancel";
185 
186   // Restore cursor in case updatePreview has not already completed and then restored it
187   QApplication::restoreOverrideCursor ();
188 
189   setResult (QDialog::Rejected);
190   saveGeometryToSettings();
191   hide();
192 }
193 
slotOk()194 void DlgImportCroppingNonPdf::slotOk ()
195 {
196   LOG4CPP_INFO_S ((*mainCat)) << "DlgImportCroppingNonPdf::slotOk";
197 
198   // Restore cursor in case updatePreview has not already completed and then restored it
199   QApplication::restoreOverrideCursor ();
200 
201   setResult (QDialog::Accepted);
202   saveGeometryToSettings();
203   hide();
204 }
205 
updatePreview()206 void DlgImportCroppingNonPdf::updatePreview ()
207 {
208   LOG4CPP_INFO_S ((*mainCat)) << "DlgImportCroppingNonPdf::updatePreview";
209 
210   if (m_pixmap != nullptr) {
211     m_scenePreview->removeItem (m_pixmap);
212   }
213 
214   m_image = loadImage ();
215   m_pixmap = new QGraphicsPixmapItem (QPixmap::fromImage (m_image));
216   m_scenePreview->addItem (m_pixmap);
217 
218   // Calculations for preview updating are now over
219   QApplication::restoreOverrideCursor ();
220 }
221