1 /* This file is part of the KDE project
2    Copyright (C)  2015 Camilla Boemann <cbo@boemann.dk>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18 */
19 
20 #include "ListLevelWidget.h"
21 
22 #include <kcharselect.h>
23 
24 #include <KoListLevelProperties.h>
25 
26 #include <QPainter>
27 #include <QDebug>
28 #include <QPaintEvent>
29 #include <QGridLayout>
30 
drawMeasureArrow(QPainter & painter,int x,int y,bool pointRight)31 static void drawMeasureArrow(QPainter &painter, int x, int y, bool pointRight)
32 {
33     int const d = 6;
34 
35     painter.drawLine(x, y + d, x, y - d); // |
36 
37     if (pointRight) {
38         --x; // makes arrow more pointy
39         painter.drawLine(x, y, x - d, y + d);
40         painter.drawLine(x, y, x - d, y - d);
41     }  else {
42         ++x; // makes arrow more pointy
43         painter.drawLine(x, y, x + d, y + d);
44         painter.drawLine(x, y, x + d, y - d);
45     }
46 }
47 
48 class LabelDrawingWidget : public QWidget
49 {
50 public:
LabelDrawingWidget()51     LabelDrawingWidget() : QWidget(), m_align(2)
52     {
53     }
54 
setLabelAlign(int a)55     void setLabelAlign(int a)
56     {
57         m_align = a;
58         update();
59     }
60 
61 protected:
paintEvent(QPaintEvent * ev)62     void paintEvent(QPaintEvent *ev) override
63     {
64         QWidget::paintEvent(ev);
65         QPainter painter(this);
66 
67         QPen pen;
68         pen.setWidthF(2.0);
69         painter.setPen(pen);
70 
71         int x = width() / 2 + 30 * (m_align -1);
72 
73         // the |< arrow
74         drawMeasureArrow(painter, x, 5, false);
75         // the - line
76         painter.drawLine(x, 5, width(), 5);
77     }
78 
79     int m_align;
80 };
81 
ListLevelWidget(QWidget * parent)82 ListLevelWidget::ListLevelWidget(QWidget* parent)
83     : QWidget(parent)
84 {
85     widget.setupUi(this);
86 
87     widget.format->addItems(KoOdfNumberDefinition::userFormatDescriptions());
88 
89     QGridLayout *bulletLayout = new QGridLayout();
90     m_charSelect = new KCharSelect(0, 0, KCharSelect::FontCombo | KCharSelect::BlockCombos | KCharSelect::CharacterTable | KCharSelect::DetailBrowser);
91     bulletLayout->addWidget(m_charSelect, 0,0);
92     widget.bulletTab->setLayout(bulletLayout);
93 
94     widget.geometryGrid->addWidget(m_label = new LabelDrawingWidget, 4, 0);
95 
96     connect(widget.format, SIGNAL(currentIndexChanged(int)), this, SLOT(numberFormatChanged(int)));
97     connect(widget.addTabStop, SIGNAL(toggled(bool)), widget.relativeTabStop, SLOT(setEnabled(bool)));
98     connect(widget.labelFollowedBy, SIGNAL(currentIndexChanged(int)), this, SLOT(labelFollowedByChanged(int)));
99     connect(widget.alignment, SIGNAL(currentIndexChanged(int)), this, SLOT(alignmentChanged(int)));
100 }
101 
paintEvent(QPaintEvent * ev)102 void ListLevelWidget::paintEvent(QPaintEvent *ev)
103 {
104     QWidget::paintEvent(ev);
105     QPainter painter(this);
106 
107     QPen pen;
108     pen.setWidthF(2.0);
109     painter.setPen(pen);
110 
111     QRect quickRect = widget.loremIpsum->geometry();
112     int x = 15;
113 
114     // the - line at the bottom
115     painter.drawLine(x, quickRect.bottom() + 15, quickRect.left(), quickRect.bottom() + 15);
116     // the < arrow aligned left side of dialog
117     drawMeasureArrow(painter, x, quickRect.bottom() + 15, false);
118 
119     // the two >| arrows aligned left side of text
120     x = quickRect.left();
121     drawMeasureArrow(painter, x, widget.aboveLoremSpacer->geometry().y() + 5, true);
122     drawMeasureArrow(painter, x, quickRect.bottom() + 15, true);
123 
124     // the | line aligned left side of text
125     painter.drawLine(x, widget.aboveLoremSpacer->geometry().y() + 5, x, quickRect.bottom() + 15);
126 
127     // the |< arrow for tab distance
128     drawMeasureArrow(painter, x, quickRect.bottom() + 15, false);
129     // the - line for tab distance
130     int tabwidth = 80;
131     painter.drawLine(x, quickRect.bottom() + 15, x + tabwidth, quickRect.bottom() + 15);
132     // the | line for tab distance
133     painter.drawLine(x + tabwidth, quickRect.bottom() + 15, x + tabwidth, quickRect.top());
134     // the >| for tab distance
135     drawMeasureArrow(painter, x + tabwidth, quickRect.bottom() + 15, true);
136 }
137 
labelFollowedByChanged(int i)138 void ListLevelWidget::labelFollowedByChanged(int i)
139 {
140     widget.addTabStop->setEnabled(i == 0);
141     widget.relativeTabStop->setEnabled(i == 0 && widget.addTabStop->isChecked());
142 
143     m_labelFollowedByModified = true;
144 }
145 
alignmentChanged(int a)146 void ListLevelWidget::alignmentChanged(int a)
147 {
148     m_label->setLabelAlign(a);
149     m_alignmentModified = true;
150 }
151 
numberFormatChanged(int index)152 void ListLevelWidget::numberFormatChanged(int index)
153 {
154     widget.synchro->setEnabled(index == KoOdfNumberDefinition::AlphabeticLowerCase
155                             || index ==KoOdfNumberDefinition::AlphabeticUpperCase);
156 }
157 
setDisplay(const KoListLevelProperties & props)158 void ListLevelWidget::setDisplay(const KoListLevelProperties &props)
159 {
160     widget.blockIndent->setValue(props.margin());
161     widget.blockIndentIncrease->setValue(props.marginIncrease());
162     widget.distance->setValue(-props.textIndent());
163     widget.alignment->setCurrentIndex(int(props.alignment()));
164     m_label->setLabelAlign(int(props.alignment()));
165     widget.relativeTabStop->setValue(props.tabStopPosition() - props.margin());
166     widget.labelFollowedBy->setCurrentIndex(props.labelFollowedBy());
167     widget.addTabStop->setChecked(props.hasTabStopPosition());
168 
169     if (props.bulletCharacter() != QChar()) {
170         m_charSelect->setCurrentChar(props.bulletCharacter());
171     } else {
172         m_charSelect->setCurrentChar(QChar(0x2022)); // default to bullet
173     }
174 
175     widget.format->setCurrentIndex(props.numberFormat());
176     numberFormatChanged(props.numberFormat()); // enable/disable letterSynch checkbox
177     widget.synchro->setChecked(props.letterSynchronization());
178     widget.prefix->setText(props.listItemPrefix());
179     widget.suffix->setText(props.listItemSuffix());
180     widget.displayLevels->setValue(props.displayLevel());
181 
182     switch(props.labelType()) {
183     case KoListStyle::BulletCharLabelType:
184         widget.tabWidget->setCurrentIndex(1);
185         break;
186     case KoListStyle::ImageLabelType:
187         widget.tabWidget->setCurrentIndex(2);
188         break;
189     default:
190         widget.tabWidget->setCurrentIndex(0);
191         break;
192     }
193 }
194 
save(KoListLevelProperties & props) const195 void ListLevelWidget::save(KoListLevelProperties &props) const
196 {
197     props.setMargin(widget.blockIndent->value());
198     props.setMarginIncrease(widget.blockIndentIncrease->value());
199     props.setTextIndent(-widget.distance->value());
200     props.setTabStopPosition(widget.relativeTabStop->value() + props.margin());
201     props.setLabelFollowedBy(KoListStyle::ListLabelFollowedBy(widget.labelFollowedBy->currentIndex()));
202     if (!widget.addTabStop->isChecked()) {
203         props.clearTabStopPosition();
204     }
205 
206     switch(widget.tabWidget->currentIndex()) {
207     case 0:
208         props.setLabelType(KoListStyle::NumberLabelType);
209         props.setNumberFormat(KoOdfNumberDefinition::FormatSpecification(widget.format->currentIndex()));
210         props.setListItemPrefix(widget.prefix->text());
211         props.setListItemSuffix(widget.suffix->text());
212         props.setLetterSynchronization(widget.synchro->isChecked());
213         props.setDisplayLevel(widget.displayLevels->value());
214         break;
215     case 1:
216         props.setLabelType(KoListStyle::BulletCharLabelType);
217         props.setBulletCharacter(m_charSelect->currentChar());
218         break;
219     case 2:
220         props.setLabelType(KoListStyle::ImageLabelType);
221         break;
222     }
223 }
224