|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (developer.feedback@nokia.com) |
|
6 ** |
|
7 ** This file is part of the HbWidgets module of the UI Extensions for Mobile. |
|
8 ** |
|
9 ** GNU Lesser General Public License Usage |
|
10 ** This file may be used under the terms of the GNU Lesser General Public |
|
11 ** License version 2.1 as published by the Free Software Foundation and |
|
12 ** appearing in the file LICENSE.LGPL included in the packaging of this file. |
|
13 ** Please review the following information to ensure the GNU Lesser General |
|
14 ** Public License version 2.1 requirements will be met: |
|
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
16 ** |
|
17 ** In addition, as a special exception, Nokia gives you certain additional |
|
18 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
20 ** |
|
21 ** If you have questions regarding the use of this file, please contact |
|
22 ** Nokia at developer.feedback@nokia.com. |
|
23 ** |
|
24 ****************************************************************************/ |
|
25 #include "hbformatdialog.h" |
|
26 #include "hbformatdialog_p.h" |
|
27 |
|
28 #include <hbwidget.h> |
|
29 |
|
30 #include <hbpushbutton.h> |
|
31 #include <hbcombobox.h> |
|
32 #include <hbdialog.h> |
|
33 #include <hbcolordialog.h> |
|
34 #include <hbabstractedit.h> |
|
35 #include <hbabstractedit_p.h> |
|
36 #include <hbstyle.h> |
|
37 |
|
38 #include <QGraphicsItem> |
|
39 #include <QGraphicsGridLayout> |
|
40 #include <QTextListFormat> |
|
41 #include <QTextCharFormat> |
|
42 #include <QTextBlockFormat> |
|
43 #include <QTextList> |
|
44 |
|
45 /*! |
|
46 \class HbFormatDialog |
|
47 \brief HbFormatDialog is a text format dialog class for HbAbstractEdit based |
|
48 editors. It offers the default UI and basic formatting functions. This class |
|
49 can be customized by overloading the setContent and polish methods. Signals |
|
50 related to the format changes are sent from the editor. |
|
51 |
|
52 HbFormatDialogPointer should be used as pointer to HbFormatDialog object. |
|
53 |
|
54 @proto |
|
55 @hbwidgets |
|
56 |
|
57 Simplest way of using HbFormatDialog is like this: |
|
58 |
|
59 \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,48} |
|
60 |
|
61 Example of subclassing the HbFormatDialog class: |
|
62 \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,49} |
|
63 |
|
64 HbFormatDialog instance shared with many editors: |
|
65 \snippet{ultimatecodesnippet/ultimatecodesnippet.cpp,50} |
|
66 */ |
|
67 |
|
68 /*! |
|
69 Constructs a HbFormatDialog. |
|
70 */ |
|
71 HbFormatDialog::HbFormatDialog(QGraphicsItem *parent) : HbDialog(*new HbFormatDialogPrivate, parent) |
|
72 {} |
|
73 |
|
74 /*! |
|
75 Destructor. |
|
76 */ |
|
77 HbFormatDialog::~HbFormatDialog() |
|
78 {} |
|
79 |
|
80 /*! |
|
81 Launches a format dialog user interface for the \a editor. |
|
82 |
|
83 \sa setContent |
|
84 */ |
|
85 void HbFormatDialog::launch(HbAbstractEdit *editor) |
|
86 { |
|
87 Q_D(HbFormatDialog); |
|
88 |
|
89 setFlag(QGraphicsItem::ItemIsMovable); |
|
90 setTimeout(HbPopup::NoTimeout); |
|
91 setBackgroundFaded(false); |
|
92 |
|
93 d->editor = editor; |
|
94 if (editor) { |
|
95 if (editor->textCursor().isNull()) |
|
96 return; |
|
97 setContent(editor->textCursor()); |
|
98 show(); |
|
99 } |
|
100 } |
|
101 |
|
102 /*! |
|
103 Sets and updates the content widget for the format dialog. This method can be overloaded. |
|
104 */ |
|
105 void HbFormatDialog::setContent(QTextCursor cursor) |
|
106 { |
|
107 Q_D(HbFormatDialog); |
|
108 |
|
109 QTextCharFormat format = cursor.charFormat(); // current char format |
|
110 |
|
111 // Set content |
|
112 if (!contentWidget()) { |
|
113 HbWidget *container = new HbWidget; |
|
114 |
|
115 d->layout = new QGraphicsGridLayout(); |
|
116 |
|
117 d->comboSize = new HbComboBox(container); |
|
118 d->comboSize->addItem ("8"); |
|
119 d->comboSize->addItem ("9"); |
|
120 d->comboSize->addItem ("10"); |
|
121 d->comboSize->addItem ("11"); |
|
122 d->comboSize->addItem ("12"); |
|
123 d->comboSize->addItem ("14"); |
|
124 d->comboSize->addItem ("16"); |
|
125 d->comboSize->addItem ("18"); |
|
126 d->comboSize->addItem ("20"); |
|
127 d->comboSize->addItem ("22"); |
|
128 d->comboSize->addItem ("24"); |
|
129 d->comboSize->addItem ("26"); |
|
130 d->comboSize->addItem ("28"); |
|
131 d->comboSize->addItem ("36"); |
|
132 d->comboSize->addItem ("48"); |
|
133 d->comboSize->addItem ("72"); |
|
134 connect(d->comboSize, SIGNAL(currentIndexChanged(const QString &)), SLOT(setFontPointSize(const QString &))); |
|
135 d->layout->addItem(d->comboSize, 0, 0, 1, 3); |
|
136 |
|
137 d->buttonColor = new HbPushButton(container); |
|
138 connect(d->buttonColor, SIGNAL(clicked()), SLOT(_q_setColor())); |
|
139 d->layout->addItem(d->buttonColor, 0, 3, 1, 1); |
|
140 |
|
141 d->buttonAlignLeft = new HbPushButton(container); |
|
142 d->buttonAlignLeft->setIcon(HbIcon("qtg_mono_text_align_left.svg")); |
|
143 d->buttonAlignLeft->setCheckable(true); |
|
144 connect(d->buttonAlignLeft, SIGNAL(toggled(bool)), SLOT(setAlignmentLeft(bool))); |
|
145 connect(d->buttonAlignLeft, SIGNAL(toggled(bool)), SLOT(_q_setAlignment(bool))); |
|
146 d->layout->addItem(d->buttonAlignLeft, 1, 0); |
|
147 |
|
148 d->buttonAlignCenter = new HbPushButton(container); |
|
149 d->buttonAlignCenter->setIcon(HbIcon("qtg_mono_text_align_center.svg")); |
|
150 d->buttonAlignCenter->setCheckable(true); |
|
151 connect(d->buttonAlignCenter, SIGNAL(toggled(bool)), SLOT(setAlignmentCenter(bool))); |
|
152 connect(d->buttonAlignCenter, SIGNAL(toggled(bool)), SLOT(_q_setAlignment(bool))); |
|
153 d->layout->addItem(d->buttonAlignCenter, 1, 1); |
|
154 |
|
155 d->buttonAlignRight = new HbPushButton(container); |
|
156 d->buttonAlignRight->setIcon(HbIcon("qtg_mono_text_align_right.svg")); |
|
157 d->buttonAlignRight->setCheckable(true); |
|
158 connect(d->buttonAlignRight, SIGNAL(toggled(bool)), SLOT(setAlignmentRight(bool))); |
|
159 connect(d->buttonAlignRight, SIGNAL(toggled(bool)), SLOT(_q_setAlignment(bool))); |
|
160 d->layout->addItem(d->buttonAlignRight, 1, 2); |
|
161 |
|
162 d->buttonAlignJustify = new HbPushButton(container); |
|
163 d->buttonAlignJustify->setIcon(HbIcon("qtg_mono_text_align_justify.svg")); |
|
164 d->buttonAlignJustify->setCheckable(true); |
|
165 connect(d->buttonAlignJustify, SIGNAL(toggled(bool)), SLOT(setAlignmentJustify(bool))); |
|
166 connect(d->buttonAlignJustify, SIGNAL(toggled(bool)), SLOT(_q_setAlignment(bool))); |
|
167 d->layout->addItem(d->buttonAlignJustify, 1, 3); |
|
168 |
|
169 d->buttonBold = new HbPushButton(container); |
|
170 d->buttonBold->setIcon(HbIcon("qtg_mono_bold.svg")); |
|
171 d->buttonBold->setCheckable(true); |
|
172 connect(d->buttonBold, SIGNAL(toggled(bool)), SLOT(setStyleBold(bool))); |
|
173 d->layout->addItem(d->buttonBold, 2, 0); |
|
174 |
|
175 d->buttonItalic = new HbPushButton(container); |
|
176 d->buttonItalic->setIcon(HbIcon("qtg_mono_italic.svg")); |
|
177 d->buttonItalic->setCheckable(true); |
|
178 connect(d->buttonItalic, SIGNAL(toggled(bool)), SLOT(setStyleItalic(bool))); |
|
179 d->layout->addItem(d->buttonItalic, 2, 1); |
|
180 |
|
181 d->buttonUnderline = new HbPushButton(container); |
|
182 d->buttonUnderline->setIcon(HbIcon("qtg_mono_underline.svg")); |
|
183 d->buttonUnderline->setCheckable(true); |
|
184 connect(d->buttonUnderline, SIGNAL(toggled(bool)), SLOT(setStyleUnderline(bool))); |
|
185 d->layout->addItem(d->buttonUnderline, 2, 2); |
|
186 |
|
187 d->buttonBullet = new HbPushButton(container); |
|
188 d->buttonBullet->setIcon(HbIcon("qtg_mono_bullet.svg")); |
|
189 d->buttonBullet->setCheckable(true); |
|
190 connect(d->buttonBullet, SIGNAL(toggled(bool)), SLOT(setStyleBullet(bool))); |
|
191 d->layout->addItem(d->buttonBullet, 2, 3); |
|
192 |
|
193 container->setLayout(d->layout); |
|
194 |
|
195 setContentWidget(container); |
|
196 } |
|
197 |
|
198 // Update content |
|
199 d->comboSize->setCurrentIndex(d->comboSize->findText(QString::number(format.font().pointSize()))); |
|
200 |
|
201 d->colorChanged(format.foreground().color()); |
|
202 |
|
203 d->buttonAlignLeft->setChecked(cursor.blockFormat().alignment() == Qt::AlignLeft); |
|
204 d->buttonAlignCenter->setChecked(cursor.blockFormat().alignment() == Qt::AlignCenter); |
|
205 d->buttonAlignRight->setChecked(cursor.blockFormat().alignment() == Qt::AlignRight); |
|
206 d->buttonAlignJustify->setChecked(cursor.blockFormat().alignment() == Qt::AlignJustify); |
|
207 |
|
208 d->buttonBold->setChecked(format.font().bold()); |
|
209 d->buttonItalic->setChecked(format.font().italic()); |
|
210 d->buttonUnderline->setChecked(format.font().underline()); |
|
211 if (cursor.currentList()) { |
|
212 d->buttonBullet->setChecked(cursor.currentList()->format().style() == QTextListFormat::ListDisc); |
|
213 } |
|
214 } |
|
215 |
|
216 /*! |
|
217 \reimp |
|
218 */ |
|
219 void HbFormatDialog::polish(HbStyleParameters& params) |
|
220 { |
|
221 Q_D(HbFormatDialog); |
|
222 |
|
223 params.addParameter("button-width"); |
|
224 params.addParameter("button-height"); |
|
225 params.addParameter("popup-margin"); |
|
226 params.addParameter("vertical-middle-margin"); |
|
227 params.addParameter("horizontal-middle-margin"); |
|
228 HbDialog::polish( params ); |
|
229 |
|
230 qreal buttonWidth = params.value("button-width").toDouble(); |
|
231 qreal buttonHeight = params.value("button-height").toDouble(); |
|
232 d->buttonColor->setMinimumSize(buttonWidth, buttonHeight); |
|
233 d->buttonAlignLeft->setMinimumSize(buttonWidth, buttonHeight); |
|
234 d->buttonAlignCenter->setMinimumSize(buttonWidth, buttonHeight); |
|
235 d->buttonAlignRight->setMinimumSize(buttonWidth, buttonHeight); |
|
236 d->buttonAlignJustify->setMinimumSize(buttonWidth, buttonHeight); |
|
237 d->buttonBold->setMinimumSize(buttonWidth, buttonHeight); |
|
238 d->buttonItalic->setMinimumSize(buttonWidth, buttonHeight); |
|
239 d->buttonUnderline->setMinimumSize(buttonWidth, buttonHeight); |
|
240 d->buttonBullet->setMinimumSize(buttonWidth, buttonHeight); |
|
241 |
|
242 qreal popupMargin = params.value("popup-margin").toDouble(); |
|
243 setContentsMargins(popupMargin, popupMargin, popupMargin, popupMargin); |
|
244 |
|
245 d->layout->setVerticalSpacing(params.value("vertical-middle-margin").toDouble()); |
|
246 d->layout->setHorizontalSpacing(params.value("horizontal-middle-margin").toDouble()); |
|
247 } |
|
248 |
|
249 /*! |
|
250 Merges new format for a selection, word under cursor or new chars after cursor position |
|
251 */ |
|
252 void HbFormatDialog::mergeCharFormat(const QTextCharFormat &format) |
|
253 { |
|
254 Q_D(HbFormatDialog); |
|
255 |
|
256 QTextCursor cursor = d->editor->textCursor(); |
|
257 if (cursor.hasSelection()) { |
|
258 cursor.mergeCharFormat(format); |
|
259 } else { |
|
260 int position = cursor.position(); |
|
261 QChar currentChar = cursor.document()->characterAt(position); |
|
262 cursor.select(QTextCursor::WordUnderCursor); |
|
263 int selectionStart = cursor.selectionStart(); |
|
264 int selectionEnd = cursor.selectionEnd(); |
|
265 if (position == selectionStart || position == selectionEnd || currentChar.isSpace()) { |
|
266 HbAbstractEditPrivate::d_ptr(d->editor)->nextCharCursor.mergeCharFormat(format); |
|
267 } else { |
|
268 cursor.mergeCharFormat(format); |
|
269 } |
|
270 } |
|
271 } |
|
272 |
|
273 /*! |
|
274 Sets font size as \a size for a selection, word under cursor or new chars after cursor position |
|
275 */ |
|
276 void HbFormatDialog::setFontPointSize(const QString &size) |
|
277 { |
|
278 Q_D(HbFormatDialog); |
|
279 |
|
280 qreal pointSize = size.toFloat(); |
|
281 QTextCursor cursor = d->editor->textCursor(); |
|
282 if (pointSize != cursor.charFormat().font().pointSize()) { |
|
283 if (pointSize > 0) { |
|
284 QTextCharFormat fmt; |
|
285 fmt.setFontPointSize(pointSize); |
|
286 mergeCharFormat(fmt); |
|
287 } |
|
288 } |
|
289 } |
|
290 |
|
291 /*! |
|
292 Sets or removes bullets for the selected paragraphs or a paragraph containing cursor. |
|
293 */ |
|
294 void HbFormatDialog::setStyleBullet(bool toggled) |
|
295 { |
|
296 Q_D(HbFormatDialog); |
|
297 |
|
298 QTextCursor cursor = d->editor->textCursor(); |
|
299 QTextListFormat::Style style; |
|
300 if (toggled) { |
|
301 style = QTextListFormat::ListDisc; |
|
302 } else { |
|
303 style = QTextListFormat::ListStyleUndefined; |
|
304 } |
|
305 QTextBlockFormat blockFmt; |
|
306 cursor.beginEditBlock(); |
|
307 blockFmt = cursor.blockFormat(); |
|
308 QTextListFormat listFmt; |
|
309 int indent = blockFmt.indent() + 1; |
|
310 if (cursor.currentList()) { |
|
311 listFmt = cursor.currentList()->format(); |
|
312 if (!toggled) |
|
313 indent = 0; |
|
314 } else { |
|
315 blockFmt.setIndent(0); |
|
316 cursor.setBlockFormat(blockFmt); |
|
317 } |
|
318 listFmt.setIndent(indent); |
|
319 listFmt.setStyle(style); |
|
320 cursor.createList(listFmt); |
|
321 cursor.endEditBlock(); |
|
322 } |
|
323 |
|
324 /*! |
|
325 Sets alignment to left for the selected paragraphs or a paragraph containing cursor. |
|
326 */ |
|
327 void HbFormatDialog::setAlignmentLeft(bool toggled) |
|
328 { |
|
329 Q_D(HbFormatDialog); |
|
330 |
|
331 if (toggled) { |
|
332 d->setAlignment(Qt::AlignLeft); |
|
333 } |
|
334 } |
|
335 |
|
336 /*! |
|
337 Sets alignment to center for the selected paragraphs or a paragraph containing cursor. |
|
338 */ |
|
339 void HbFormatDialog::setAlignmentCenter(bool toggled) |
|
340 { |
|
341 Q_D(HbFormatDialog); |
|
342 |
|
343 if (toggled) { |
|
344 d->setAlignment(Qt::AlignCenter); |
|
345 } |
|
346 } |
|
347 |
|
348 /*! |
|
349 Sets alignment to right for the selected paragraphs or a paragraph containing cursor. |
|
350 */ |
|
351 void HbFormatDialog::setAlignmentRight(bool toggled) |
|
352 { |
|
353 Q_D(HbFormatDialog); |
|
354 |
|
355 if (toggled) { |
|
356 d->setAlignment(Qt::AlignRight); |
|
357 } |
|
358 } |
|
359 |
|
360 /*! |
|
361 Sets alignment to justify for the selected paragraphs or a paragraph containing cursor. |
|
362 */ |
|
363 void HbFormatDialog::setAlignmentJustify(bool toggled) |
|
364 { |
|
365 Q_D(HbFormatDialog); |
|
366 |
|
367 if (toggled) { |
|
368 d->setAlignment(Qt::AlignJustify); |
|
369 } |
|
370 } |
|
371 |
|
372 /*! |
|
373 Sets text bold for a selection, word under cursor or new chars after cursor position |
|
374 */ |
|
375 void HbFormatDialog::setStyleBold(bool toggled) |
|
376 { |
|
377 QTextCharFormat fmt; |
|
378 fmt.setFontWeight(toggled ? QFont::Bold : QFont::Normal); |
|
379 mergeCharFormat(fmt); |
|
380 } |
|
381 |
|
382 /*! |
|
383 Sets text italic for a selection, word under cursor or new chars after cursor position |
|
384 */ |
|
385 void HbFormatDialog::setStyleItalic(bool toggled) |
|
386 { |
|
387 QTextCharFormat fmt; |
|
388 fmt.setFontItalic(toggled); |
|
389 mergeCharFormat(fmt); |
|
390 } |
|
391 |
|
392 /*! |
|
393 Sets text underlined for a selection, word under cursor or new chars after cursor position |
|
394 */ |
|
395 void HbFormatDialog::setStyleUnderline(bool toggled) |
|
396 { |
|
397 QTextCharFormat fmt; |
|
398 fmt.setFontUnderline(toggled); |
|
399 mergeCharFormat(fmt); |
|
400 } |