Engauge Digitizer  2
DlgSettingsDigitizeCurve.cpp
1 #include "CmdMediator.h"
2 #include "CmdSettingsDigitizeCurve.h"
3 #include "CursorFactory.h"
4 #include "CursorSize.h"
5 #include "DlgSettingsDigitizeCurve.h"
6 #include "DocumentModelDigitizeCurve.h"
7 #include "EngaugeAssert.h"
8 #include "Logger.h"
9 #include "MainWindow.h"
10 #include "PointStyle.h"
11 #include <QCheckBox>
12 #include <QComboBox>
13 #include <QGraphicsPixmapItem>
14 #include <QGridLayout>
15 #include <QGraphicsScene>
16 #include <QGroupBox>
17 #include <QLabel>
18 #include <qmath.h>
19 #include <QRadioButton>
20 #include <QSpinBox>
21 #include "Segment.h"
22 #include "SegmentFactory.h"
23 #include "ViewPreview.h"
24 
25 const int IMAGE_WIDTH = 100;
26 const int IMAGE_HEIGHT = 100;
27 
28 const int INNER_RADIUS_MAX = 64;
29 const int INNER_RADIUS_MIN = 0;
30 const int LINE_LENGTH_MIN = 2; // Min length of one line in the cursor, in pixels
31 const int LINE_WIDTH_MAX = 32;
32 const int LINE_WIDTH_MIN = 1;
33 
35  DlgSettingsAbstractBase ("Digitize Curve",
36  "DlgSettingsDigitizeCurve",
37  mainWindow),
38  m_scenePreview (0),
39  m_viewPreview (0),
40  m_modelDigitizeCurveBefore (0),
41  m_modelDigitizeCurveAfter (0)
42 {
43  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::DlgSettingsDigitizeCurve";
44 
45  QWidget *subPanel = createSubPanel ();
46  finishPanel (subPanel);
47 }
48 
49 DlgSettingsDigitizeCurve::~DlgSettingsDigitizeCurve()
50 {
51  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::~DlgSettingsDigitizeCurve";
52 }
53 
54 void DlgSettingsDigitizeCurve::createControls (QGridLayout *layout,
55  int &row)
56 {
57  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createControls";
58 
59  m_boxCursor = new QGroupBox ("Cursor");
60  layout->addWidget (m_boxCursor, row++, 1, 1, 2);
61 
62  // Layout inside cursor group box
63  QGridLayout *layoutCursor = new QGridLayout;
64  m_boxCursor->setLayout (layoutCursor);
65  int rowCursor = 0;
66 
67  QLabel *labelCursorType = new QLabel("Type:");
68  layoutCursor->addWidget (labelCursorType, rowCursor, 0);
69 
70  m_btnStandard = new QRadioButton ("Standard cross");
71  m_btnStandard->setWhatsThis (tr ("Selects the standard cross cursor"));
72  layoutCursor->addWidget (m_btnStandard, rowCursor++, 1);
73  connect (m_btnStandard, SIGNAL (toggled (bool)), this, SLOT (slotCursorStandard(bool)));
74 
75  m_btnCustom = new QRadioButton ("Custom cross");
76  m_btnCustom->setWhatsThis (tr ("Selects a custom cursor based on the settings selected below"));
77  layoutCursor->addWidget (m_btnCustom, rowCursor++, 1);
78  connect (m_btnCustom, SIGNAL (toggled (bool)), this, SLOT (slotCursorCustom(bool)));
79 
80  QLabel *labelSize = new QLabel("Size (pixels):");
81  layoutCursor->addWidget (labelSize, rowCursor, 0);
82 
83  m_cmbSize = new QComboBox;
84  m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_16)), QVariant (CURSOR_SIZE_16));
85  m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_32)), QVariant (CURSOR_SIZE_32));
86  m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_48)), QVariant (CURSOR_SIZE_48));
87  m_cmbSize->addItem (QString::number (CursorSizeToPixels (CURSOR_SIZE_64)), QVariant (CURSOR_SIZE_64));
88  ENGAUGE_ASSERT (m_cmbSize->count() == NUM_CURSOR_SIZES);
89  m_cmbSize->setWhatsThis (tr ("Horizontal and vertical size of the cursor in pixels"));
90  layoutCursor->addWidget (m_cmbSize, rowCursor++, 1);
91  connect (m_cmbSize, SIGNAL (currentIndexChanged (const QString &)), this, SLOT (slotCursorSize (const QString &)));
92 
93  QLabel *labelInnerRadius = new QLabel("Inner radius (pixels):");
94  layoutCursor->addWidget (labelInnerRadius, rowCursor, 0);
95 
96  m_spinInnerRadius = new QSpinBox;
97  m_spinInnerRadius->setRange (INNER_RADIUS_MIN, INNER_RADIUS_MAX);
98  m_spinInnerRadius->setWhatsThis (tr ("Radius of circle at the center of the cursor that will remain empty"));
99  layoutCursor->addWidget (m_spinInnerRadius, rowCursor++, 1);
100  connect (m_spinInnerRadius, SIGNAL (valueChanged(const QString &)), this, SLOT (slotCursorInnerRadius (const QString &)));
101 
102  QLabel *labelLineWidth = new QLabel("Line width (pixels):");
103  layoutCursor->addWidget (labelLineWidth, rowCursor, 0);
104 
105  m_spinLineWidth = new QSpinBox;
106  m_spinLineWidth->setRange (LINE_WIDTH_MIN, LINE_WIDTH_MAX);
107  m_spinLineWidth->setWhatsThis (tr ("Width of each arm of the cross of the cursor"));
108  layoutCursor->addWidget (m_spinLineWidth, rowCursor++, 1);
109  connect (m_spinLineWidth, SIGNAL (valueChanged(const QString &)), this, SLOT (slotCursorLineWidth (const QString &)));
110 }
111 
112 void DlgSettingsDigitizeCurve::createPreview (QGridLayout *layout,
113  int &row)
114 {
115  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createPreview";
116 
117  QLabel *labelPreview = new QLabel ("Preview");
118  layout->addWidget (labelPreview, row++, 0, 1, 4);
119 
120  m_scenePreview = new QGraphicsScene (this);
121  m_scenePreview->setSceneRect(0,
122  0,
123  IMAGE_WIDTH,
124  IMAGE_HEIGHT);
125 
126  m_viewPreview = new ViewPreview (m_scenePreview, this);
127  m_viewPreview->setWhatsThis (tr ("Preview window showing the currently selected cursor"));
128  m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
129  m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
130  m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
131 
132  layout->addWidget (m_viewPreview, row++, 0, 1, 4);
133 }
134 
136 {
137  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createSubPanel";
138 
139  QWidget *subPanel = new QWidget ();
140  QGridLayout *layout = new QGridLayout (subPanel);
141  subPanel->setLayout (layout);
142 
143  layout->setColumnStretch (0, 1); // Empty first column
144  layout->setColumnStretch (1, 0); // Labels
145  layout->setColumnStretch (2, 0); // User controls
146  layout->setColumnStretch (3, 1); // Empty last column
147 
148  int row = 0;
149  createControls(layout, row);
150  createPreview (layout, row);
151 
152  return subPanel;
153 }
154 
156 {
157  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::handleOk";
158 
160  cmdMediator ().document(),
161  *m_modelDigitizeCurveBefore,
162  *m_modelDigitizeCurveAfter);
163  cmdMediator ().push (cmd);
164 
165  hide ();
166 }
167 
169 {
170  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::load";
171 
172  setCmdMediator (cmdMediator);
173 
174  // Flush old data
175  if (m_modelDigitizeCurveBefore != 0) {
176  delete m_modelDigitizeCurveBefore;
177  }
178  if (m_modelDigitizeCurveAfter != 0) {
179  delete m_modelDigitizeCurveAfter;
180  }
181 
182  // Save new data
183  m_modelDigitizeCurveBefore = new DocumentModelDigitizeCurve (cmdMediator.document());
184  m_modelDigitizeCurveAfter = new DocumentModelDigitizeCurve (cmdMediator.document());
185 
186  // Sanity checks. Incoming defaults must be acceptable to the local limits
187  ENGAUGE_ASSERT (INNER_RADIUS_MIN <= m_modelDigitizeCurveAfter->cursorInnerRadius ());
188  ENGAUGE_ASSERT (INNER_RADIUS_MAX >= m_modelDigitizeCurveAfter->cursorInnerRadius ());
189  ENGAUGE_ASSERT (LINE_WIDTH_MIN <= m_modelDigitizeCurveAfter->cursorLineWidth ());
190  ENGAUGE_ASSERT (LINE_WIDTH_MAX >= m_modelDigitizeCurveAfter->cursorLineWidth ());
191 
192  // Populate controls
193  m_btnStandard->setChecked (m_modelDigitizeCurveAfter->cursorStandardCross());
194  m_btnCustom->setChecked (!m_modelDigitizeCurveAfter->cursorStandardCross());
195  m_spinInnerRadius->setValue (m_modelDigitizeCurveAfter->cursorInnerRadius());
196  int index = m_cmbSize->findData (QVariant (m_modelDigitizeCurveAfter->cursorSize()));
197  m_cmbSize->setCurrentIndex (index);
198  m_spinLineWidth->setValue (m_modelDigitizeCurveAfter->cursorLineWidth());
199 
200  updateControls();
201  enableOk (false); // Disable Ok button since there not yet any changes
202  updatePreview();
203 }
204 
205 void DlgSettingsDigitizeCurve::slotCursorCustom (bool)
206 {
207  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorCustom";
208 
209  m_modelDigitizeCurveAfter->setCursorStandardCross(false);
210  updateControls();
211  updatePreview();
212 }
213 
214 void DlgSettingsDigitizeCurve::slotCursorInnerRadius (const QString &)
215 {
216  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorInnerRadius";
217 
218  m_modelDigitizeCurveAfter->setCursorInnerRadius (m_spinInnerRadius->value());
219  updateControls();
220  updatePreview();
221 }
222 
223 void DlgSettingsDigitizeCurve::slotCursorLineWidth (const QString &)
224 {
225  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorLineWidth";
226 
227  m_modelDigitizeCurveAfter->setCursorLineWidth (m_spinLineWidth->value());
228  updateControls();
229  updatePreview();
230 }
231 
232 void DlgSettingsDigitizeCurve::slotCursorSize (const QString &)
233 {
234  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorSize";
235 
236  m_modelDigitizeCurveAfter->setCursorSize ((CursorSize) m_cmbSize->currentData().toInt());
237  updateControls();
238  updatePreview();
239 }
240 
241 void DlgSettingsDigitizeCurve::slotCursorStandard (bool)
242 {
243  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorStandard";
244 
245  m_modelDigitizeCurveAfter->setCursorStandardCross(true);
246  updateControls();
247  updatePreview();
248 }
249 
250 void DlgSettingsDigitizeCurve::updateControls()
251 {
252  // Cursor has to fit into current extent
253  bool isGoodState = 2 * (m_modelDigitizeCurveAfter->cursorInnerRadius() + LINE_LENGTH_MIN) <=
254  CursorSizeToPixels (m_modelDigitizeCurveAfter->cursorSize());
255  enableOk (isGoodState);
256 
257  m_spinInnerRadius->setEnabled (m_btnCustom->isChecked());
258  m_cmbSize->setEnabled (m_btnCustom->isChecked());
259  m_spinLineWidth->setEnabled (m_btnCustom->isChecked());
260 }
261 
262 void DlgSettingsDigitizeCurve::updatePreview()
263 {
264  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::updatePreview";
265 
266  CursorFactory cursorFactory;
267  QCursor cursor = cursorFactory.generate (*m_modelDigitizeCurveAfter);
268  m_viewPreview->setCursor (cursor);
269 }
DlgSettingsDigitizeCurve(MainWindow &mainWindow)
Single constructor.
int cursorLineWidth() const
Get method for cursor line width.
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
Create standard cross cursor, or custom cursor, according to settings.
Definition: CursorFactory.h:9
void setCursorLineWidth(int lineWidth)
Set method for cursor line width.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
virtual void handleOk()
Process slotOk.
bool cursorStandardCross() const
Get method for cursor type.
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:61
void setCursorSize(CursorSize cursorSize)
Set method for cursor size.
Model for DlgSettingsDigitizeCurve and CmdSettingsDigitizeCurve.
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window...
Definition: ViewPreview.h:8
int cursorInnerRadius() const
Get method for cursor inner radius.
void setCursorInnerRadius(int innerRadius)
Set method for cursor inner radius.
void finishPanel(QWidget *subPanel)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
CursorSize cursorSize() const
Get method for cursor size.
Command for DlgSettingsDigitizeCurve.
Command queue stack.
Definition: CmdMediator.h:16
Abstract base class for all Settings dialogs.
QCursor generate(const DocumentModelDigitizeCurve &modelDigitizeCurve) const
Factory method to generate standard or custom cursor.
MainWindow & mainWindow()
Get method for MainWindow.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:60
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.
void setCursorStandardCross(bool cursorStandardCross)
Set method for cursor type.