1 /*
2     Copyright © 2008-13 Qtrac Ltd. All rights reserved.
3     This program or module is free software: you can redistribute it
4     and/or modify it under the terms of the GNU General Public License
5     as published by the Free Software Foundation, either version 2 of
6     the License, or (at your option) any later version. This program is
7     distributed in the hope that it will be useful, but WITHOUT ANY
8     WARRANTY; without even the implied warranty of MERCHANTABILITY or
9     FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10     for more details.
11 */
12 
13 #include "generic.hpp"
14 #include "optionsform.hpp"
15 #include <QCheckBox>
16 #include <QColor>
17 #include <QComboBox>
18 #include <QDialogButtonBox>
19 #include <QDoubleSpinBox>
20 #include <QFormLayout>
21 #include <QGroupBox>
22 #include <QPushButton>
23 #include <QSpinBox>
24 #include <QTabWidget>
25 #include <QVBoxLayout>
26 
27 
OptionsForm(QPen * pen,QBrush * brush,qreal * ruleWidth,bool * showToolTips,bool * combineTextHighlighting,int * cacheSize,int * alpha,int * squareSize,QWidget * parent)28 OptionsForm::OptionsForm(QPen *pen, QBrush *brush, qreal *ruleWidth,
29         bool *showToolTips,  bool *combineTextHighlighting,
30         int *cacheSize, int *alpha, int *squareSize, QWidget *parent)
31     : QDialog(parent), m_pen(pen), m_brush(brush), m_ruleWidth(ruleWidth),
32       m_showToolTips(showToolTips),
33       m_combineTextHighlighting(combineTextHighlighting),
34       m_cacheSize(cacheSize), m_alpha(alpha), m_squareSize(squareSize)
35 {
36     this->pen = *m_pen;
37     this->brush = *m_brush;
38 
39     createWidgets();
40     createLayout();
41     createConnections();
42 
43     updateSwatches();
44     updateUi();
45     setWindowTitle(tr("DiffPDF — Options"));
46 }
47 
48 
createWidgets()49 void OptionsForm::createWidgets()
50 {
51     colorComboBox = new QComboBox;
52     foreach (const QString &name, QColor::colorNames()) {
53         QColor color(name);
54         colorComboBox->addItem(colorSwatch(color), name, color);
55     }
56     colorComboBox->setCurrentIndex(colorComboBox->findData(pen.color()));
57 
58     QColor color = pen.color();
59     color.setAlphaF(*m_alpha / 100.0);
60 
61     brushStyleComboBox = new QComboBox;
62     typedef QPair<QString, Qt::BrushStyle> BrushPair;
63     foreach (const BrushPair &pair, QList<BrushPair>()
64             << qMakePair(tr("No Brush"), Qt::NoBrush)
65             << qMakePair(tr("Solid"), Qt::SolidPattern)
66             << qMakePair(tr("Dense #1"), Qt::Dense1Pattern)
67             << qMakePair(tr("Dense #2"), Qt::Dense2Pattern)
68             << qMakePair(tr("Dense #3"), Qt::Dense3Pattern)
69             << qMakePair(tr("Dense #4"), Qt::Dense4Pattern)
70             << qMakePair(tr("Dense #5"), Qt::Dense5Pattern)
71             << qMakePair(tr("Dense #6"), Qt::Dense6Pattern)
72             << qMakePair(tr("Horizontal"), Qt::HorPattern)
73             << qMakePair(tr("Vertical"), Qt::VerPattern)
74             << qMakePair(tr("Cross"), Qt::CrossPattern)
75             << qMakePair(tr("Diagonal /"), Qt::BDiagPattern)
76             << qMakePair(tr("Diagonal \\"), Qt::FDiagPattern)
77             << qMakePair(tr("Diagonal Cross"), Qt::DiagCrossPattern))
78         brushStyleComboBox->addItem(brushSwatch(pair.second, color),
79                                                 pair.first, QVariant::fromValue(pair.second));
80     brushStyleComboBox->setCurrentIndex(brushStyleComboBox->findData(
81                 QVariant::fromValue(brush.style())));
82 
83     penStyleComboBox = new QComboBox;
84     typedef QPair<QString, Qt::PenStyle> PenPair;
85     foreach (const PenPair &pair, QList<PenPair>()
86             << qMakePair(tr("No Pen"), Qt::NoPen)
87             << qMakePair(tr("Solid"), Qt::SolidLine)
88             << qMakePair(tr("Dashed"), Qt::DashLine)
89             << qMakePair(tr("Dotted"), Qt::DotLine)
90             << qMakePair(tr("Dash-Dotted"), Qt::DashDotLine)
91             << qMakePair(tr("Dash-Dot-Dotted"), Qt::DashDotDotLine))
92         penStyleComboBox->addItem(penStyleSwatch(pair.second, color),
93                                   pair.first, QVariant::fromValue(pair.second));
94     penStyleComboBox->setCurrentIndex(penStyleComboBox->findData(
95                 QVariant::fromValue(pen.style())));
96 
97     alphaSpinBox = new QSpinBox;
98     alphaSpinBox->setRange(1, 100);
99     alphaSpinBox->setValue(*m_alpha);
100     alphaSpinBox->setSuffix(tr(" %"));
101     alphaSpinBox->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
102     alphaSpinBox->setToolTip(tr("<p>How opaque the highlighting "
103             "color is. The default is 13%"));
104 
105     squareSizeSpinBox = new QSpinBox;
106     squareSizeSpinBox->setRange(2, 40);
107     squareSizeSpinBox->setValue(*m_squareSize);
108     squareSizeSpinBox->setSuffix(tr(" px"));
109     squareSizeSpinBox->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
110     squareSizeSpinBox->setToolTip(tr("<p>The size of the "
111             "highlighting squares in Appearance mode. Small values are "
112             "more expensive to compute. Large values give coarse "
113             "comparisons. The default is 10 px"));
114 
115     ruleWidthSpinBox = new QDoubleSpinBox;
116     ruleWidthSpinBox->setRange(0.0, 10.0);
117     ruleWidthSpinBox->setDecimals(2);
118     ruleWidthSpinBox->setSingleStep(0.25);
119     ruleWidthSpinBox->setAlignment(Qt::AlignVCenter|Qt::AlignRight);
120     ruleWidthSpinBox->setSpecialValueText(tr("No Rules"));
121     ruleWidthSpinBox->setValue(*m_ruleWidth);
122 
123     showToolTipsCheckBox = new QCheckBox(tr("Show &Tooltips in "
124                                             "the Main Window"));
125     showToolTipsCheckBox->setChecked(*m_showToolTips);
126 
127     combineTextHighlightingCheckBox = new QCheckBox(
128             tr("Combine Highlighting in &Text Modes"));
129     combineTextHighlightingCheckBox->setChecked(
130             *m_combineTextHighlighting);
131 
132     cacheSizeSpinBox = new QSpinBox;
133     cacheSizeSpinBox->setRange(1, 100);
134     cacheSizeSpinBox->setValue(*m_cacheSize);
135     cacheSizeSpinBox->setSuffix(tr(" MB"));
136     cacheSizeSpinBox->setToolTip(tr("<p>The cache is used to store pages "
137             "already seen to make flipping back and forth as fast as "
138             "possible. The bigger the cache the more pages that can be "
139             "stored."));
140 
141     buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|
142                                      QDialogButtonBox::Cancel);
143     tabWidget = new QTabWidget;
144 }
145 
146 
createLayout()147 void OptionsForm::createLayout()
148 {
149     QFormLayout *generalLayout = new QFormLayout;
150     generalLayout->addRow(showToolTipsCheckBox);
151     generalLayout->addRow(tr("&Rule width:"), ruleWidthSpinBox);
152     QWidget *widget = new QWidget;
153     widget->setLayout(generalLayout);
154     tabWidget->addTab(widget, tr("&General"));
155 
156     QFormLayout *highlightingLayout = new QFormLayout;
157     highlightingLayout->addRow(tr("&Base Color:"), colorComboBox);
158     highlightingLayout->addRow(tr("O&utline:"), penStyleComboBox);
159     highlightingLayout->addRow(tr("&Fill:"), brushStyleComboBox);
160     highlightingLayout->addRow(tr("F&ill Opacity:"), alphaSpinBox);
161     highlightingLayout->addRow(combineTextHighlightingCheckBox);
162     widget = new QWidget;
163     widget->setToolTip(tr("<p>The outline and fill are used to highlight "
164             "differences using a semi-transparent version of the base "
165             "color. The margin rules are painted using the base color  "
166             "and indicate where changes are. Set the rule width to 0.0 "
167             "to switch the rules off. If combining highlighting is "
168             "checked it will try to merge the highlighting of adjacent "
169             "text differences."));
170     widget->setLayout(highlightingLayout);
171     tabWidget->addTab(widget, tr("&Highlighting"));
172 
173     QFormLayout *performanceLayout = new QFormLayout;
174     performanceLayout->addRow(tr("&Square Size:"), squareSizeSpinBox);
175     performanceLayout->addRow(tr("C&ache Size:"), cacheSizeSpinBox);
176     widget = new QWidget;
177     widget->setLayout(performanceLayout);
178     tabWidget->addTab(widget, tr("&Performance"));
179 
180     QVBoxLayout *layout = new QVBoxLayout;
181     layout->addWidget(tabWidget);
182     layout->addWidget(buttonBox);
183     setLayout(layout);
184 }
185 
186 
createConnections()187 void OptionsForm::createConnections()
188 {
189     connect(colorComboBox, SIGNAL(currentIndexChanged(int)),
190             this, SLOT(updateColor(int)));
191     connect(penStyleComboBox, SIGNAL(currentIndexChanged(int)),
192             this, SLOT(updatePenStyle(int)));
193     connect(penStyleComboBox, SIGNAL(currentIndexChanged(int)),
194             this, SLOT(updateUi()));
195     connect(brushStyleComboBox, SIGNAL(currentIndexChanged(int)),
196             this, SLOT(updateBrushStyle(int)));
197     connect(brushStyleComboBox, SIGNAL(currentIndexChanged(int)),
198             this, SLOT(updateUi()));
199     connect(alphaSpinBox, SIGNAL(valueChanged(int)),
200             this, SLOT(updateSwatches()));
201     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
202     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
203 }
204 
205 
updateColor(int index)206 void OptionsForm::updateColor(int index)
207 {
208     QColor color = colorComboBox->itemData(index).value<QColor>();
209     brush.setColor(color);
210     pen.setColor(color);
211     updateSwatches();
212 }
213 
214 
updatePenStyle(int index)215 void OptionsForm::updatePenStyle(int index)
216 {
217     pen.setStyle(static_cast<Qt::PenStyle>(
218                  penStyleComboBox->itemData(index).toInt()));
219 }
220 
221 
updateBrushStyle(int index)222 void OptionsForm::updateBrushStyle(int index)
223 {
224     brush.setStyle(static_cast<Qt::BrushStyle>(
225                    brushStyleComboBox->itemData(index).toInt()));
226 }
227 
228 
updateSwatches()229 void OptionsForm::updateSwatches()
230 {
231     QColor color = colorComboBox->itemData(
232             colorComboBox->currentIndex()).value<QColor>();
233     color.setAlphaF(alphaSpinBox->value() / 100.0);
234     for (int i = 0; i < brushStyleComboBox->count(); ++i)
235         brushStyleComboBox->setItemIcon(i, brushSwatch(
236                 static_cast<Qt::BrushStyle>(
237                     brushStyleComboBox->itemData(i).toInt()), color));
238     for (int i = 0; i < penStyleComboBox->count(); ++i)
239         penStyleComboBox->setItemIcon(i, penStyleSwatch(
240                 static_cast<Qt::PenStyle>(
241                     penStyleComboBox->itemData(i).toInt()), color));
242 }
243 
244 
updateUi()245 void OptionsForm::updateUi()
246 {
247     Qt::BrushStyle brushStyle = static_cast<Qt::BrushStyle>(
248             brushStyleComboBox->itemData(
249                     brushStyleComboBox->currentIndex()).toInt());
250     Qt::PenStyle penStyle = static_cast<Qt::PenStyle>(
251             penStyleComboBox->itemData(
252                     penStyleComboBox->currentIndex()).toInt());
253     buttonBox->button(QDialogButtonBox::Ok)->setEnabled(
254             !(brushStyle == Qt::NoBrush && penStyle == Qt::NoPen));
255 }
256 
257 
accept()258 void OptionsForm::accept()
259 {
260     *m_pen = pen;
261     *m_brush = brush;
262     *m_ruleWidth = ruleWidthSpinBox->value();
263     *m_showToolTips = showToolTipsCheckBox->isChecked();
264     *m_combineTextHighlighting =
265             combineTextHighlightingCheckBox->isChecked();
266     *m_cacheSize = cacheSizeSpinBox->value();
267     *m_alpha = alphaSpinBox->value();
268     *m_squareSize = squareSizeSpinBox->value();
269     QDialog::accept();
270 }
271