Engauge Digitizer  2
 All Classes Files Functions Variables Enumerations Enumerator Friends Pages
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,
127  ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
128  this);
129  m_viewPreview->setWhatsThis (tr ("Preview window showing the currently selected cursor"));
130  m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
131  m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
132  m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
133 
134  layout->addWidget (m_viewPreview, row++, 0, 1, 4);
135 }
136 
138 {
139  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::createSubPanel";
140 
141  QWidget *subPanel = new QWidget ();
142  QGridLayout *layout = new QGridLayout (subPanel);
143  subPanel->setLayout (layout);
144 
145  layout->setColumnStretch (0, 1); // Empty first column
146  layout->setColumnStretch (1, 0); // Labels
147  layout->setColumnStretch (2, 0); // User controls
148  layout->setColumnStretch (3, 1); // Empty last column
149 
150  int row = 0;
151  createControls(layout, row);
152  createPreview (layout, row);
153 
154  return subPanel;
155 }
156 
158 {
159  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::handleOk";
160 
162  cmdMediator ().document(),
163  *m_modelDigitizeCurveBefore,
164  *m_modelDigitizeCurveAfter);
165  cmdMediator ().push (cmd);
166 
167  hide ();
168 }
169 
171 {
172  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::load";
173 
174  setCmdMediator (cmdMediator);
175 
176  // Flush old data
177  if (m_modelDigitizeCurveBefore != 0) {
178  delete m_modelDigitizeCurveBefore;
179  }
180  if (m_modelDigitizeCurveAfter != 0) {
181  delete m_modelDigitizeCurveAfter;
182  }
183 
184  // Save new data
185  m_modelDigitizeCurveBefore = new DocumentModelDigitizeCurve (cmdMediator.document());
186  m_modelDigitizeCurveAfter = new DocumentModelDigitizeCurve (cmdMediator.document());
187 
188  // Sanity checks. Incoming defaults must be acceptable to the local limits
189  ENGAUGE_ASSERT (INNER_RADIUS_MIN <= m_modelDigitizeCurveAfter->cursorInnerRadius ());
190  ENGAUGE_ASSERT (INNER_RADIUS_MAX >= m_modelDigitizeCurveAfter->cursorInnerRadius ());
191  ENGAUGE_ASSERT (LINE_WIDTH_MIN <= m_modelDigitizeCurveAfter->cursorLineWidth ());
192  ENGAUGE_ASSERT (LINE_WIDTH_MAX >= m_modelDigitizeCurveAfter->cursorLineWidth ());
193 
194  // Populate controls
195  m_btnStandard->setChecked (m_modelDigitizeCurveAfter->cursorStandardCross());
196  m_btnCustom->setChecked (!m_modelDigitizeCurveAfter->cursorStandardCross());
197  m_spinInnerRadius->setValue (m_modelDigitizeCurveAfter->cursorInnerRadius());
198  int index = m_cmbSize->findData (QVariant (m_modelDigitizeCurveAfter->cursorSize()));
199  m_cmbSize->setCurrentIndex (index);
200  m_spinLineWidth->setValue (m_modelDigitizeCurveAfter->cursorLineWidth());
201 
202  updateControls();
203  enableOk (false); // Disable Ok button since there not yet any changes
204  updatePreview();
205 }
206 
207 void DlgSettingsDigitizeCurve::slotCursorCustom (bool)
208 {
209  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorCustom";
210 
211  m_modelDigitizeCurveAfter->setCursorStandardCross(false);
212  updateControls();
213  updatePreview();
214 }
215 
216 void DlgSettingsDigitizeCurve::slotCursorInnerRadius (const QString &)
217 {
218  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorInnerRadius";
219 
220  m_modelDigitizeCurveAfter->setCursorInnerRadius (m_spinInnerRadius->value());
221  updateControls();
222  updatePreview();
223 }
224 
225 void DlgSettingsDigitizeCurve::slotCursorLineWidth (const QString &)
226 {
227  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorLineWidth";
228 
229  m_modelDigitizeCurveAfter->setCursorLineWidth (m_spinLineWidth->value());
230  updateControls();
231  updatePreview();
232 }
233 
234 void DlgSettingsDigitizeCurve::slotCursorSize (const QString &)
235 {
236  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorSize";
237 
238  m_modelDigitizeCurveAfter->setCursorSize ((CursorSize) m_cmbSize->currentData().toInt());
239  updateControls();
240  updatePreview();
241 }
242 
243 void DlgSettingsDigitizeCurve::slotCursorStandard (bool)
244 {
245  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::slotCursorStandard";
246 
247  m_modelDigitizeCurveAfter->setCursorStandardCross(true);
248  updateControls();
249  updatePreview();
250 }
251 
252 void DlgSettingsDigitizeCurve::updateControls()
253 {
254  // Cursor has to fit into current extent
255  bool isGoodState = 2 * (m_modelDigitizeCurveAfter->cursorInnerRadius() + LINE_LENGTH_MIN) <=
256  CursorSizeToPixels (m_modelDigitizeCurveAfter->cursorSize());
257  enableOk (isGoodState);
258 
259  m_spinInnerRadius->setEnabled (m_btnCustom->isChecked());
260  m_cmbSize->setEnabled (m_btnCustom->isChecked());
261  m_spinLineWidth->setEnabled (m_btnCustom->isChecked());
262 }
263 
264 void DlgSettingsDigitizeCurve::updatePreview()
265 {
266  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsDigitizeCurve::updatePreview";
267 
268  CursorFactory cursorFactory;
269  QCursor cursor = cursorFactory.generate (*m_modelDigitizeCurveAfter);
270  m_viewPreview->setCursor (cursor);
271 }
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.