]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiParagraph.cpp
11c43934771126780323bb4bf82db1825ac44cd0
[lyx.git] / src / frontends / qt4 / GuiParagraph.cpp
1 /**
2  * \file GuiParagraph.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Edwin Leuven
7  * \author Richard Heck
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "GuiParagraph.h"
15
16 #include "ControlParagraph.h"
17
18 #include "debug.h"
19 #include "frontend_helpers.h"
20 #include "ParagraphParameters.h"
21 #include "qt_helpers.h"
22 #include "Spacing.h"
23
24 #include <QCheckBox>
25 #include <QCloseEvent>
26 #include <QLineEdit>
27 #include <QPushButton>
28
29 #include <boost/current_function.hpp>
30
31 using std::string;
32 using std::endl;
33
34 namespace lyx {
35 namespace frontend {
36
37 GuiParagraphDialog::GuiParagraphDialog(LyXView & lv)
38         : GuiDialog(lv, "paragraph")
39 {
40         setupUi(this);
41         setViewTitle(_("Paragraph Settings"));
42         setController(new ControlParagraph(*this));
43
44         connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
45         connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
46         connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
47         connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
48         connect(alignDefaultRB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
49         connect(alignJustRB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
50         connect(alignLeftRB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
51         connect(alignRightRB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
52         connect(alignCenterRB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
53         connect(linespacing, SIGNAL(activated(int)), this, SLOT(change_adaptor()));
54         connect(linespacing, SIGNAL(activated(int)),
55                 this, SLOT(enableLinespacingValue(int)));
56         connect(linespacingValue, SIGNAL(textChanged(const QString &)),
57                 this, SLOT(change_adaptor()));
58         connect(indentCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
59         connect(labelWidth, SIGNAL(textChanged(const QString &)),
60                 this, SLOT(change_adaptor()));
61
62         linespacingValue->setValidator(new QDoubleValidator(linespacingValue));
63
64         labelWidth->setWhatsThis( qt_(
65                 "As described in the User Guide, the width of"
66                 " this text determines the width of the label part"
67                 " of each item in environments like List and"
68                 " Description.\n"
69                 "\n"
70                 " Normally, you won't need to set this,"
71                 " since the largest label width of all the"
72                 " items is used."
73         ));
74
75         radioMap[LYX_ALIGN_LAYOUT] = alignDefaultRB;
76         radioMap[LYX_ALIGN_BLOCK]  = alignJustRB;
77         radioMap[LYX_ALIGN_LEFT]   = alignLeftRB;
78         radioMap[LYX_ALIGN_RIGHT]  = alignRightRB;
79         radioMap[LYX_ALIGN_CENTER] = alignCenterRB;
80         
81         labelMap[LYX_ALIGN_LAYOUT] = _("Use Paragraph's Default Alignment");
82         labelMap[LYX_ALIGN_BLOCK]  = _("Justified");
83         labelMap[LYX_ALIGN_LEFT]   = _("Left");
84         labelMap[LYX_ALIGN_RIGHT]  = _("Right");
85         labelMap[LYX_ALIGN_CENTER] = _("Center");
86
87         bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy);
88         bc().setOK(okPB);
89         bc().setApply(applyPB);
90         bc().setCancel(closePB);
91         bc().setRestore(restorePB);
92 }
93
94
95 ControlParagraph & GuiParagraphDialog::controller()
96 {
97         return static_cast<ControlParagraph &>(GuiDialog::controller());
98 }
99
100
101 void GuiParagraphDialog::closeEvent(QCloseEvent * e)
102 {
103         slotClose();
104         e->accept();
105 }
106
107
108 void GuiParagraphDialog::change_adaptor()
109 {
110         changed();
111 }
112
113
114 void GuiParagraphDialog::enableLinespacingValue(int)
115 {
116         bool const enable = linespacing->currentIndex() == 4;
117         linespacingValue->setEnabled(enable);
118 }
119
120
121 void GuiParagraphDialog::checkAlignmentRadioButtons() {
122         LyXAlignment const alignPossible = controller().alignPossible();
123
124         RadioMap::iterator it = radioMap.begin();
125         for (; it != radioMap.end(); ++it) {
126                 LyXAlignment const align = it->first;
127                 it->second->setEnabled(align & alignPossible);
128         }
129         docstring label = labelMap[LYX_ALIGN_LAYOUT];
130         if (!controller().haveMulitParSelection())
131                 label += (" (" + labelMap[controller().alignDefault()] + ")");
132         alignDefaultRB->setText(toqstr(label));
133 }
134
135
136 void GuiParagraphDialog::alignmentToRadioButtons(LyXAlignment align)
137 {
138         RadioMap::const_iterator it = radioMap.begin();
139         for (;it != radioMap.end(); ++it) {
140                 if (align == it->first) {
141                         it->second->blockSignals(true);
142                         it->second->setChecked(true);
143                         it->second->blockSignals(false);
144                         return;
145                 }
146         }
147
148         lyxerr << BOOST_CURRENT_FUNCTION << "Unknown alignment "
149                 << align << std::endl;
150 }
151
152
153 LyXAlignment GuiParagraphDialog::getAlignmentFromDialog()
154 {
155         LyXAlignment alignment = LYX_ALIGN_NONE;
156         RadioMap::const_iterator it = radioMap.begin();
157         for (; it != radioMap.end(); ++it) {
158                 if (it->second->isChecked()) {
159                         alignment = it->first;
160                         break;
161                 }
162         }
163         return alignment;
164 }
165
166
167 void GuiParagraphDialog::applyView()
168 {
169         // FIXME: We should not access params() at all!
170         // we should just pass the relevant GUI information
171         // and let the controller do the rest.
172         // With this architecture, only current parent paragraph will be
173         // modified when we have a multi-paragraph selection.
174         ParagraphParameters & params = controller().params();
175
176         params.align(getAlignmentFromDialog());
177
178         // get spacing
179         Spacing::Space ls = Spacing::Default;
180         string other;
181         switch (linespacing->currentIndex()) {
182         case 0:
183                 ls = Spacing::Default;
184                 break;
185         case 1:
186                 ls = Spacing::Single;
187                 break;
188         case 2:
189                 ls = Spacing::Onehalf;
190                 break;
191         case 3:
192                 ls = Spacing::Double;
193                 break;
194         case 4:
195                 ls = Spacing::Other;
196                 other = fromqstr(linespacingValue->text());
197                 break;
198         }
199
200         Spacing const spacing(ls, other);
201         params.spacing(spacing);
202
203         // label width
204         params.labelWidthString(qstring_to_ucs4(labelWidth->text()));
205         // indendation
206         params.noindent(!indentCB->isChecked());
207 }
208
209
210 void GuiParagraphDialog::updateContents()
211 {
212         ParagraphParameters const & params = controller().params();
213
214         // label width
215         docstring const & labelwidth = params.labelWidthString();
216         // FIXME We should not compare translated strings
217         if (labelwidth != _("Senseless with this layout!")) {
218                 labelwidthGB->setEnabled(true);
219                 labelWidth->setText(toqstr(labelwidth));
220         } else {
221                 labelwidthGB->setEnabled(false);
222                 labelWidth->setText("");
223         }
224
225         // alignment
226         checkAlignmentRadioButtons();
227         alignmentToRadioButtons(params.align());
228
229         //indentation
230         bool const canindent = controller().canIndent();
231         indentCB->setEnabled(canindent);
232         indentCB->setChecked(canindent && !params.noindent());
233
234         // linespacing
235         int ls;
236         Spacing const & space = params.spacing();
237         switch (space.getSpace()) {
238         case Spacing::Single:
239                 ls = 1;
240                 break;
241         case Spacing::Onehalf:
242                 ls = 2;
243                 break;
244         case Spacing::Double:
245                 ls = 3;
246                 break;
247         case Spacing::Other:
248                 ls = 4;
249                 break;
250         default:
251                 ls = 0;
252                 break;
253         }
254         linespacing->setCurrentIndex(ls);
255         if (space.getSpace() == Spacing::Other) {
256                 linespacingValue->setText(toqstr(space.getValueAsString()));
257                 linespacingValue->setEnabled(true);
258         } else {
259                 linespacingValue->setText(QString());
260                 linespacingValue->setEnabled(false);
261         }
262 }
263
264 } // namespace frontend
265 } // namespace lyx
266
267 #include "GuiParagraph_moc.cpp"