1 /* This file is part of the KDE project
2 * Copyright (C) 2007, 2009 Thomas Zander <zander@kde.org>
3 * Copyright (c) 2003 David Faure <faure@kde.org>
4 * Copyright (C) 2011 Mojtaba Shahi Senobari <mojtaba.shahi3000@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include "ParagraphIndentSpacing.h"
23
24 #include <KoParagraphStyle.h>
25 #include <QDebug>
26
ParagraphIndentSpacing(QWidget * parent)27 ParagraphIndentSpacing::ParagraphIndentSpacing(QWidget *parent)
28 : QWidget(parent),
29 m_fontMetricsChecked(false)
30 {
31 widget.setupUi(this);
32
33 connect(widget.first, SIGNAL(valueChangedPt(qreal)), this, SLOT(firstLineMarginChanged(qreal)));
34 connect(widget.left, SIGNAL(valueChangedPt(qreal)), this, SLOT(leftMarginChanged(qreal)));
35 connect(widget.right, SIGNAL(valueChangedPt(qreal)), this, SLOT(rightMarginChanged(qreal)));
36
37 // Keep order in sync with lineSpacingType() and display()
38 widget.lineSpacing->addItem(i18nc("Line spacing value", "Single"));
39 widget.lineSpacing->addItem(i18nc("Line spacing value", "1.5 Lines"));
40 widget.lineSpacing->addItem(i18nc("Line spacing value", "Double"));
41 widget.lineSpacing->addItem(i18nc("Line spacing type", "Proportional")); // called Proportional like in OO
42 widget.lineSpacing->addItem(i18nc("Line spacing type", "Additional")); // normal distance + absolute value
43 widget.lineSpacing->addItem(i18nc("Line spacing type", "Fixed"));
44 widget.lineSpacing->addItem(i18nc("Line spacing type", "At least"));
45
46 connect(widget.first, SIGNAL(valueChangedPt(qreal)), this, SLOT(firstIndentValueChanged()));
47 connect(widget.left, SIGNAL(valueChangedPt(qreal)), this, SLOT(leftMarginValueChanged()));
48 connect(widget.right, SIGNAL(valueChangedPt(qreal)), this, SLOT(rightMarginValueChanged()));
49 connect(widget.after, SIGNAL(valueChangedPt(qreal)), this, SLOT(bottomMarginValueChanged()));
50 connect(widget.before, SIGNAL(valueChangedPt(qreal)), this, SLOT(topMarginValueChanged()));
51 connect(widget.lineSpacing, SIGNAL(currentIndexChanged(int)), this, SLOT(lineSpacingChanged(int)));
52 connect(widget.useFont, SIGNAL(toggled(bool)), this, SLOT(useFontMetrices(bool)));
53 connect(widget.autoTextIndent, SIGNAL(stateChanged(int)), this, SLOT(autoTextIndentChanged(int)));
54 connect(widget.proportional, SIGNAL(valueChanged(int)), this, SLOT(spacingPercentChanged()));
55 connect(widget.custom, SIGNAL(valueChangedPt(qreal)), this, SLOT(spacingValueChanged()));
56 lineSpacingChanged(0);
57 }
58
autoTextIndentChanged(int state)59 void ParagraphIndentSpacing::autoTextIndentChanged(int state)
60 {
61 widget.first->setEnabled(state == Qt::Unchecked);
62 m_autoTextIndentInherited = false;
63 emit parStyleChanged();
64 }
firstIndentValueChanged()65 void ParagraphIndentSpacing::firstIndentValueChanged()
66 {
67 m_textIndentInherited = false;
68 emit parStyleChanged();
69 }
70
rightMarginValueChanged()71 void ParagraphIndentSpacing::rightMarginValueChanged()
72 {
73 m_rightMarginIngerited = false;
74 emit parStyleChanged();
75 }
76
leftMarginValueChanged()77 void ParagraphIndentSpacing::leftMarginValueChanged()
78 {
79 m_leftMarginInherited = false;
80 emit parStyleChanged();
81 }
82
topMarginValueChanged()83 void ParagraphIndentSpacing::topMarginValueChanged()
84 {
85 m_topMarginInherited = false;
86 emit parStyleChanged();
87 }
88
bottomMarginValueChanged()89 void ParagraphIndentSpacing::bottomMarginValueChanged()
90 {
91 m_bottomMarginInherited = false;
92 emit parStyleChanged();
93 }
94
setDisplay(KoParagraphStyle * style,bool directFormattingMode)95 void ParagraphIndentSpacing::setDisplay(KoParagraphStyle *style, bool directFormattingMode)
96 {
97 m_style = style;
98 // TODO : handle relatives
99 widget.first->changeValue(style->textIndent());
100 widget.left->changeValue(style->leftMargin());
101 widget.right->changeValue(style->rightMargin());
102 widget.before->changeValue(style->topMargin());
103 widget.after->changeValue(style->bottomMargin());
104
105 m_rightMarginIngerited = directFormattingMode || !style->hasProperty(QTextFormat::BlockRightMargin);
106 m_leftMarginInherited = directFormattingMode || !style->hasProperty(QTextFormat::BlockLeftMargin);
107 m_topMarginInherited = directFormattingMode || !style->hasProperty(QTextFormat::BlockTopMargin);
108 m_bottomMarginInherited = directFormattingMode || !style->hasProperty(QTextFormat::BlockBottomMargin);
109 m_autoTextIndentInherited = directFormattingMode || !style->hasProperty(KoParagraphStyle::AutoTextIndent);
110 m_textIndentInherited = directFormattingMode || !style->hasProperty(QTextFormat::TextIndent);
111
112 widget.autoTextIndent->setChecked(style->autoTextIndent());
113
114 m_spacingInherited = !(style->hasProperty(KoParagraphStyle::FixedLineHeight) || style->hasProperty(KoParagraphStyle::LineSpacing) || style->hasProperty(KoParagraphStyle::PercentLineHeight) ||style->hasProperty(KoParagraphStyle::MinimumLineHeight));
115
116 int index;
117 if (style->hasProperty(KoParagraphStyle::FixedLineHeight) && style->lineHeightAbsolute() != 0) {
118 // this is the strongest; if this is set we don't care what other properties there are.
119 index = 5;
120 } else if (style->hasProperty(KoParagraphStyle::LineSpacing) && style->lineSpacing() != 0) {
121 // if LineSpacing is set then percent is ignored.
122 index = 4;
123 } else if (style->hasProperty(KoParagraphStyle::PercentLineHeight) && style->lineHeightPercent() != 0) {
124 int percent = style->lineHeightPercent();
125 if (percent == 100)
126 index = 0; // single
127 else if (percent == 150)
128 index = 1; // 1.5
129 else if (percent == 200)
130 index = 2; // double
131 else
132 index = 3; // proportional
133 } else if (style->hasProperty(KoParagraphStyle::MinimumLineHeight) && style->minimumLineHeight() != 0) {
134 index = 6;
135 } else {
136 index = 0; // nothing set, default is 'single' just like for geeks.
137 }
138 widget.lineSpacing->setCurrentIndex(index);
139 //widget.minimumLineSpacing->changeValue(style->minimumLineHeight());
140 widget.useFont->setChecked(style->lineSpacingFromFont());
141 m_fontMetricsChecked = style->lineSpacingFromFont();
142 }
143
lineSpacingChanged(int row)144 void ParagraphIndentSpacing::lineSpacingChanged(int row)
145 {
146 bool percent = false, custom = false;
147 qreal customValue = 0.0;
148 switch (row) {
149 case 0:
150 case 1:
151 case 2:
152 break;
153 case 3: // proportional
154 percent = true;
155 widget.proportional->setValue(m_style->lineHeightPercent());
156 break;
157 case 4: // additional
158 custom = true;
159 customValue = qMax(qreal(0.1), m_style->lineSpacing());
160 break;
161 case 5: // fixed
162 custom = true;
163 if (m_style->lineHeightAbsolute() == 0) // unset
164 customValue = 12.0; // nice default value...
165 else
166 customValue = m_style->lineHeightAbsolute();
167 break;
168 case 6: // minimum
169 custom = true;
170 customValue = m_style->minimumLineHeight();
171 break;
172 default:; // other cases don't need the spinboxes
173 }
174
175 m_spacingInherited = false;
176
177 if (custom) {
178 widget.custom->setEnabled(true);
179 widget.spacingStack->setCurrentWidget(widget.unitsPage);
180 widget.custom->changeValue(customValue);
181 } else {
182 widget.spacingStack->setCurrentWidget(widget.percentPage);
183 widget.proportional->setEnabled(percent);
184 if (! percent)
185 widget.proportional->setValue(100);
186 }
187
188 widget.useFont->setEnabled(row != 5);
189 widget.useFont->setChecked(row == 5 ? false : m_fontMetricsChecked);
190 emit parStyleChanged();
191 }
192
spacingPercentChanged()193 void ParagraphIndentSpacing::spacingPercentChanged()
194 {
195 m_spacingInherited = false;
196 emit parStyleChanged();
197 }
198
spacingValueChanged()199 void ParagraphIndentSpacing::spacingValueChanged()
200 {
201 m_spacingInherited = false;
202 emit parStyleChanged();
203 }
204
save(KoParagraphStyle * style)205 void ParagraphIndentSpacing::save(KoParagraphStyle *style)
206 {
207 // general note; we have to unset values by setting it to zero instead of removing the item
208 // since this dialog may be used on a copy style, which will be applied later. And removing
209 // items doesn't work for that.
210 if (!m_textIndentInherited){
211 style->setTextIndent(QTextLength(QTextLength::FixedLength, widget.first->value()));
212 }
213 if (!m_leftMarginInherited){
214 style->setLeftMargin(QTextLength(QTextLength::FixedLength, widget.left->value()));
215 }
216 if (!m_rightMarginIngerited){
217 style->setRightMargin(QTextLength(QTextLength::FixedLength, widget.right->value()));
218 }
219 if (!m_topMarginInherited){
220 style->setTopMargin(QTextLength(QTextLength::FixedLength, widget.before->value()));
221 }
222 if (!m_bottomMarginInherited){
223 style->setBottomMargin(QTextLength(QTextLength::FixedLength, widget.after->value()));
224 }
225 if (!m_autoTextIndentInherited){
226 style->setAutoTextIndent(widget.autoTextIndent->isChecked());
227 }
228 if (!m_spacingInherited) {
229 style->setLineHeightAbsolute(0); // since it trumps percentage based line heights, unset it.
230 style->setMinimumLineHeight(QTextLength(QTextLength::FixedLength, 0));
231 style->setLineSpacing(0);
232 switch (widget.lineSpacing->currentIndex()) {
233 case 0: style->setLineHeightPercent(100); break;
234 case 1: style->setLineHeightPercent(150); break;
235 case 2: style->setLineHeightPercent(200); break;
236 case 3: style->setLineHeightPercent(widget.proportional->value()); break;
237 case 4:
238 if (widget.custom->value() == 0.0) { // then we need to save it differently.
239 style->setLineHeightPercent(100);
240 } else {
241 style->setLineSpacing(widget.custom->value());
242 }
243 break;
244 case 5:
245 style->setLineHeightAbsolute(widget.custom->value());
246 break;
247 case 6:
248 style->setMinimumLineHeight(QTextLength(QTextLength::FixedLength, widget.custom->value()));
249 break;
250 }
251 style->setLineSpacingFromFont(widget.lineSpacing->currentIndex() != 5 && widget.useFont->isChecked());
252 }
253 }
254
setUnit(const KoUnit & unit)255 void ParagraphIndentSpacing::setUnit(const KoUnit &unit)
256 {
257 widget.first->setUnit(unit);
258 widget.left->setUnit(unit);
259 widget.right->setUnit(unit);
260 widget.before->setUnit(unit);
261 widget.after->setUnit(unit);
262 widget.custom->setUnit(unit);
263 }
264
useFontMetrices(bool on)265 void ParagraphIndentSpacing::useFontMetrices(bool on)
266 {
267 if (widget.lineSpacing->currentIndex() != 5)
268 m_fontMetricsChecked = on;
269 emit parStyleChanged();
270 }
271
firstLineMarginChanged(qreal margin)272 void ParagraphIndentSpacing::firstLineMarginChanged(qreal margin)
273 {
274 Q_UNUSED(margin);
275 emit parStyleChanged();
276 }
277
leftMarginChanged(qreal margin)278 void ParagraphIndentSpacing::leftMarginChanged(qreal margin)
279 {
280 Q_UNUSED(margin);
281 emit parStyleChanged();
282 }
283
rightMarginChanged(qreal margin)284 void ParagraphIndentSpacing::rightMarginChanged(qreal margin)
285 {
286 Q_UNUSED(margin);
287 emit parStyleChanged();
288 }
289