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