|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU Lesser General Public License as published by |
|
7 * the Free Software Foundation, version 2.1 of the License. |
|
8 * |
|
9 * This program 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 |
|
12 * GNU Lesser General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU Lesser General Public License |
|
15 * along with this program. If not, |
|
16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/". |
|
17 * |
|
18 * Description: |
|
19 * |
|
20 */ |
|
21 |
|
22 #include "EditorWidget.h" |
|
23 #include "Utilities.h" |
|
24 #include "ChromeEffect.h" |
|
25 |
|
26 // FIXME ;;; Must address the following issues: |
|
27 // |
|
28 // * On Symbian, when focus is outside editor and user clicks inside editor, the editor |
|
29 // receives FocusIn event but does not make the blinking cursor visible until |
|
30 // the user starts to type or presses arrow keys. |
|
31 // |
|
32 // * Edit selection is not visible. |
|
33 // |
|
34 |
|
35 |
|
36 namespace GVA { |
|
37 |
|
38 // Methods for class EditorItem |
|
39 |
|
40 //GTextLineItem extends QGraphicsTextItem as a single-line editor. |
|
41 //Signals horizontal cursor movement, which can be used to implement horizontal scrolling. |
|
42 |
|
43 GTextLineItem::GTextLineItem(QGraphicsItem * parent) |
|
44 : QGraphicsTextItem(parent) |
|
45 , m_maxTextLength(0) |
|
46 , m_hints(Qt::ImhNoPredictiveText) // disable the predictive text |
|
47 { |
|
48 // Disable wrapping, force text to be stored and displayed |
|
49 // as a single line. |
|
50 QTextOption textOption = document()->defaultTextOption(); |
|
51 textOption.setWrapMode(QTextOption::NoWrap); |
|
52 document()->setDefaultTextOption(textOption); |
|
53 // Enable cursor keys. |
|
54 setTextInteractionFlags(Qt::TextEditorInteraction); |
|
55 // This is needed to initialize m_textLine. |
|
56 setText(""); |
|
57 setAcceptDrops(false); |
|
58 m_defaultStartDragDistance = QApplication::startDragDistance(); |
|
59 } |
|
60 |
|
61 GTextLineItem::~GTextLineItem() |
|
62 { |
|
63 if (m_maxTextLength > 0) |
|
64 disconnect(document(), SIGNAL(contentsChange(int, int, int)), this, SLOT(contentsChange(int, int, int))); |
|
65 QApplication::setStartDragDistance(m_defaultStartDragDistance); |
|
66 } |
|
67 |
|
68 void GTextLineItem::setText(const QString & text) |
|
69 { |
|
70 QString newText = text; |
|
71 if(m_maxTextLength > 0 && text.length() > m_maxTextLength ) { |
|
72 newText = newText.left(m_maxTextLength); |
|
73 } |
|
74 setPlainText(newText); |
|
75 m_textLine = document()->begin().layout()->lineForTextPosition(0); |
|
76 } |
|
77 |
|
78 void GTextLineItem::setMaxTextLength(int length) |
|
79 { |
|
80 if (m_maxTextLength <= 0 && length > 0) { |
|
81 QString text = toPlainText(); |
|
82 if( text.length() > length ) { |
|
83 setPlainText(text.left(length)); |
|
84 } |
|
85 connect(document(), SIGNAL(contentsChange(int, int, int)), this, SLOT(contentsChange(int, int, int))); |
|
86 } else if (m_maxTextLength > 0 && length <= 0) { |
|
87 disconnect(document(), SIGNAL(contentsChange(int, int, int)), this, SLOT(contentsChange(int, int, int))); |
|
88 } |
|
89 m_maxTextLength = length; |
|
90 } |
|
91 |
|
92 void GTextLineItem::contentsChange(int position, int charsRemoved, int charsAdded) |
|
93 { |
|
94 Q_UNUSED(position); |
|
95 Q_UNUSED(charsRemoved); |
|
96 Q_UNUSED(charsAdded); |
|
97 if( m_maxTextLength > 0 && toPlainText().length() > m_maxTextLength ) { |
|
98 QTextCursor cursor = textCursor(); |
|
99 cursor.deletePreviousChar(); |
|
100 setTextCursor(cursor); |
|
101 } |
|
102 } |
|
103 |
|
104 // Get the pixel offset of the cursor. Needed to implement scrolling. |
|
105 |
|
106 qreal GTextLineItem::cursorX() |
|
107 { |
|
108 return m_textLine.cursorToX(textCursor().position()); |
|
109 } |
|
110 |
|
111 qreal GTextLineItem::anchorX() |
|
112 { |
|
113 return m_textLine.cursorToX(textCursor().anchor()); |
|
114 } |
|
115 |
|
116 QRectF GTextLineItem::selectionRectF() |
|
117 { |
|
118 qreal x1 = cursorX(); |
|
119 qreal x2 = anchorX(); |
|
120 if (x1 == x2) |
|
121 return QRectF(); |
|
122 return QRectF(x1, 0, x2-x1 + 16, boundingRect().height()); |
|
123 } |
|
124 |
|
125 void GTextLineItem::selectAll() |
|
126 { |
|
127 QTextCursor tc = textCursor(); |
|
128 tc.select(QTextCursor::Document); |
|
129 setTextCursor(tc); |
|
130 emit cursorXChanged(cursorX()); |
|
131 } |
|
132 |
|
133 void GTextLineItem::unselect() |
|
134 { |
|
135 QTextCursor tc = textCursor(); |
|
136 tc.setPosition(tc.position()); |
|
137 setTextCursor(tc); |
|
138 } |
|
139 |
|
140 void GTextLineItem::setCursorPosition(int pos) |
|
141 { |
|
142 QTextCursor tc = textCursor(); |
|
143 tc.setPosition(pos); |
|
144 setTextCursor(tc); |
|
145 } |
|
146 |
|
147 qreal GTextLineItem::textWidth() |
|
148 { |
|
149 return m_textLine.naturalTextWidth(); |
|
150 } |
|
151 |
|
152 void GTextLineItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) |
|
153 { |
|
154 // Paint without ugly selection ants (the dashed line that surrounds |
|
155 // the selected text). TODO: It is clearly a bug in QGraphicsTextItem |
|
156 // that you cannot explicitly set the style of the selection indicator. File this. |
|
157 QStyleOptionGraphicsItem newOption = *option; |
|
158 newOption.state &= (!QStyle::State_Selected | !QStyle::State_HasFocus); |
|
159 painter->save(); |
|
160 painter->setRenderHint(QPainter::Antialiasing); |
|
161 QGraphicsTextItem::paint(painter, &newOption, widget); |
|
162 painter->restore(); |
|
163 if(!isEnabled()) { |
|
164 ChromeEffect::paintDisabledRect(painter, option->exposedRect); |
|
165 } |
|
166 } |
|
167 |
|
168 void GTextLineItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) |
|
169 { |
|
170 QGraphicsTextItem::mouseMoveEvent(event); |
|
171 emit cursorXChanged(cursorX()); |
|
172 } |
|
173 |
|
174 void GTextLineItem::mousePressEvent(QGraphicsSceneMouseEvent * event) |
|
175 { |
|
176 QGraphicsTextItem::mousePressEvent(event); |
|
177 } |
|
178 |
|
179 void GTextLineItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) |
|
180 { |
|
181 QGraphicsTextItem::mouseReleaseEvent(event); |
|
182 QPointF pos = event->pos(); |
|
183 emit tapped(pos); |
|
184 // open vkb by single tap |
|
185 QWidget * widget = event->widget(); |
|
186 QEvent vkbEvent(QEvent::RequestSoftwareInputPanel); |
|
187 QApplication::sendEvent(widget, &vkbEvent); |
|
188 } |
|
189 |
|
190 void GTextLineItem::keyPressEvent(QKeyEvent * event) |
|
191 { |
|
192 // Signal horizontal cursor movement so that an editor widget can |
|
193 // implement horizontal scrolling. |
|
194 qreal oldX = cursorX(); |
|
195 QGraphicsTextItem::keyPressEvent(event); |
|
196 qreal newX = cursorX(); |
|
197 if (newX != oldX) { |
|
198 emit cursorXChanged(newX); |
|
199 } |
|
200 } |
|
201 |
|
202 void GTextLineItem::keyReleaseEvent(QKeyEvent * event) |
|
203 { |
|
204 QGraphicsTextItem::keyReleaseEvent(event); |
|
205 emit textMayChanged(); |
|
206 } |
|
207 |
|
208 void GTextLineItem::focusInEvent(QFocusEvent * event) |
|
209 { |
|
210 Q_UNUSED(event); |
|
211 // disable the drag & drop to fix the auto-delete-all issue |
|
212 QApplication::setStartDragDistance(1000); |
|
213 QGraphicsTextItem::focusInEvent(event); |
|
214 |
|
215 QWidget* fw = QApplication::focusWidget(); |
|
216 Qt::InputMethodHints hints = fw->inputMethodHints(); |
|
217 if (hints != m_hints) |
|
218 fw->setInputMethodHints(m_hints); |
|
219 |
|
220 if (event->reason() != Qt::PopupFocusReason) // to fix the special char issue on VKB |
|
221 emit focusChanged(true); |
|
222 } |
|
223 |
|
224 void GTextLineItem::focusOutEvent(QFocusEvent * event) |
|
225 { |
|
226 Q_UNUSED(event); |
|
227 // restore the drag & drop for other components |
|
228 QApplication::setStartDragDistance(m_defaultStartDragDistance); |
|
229 QGraphicsTextItem::focusOutEvent(event); |
|
230 if (event->reason() != Qt::PopupFocusReason && event->reason() != Qt::ActiveWindowFocusReason) // to fix the special char issue on VKB |
|
231 emit focusChanged(false); |
|
232 } |
|
233 |
|
234 void GTextLineItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) |
|
235 { |
|
236 // ignore context menu event |
|
237 event->ignore(); |
|
238 } |
|
239 |
|
240 void GTextLineItem::setInputMethodHints(Qt::InputMethodHints hints) |
|
241 { |
|
242 m_hints = hints; |
|
243 m_hints |= Qt::ImhNoPredictiveText; // disable the predictive text |
|
244 } |
|
245 |
|
246 // Methods for class GLineEditor |
|
247 // GLineEditor is a QGraphicsWidget that wraps a GTextLineItem to implement scrolling, |
|
248 // draw a background and set padding |
|
249 |
|
250 GLineEditor::GLineEditor(ChromeSnippet * snippet, ChromeWidget * chrome, QGraphicsItem * parent) |
|
251 : QGraphicsWidget(parent) |
|
252 , m_chrome(chrome) |
|
253 , m_viewPortWidth(0.0) |
|
254 , m_viewPortHeight(0.0) |
|
255 , m_padding(0.0) |
|
256 , m_rightTextMargin(0.0) |
|
257 { |
|
258 Q_UNUSED(snippet); |
|
259 |
|
260 // The viewport clips the editor when text overflows |
|
261 // viewport size will be set in resize() |
|
262 m_viewPort = new QGraphicsWidget(this); |
|
263 m_viewPort->setFlags(QGraphicsItem::ItemClipsChildrenToShape); |
|
264 |
|
265 // The actual text editor item |
|
266 m_editor = new GTextLineItem(m_viewPort); |
|
267 m_editor->setDefaultTextColor(m_textColor); |
|
268 m_editor->installEventFilter(this); |
|
269 |
|
270 // Monitor editor cursor position changes for horizontal scrolling. |
|
271 safe_connect(m_editor, SIGNAL(cursorXChanged(qreal)), |
|
272 this, SLOT(makeVisible(qreal))); |
|
273 |
|
274 safe_connect(m_editor, SIGNAL(textMayChanged()), |
|
275 this, SIGNAL(textMayChanged())); |
|
276 |
|
277 safe_connect(m_editor, SIGNAL(focusChanged(bool)), |
|
278 this, SIGNAL(focusChanged(bool))); |
|
279 |
|
280 safe_connect(m_editor, SIGNAL(tapped(QPointF&)), |
|
281 this, SIGNAL(tapped(QPointF&))); |
|
282 |
|
283 setAcceptDrops(false); |
|
284 } |
|
285 |
|
286 GLineEditor::~GLineEditor() |
|
287 { |
|
288 } |
|
289 |
|
290 // TODO: Be a good QGraphicsWidget: update this to use palette color? |
|
291 |
|
292 void GLineEditor::setTextColor(QColor & color) |
|
293 { |
|
294 m_textColor = color; |
|
295 m_editor->setDefaultTextColor(m_textColor); |
|
296 } |
|
297 |
|
298 void GLineEditor::setPadding(qreal padding) |
|
299 { |
|
300 m_padding = padding; |
|
301 //Trigger a resize to adjust component sizes to new padding |
|
302 resize(size()); |
|
303 } |
|
304 |
|
305 void GLineEditor::setRightTextMargin(qreal margin) |
|
306 { |
|
307 m_rightTextMargin = margin; |
|
308 resize(size()); |
|
309 } |
|
310 |
|
311 QString GLineEditor::text() const |
|
312 { |
|
313 return m_editor->toPlainText(); |
|
314 } |
|
315 |
|
316 void GLineEditor::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) |
|
317 { |
|
318 Q_UNUSED(option); |
|
319 Q_UNUSED(widget); |
|
320 |
|
321 painter->save(); |
|
322 painter->setRenderHint(QPainter::Antialiasing); |
|
323 // First, fill rectangle with background color. |
|
324 painter->fillRect(boundingRect(), m_backgroundColor); |
|
325 painter->restore(); |
|
326 if(!isEnabled()) { |
|
327 ChromeEffect::paintDisabledRect(painter, option->exposedRect); |
|
328 } |
|
329 // Make sure any required horizontal scrolling happens |
|
330 // before rendering editor widget, which will be drawn on top |
|
331 // of the background rectangle. |
|
332 makeVisible(m_editor->cursorX()); |
|
333 } |
|
334 |
|
335 void GLineEditor::resizeEvent(QGraphicsSceneResizeEvent * event) |
|
336 { |
|
337 QSizeF size = event->newSize(); |
|
338 m_viewPortWidth = size.width() - m_rightTextMargin - m_padding * 2; |
|
339 m_viewPortHeight = size.height() - m_padding * 2; |
|
340 m_viewPort->setGeometry( |
|
341 m_padding, |
|
342 (size.height() - m_editor->boundingRect().height()) / 2, |
|
343 m_viewPortWidth, |
|
344 m_viewPortHeight); |
|
345 m_editor->setTextWidth(m_viewPortWidth); |
|
346 // move back the m_editor'x to 0 |
|
347 qreal editorShift = -1 * m_editor->pos().x(); |
|
348 m_editor->moveBy(editorShift, 0); |
|
349 updateEditor(); |
|
350 } |
|
351 |
|
352 void GLineEditor::setText(const QString & text) |
|
353 { |
|
354 m_editor->setText(text); |
|
355 m_editor->setPos(0, m_editor->pos().y()); |
|
356 updateEditor(); |
|
357 } |
|
358 |
|
359 void GLineEditor::updateEditor() |
|
360 { |
|
361 makeVisible(m_editor->cursorX()); |
|
362 } |
|
363 |
|
364 // We divide the viewport into 3 distinct regions: |
|
365 // |
|
366 // |
|
367 // [ left | middle | right ] |
|
368 // |
|
369 // [ editor, shifted left by editorShift pixels ] |
|
370 // |
|
371 // When a cursor is in the middle section of the viewport we |
|
372 // leave the editor shift unchanged, to preserve stability. |
|
373 // |
|
374 // When a cursor is in the right section or beyond we shift |
|
375 // the editor left until the cursor appears at the border |
|
376 // between the middle and right sections. |
|
377 // |
|
378 // When a cursor is in the left section or beyond we shift |
|
379 // the editor right until the cursor appears at the border |
|
380 // between the left and middle sections. |
|
381 // |
|
382 // We never shift the editor right of the viewport. |
|
383 |
|
384 void GLineEditor::makeVisible(qreal cursorX) |
|
385 { |
|
386 qreal leftScrollBorder = 0; |
|
387 qreal rightScrollBorder = m_viewPortWidth - 20; |
|
388 qreal editorShift = -1 * m_editor->pos().x(); |
|
389 qreal localX = cursorX - editorShift; |
|
390 |
|
391 if (m_editor->textWidth() < rightScrollBorder) { |
|
392 if (editorShift !=0) |
|
393 m_editor->moveBy(editorShift, 0); |
|
394 return; |
|
395 } |
|
396 |
|
397 if (m_editor->textWidth() - editorShift < rightScrollBorder) { |
|
398 if (editorShift != 0) |
|
399 m_editor->moveBy(rightScrollBorder - m_editor->textWidth() + editorShift, 0); |
|
400 return; |
|
401 } |
|
402 |
|
403 if (localX < leftScrollBorder) { |
|
404 // Before left section, scroll right. |
|
405 // In left section, scroll right. |
|
406 qreal shift = qMin(leftScrollBorder - localX, editorShift); |
|
407 m_editor->moveBy(shift, 0); |
|
408 return; |
|
409 } |
|
410 if (localX >= rightScrollBorder) { |
|
411 // In right section, scroll left. |
|
412 // After right section, scroll left. |
|
413 qreal shift = localX - rightScrollBorder; |
|
414 m_editor->moveBy(-shift, 0); |
|
415 return; |
|
416 } |
|
417 // In middle section, no scroll needed. |
|
418 return; |
|
419 } |
|
420 |
|
421 bool GLineEditor::tappedOnText(qreal x) const |
|
422 { |
|
423 qreal editorShift = m_editor->pos().x(); |
|
424 qreal editorWidth = m_editor->textWidth(); |
|
425 if (editorShift == 0 && editorWidth < x) |
|
426 return false; |
|
427 return true; |
|
428 } |
|
429 |
|
430 bool GLineEditor::eventFilter(QObject * object, QEvent * event) |
|
431 { |
|
432 // Filter editor key events. |
|
433 if (object != m_editor) |
|
434 return false; |
|
435 |
|
436 if (event->type() != QEvent::KeyPress) |
|
437 return false; |
|
438 |
|
439 QKeyEvent * keyEvent = static_cast<QKeyEvent*>(event); |
|
440 switch (keyEvent->key()) { |
|
441 case Qt::Key_Select: |
|
442 case Qt::Key_Return: |
|
443 case Qt::Key_Enter: |
|
444 // Signal that a carriage return-like key-press happened. |
|
445 emit activated(); |
|
446 return true; |
|
447 case Qt::Key_Down: |
|
448 case Qt::Key_Up: |
|
449 // Swallow arrow up/down keys, editor has just one line. |
|
450 return true; |
|
451 default: |
|
452 return false; |
|
453 } |
|
454 } |
|
455 |
|
456 //GTextEditor paints a styled frame around a GLineEditor |
|
457 |
|
458 GTextEditor::GTextEditor(ChromeSnippet * snippet, ChromeWidget * chrome, QGraphicsItem * parent) |
|
459 : GLineEditor(snippet, chrome, parent) |
|
460 { |
|
461 } |
|
462 |
|
463 GTextEditor::~GTextEditor() |
|
464 { |
|
465 } |
|
466 |
|
467 void GTextEditor::paintBorder(QPainter * painter) |
|
468 { |
|
469 if (m_padding > 0 ) { |
|
470 QPainterPath border; |
|
471 //qDebug() << "GTextEditor::paintBorder: " << boundingRect().width() << " " << size().width(); |
|
472 border.addRect(boundingRect()); |
|
473 border.addRoundedRect( |
|
474 m_padding, |
|
475 m_padding, |
|
476 size().width()-m_padding*2, |
|
477 size().height()-m_padding*2, |
|
478 4, |
|
479 4); |
|
480 painter->fillPath(border, m_borderColor); |
|
481 } |
|
482 } |
|
483 |
|
484 void GTextEditor::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) |
|
485 { |
|
486 Q_UNUSED(option); |
|
487 Q_UNUSED(widget); |
|
488 |
|
489 //updateEditor(); |
|
490 GLineEditor::paint(painter, option, widget); |
|
491 painter->save(); |
|
492 painter->setRenderHint(QPainter::Antialiasing); |
|
493 paintBorder(painter); |
|
494 painter->restore(); |
|
495 } |
|
496 |
|
497 //GProgressEditor adds a progress bar to GTextEditor. Joining these into a single QGraphicsWidget makes it |
|
498 //possible to draw a text editor with a progress bar with minimal updates |
|
499 |
|
500 GProgressEditor::GProgressEditor(ChromeSnippet * snippet, ChromeWidget * chrome, QGraphicsItem * parent) |
|
501 : GTextEditor(snippet, chrome, parent) |
|
502 , m_percent(0) |
|
503 { |
|
504 } |
|
505 |
|
506 GProgressEditor::~GProgressEditor() |
|
507 { |
|
508 } |
|
509 |
|
510 void GProgressEditor::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) |
|
511 { |
|
512 Q_UNUSED(option); |
|
513 Q_UNUSED(widget); |
|
514 |
|
515 updateEditor(); |
|
516 |
|
517 QRectF progressRect = boundingRect(); |
|
518 progressRect.setWidth(progressRect.width() * m_percent / 100.0); |
|
519 |
|
520 painter->save(); |
|
521 painter->setRenderHint(QPainter::Antialiasing); |
|
522 painter->fillRect(progressRect, m_progressColor); |
|
523 paintBorder(painter); |
|
524 painter->restore(); |
|
525 if(!isEnabled()) { |
|
526 ChromeEffect::paintDisabledRect(painter, option->exposedRect); |
|
527 } |
|
528 } |
|
529 |
|
530 void GProgressEditor::setProgress(int percent) |
|
531 { |
|
532 // Don't bother with small increments, but ... |
|
533 // |
|
534 // - ALWAYS show the final increment to 99 or 100, because |
|
535 // this tells the user a network request has completed. |
|
536 // |
|
537 // - ALWAYS show the initial increment from 0, because this |
|
538 // tells the user a new network request has started. |
|
539 // |
|
540 // - ALWAYS show decrements, because this tells the user |
|
541 // a new network request has started. |
|
542 if (percent < 99) { |
|
543 if (m_percent > 0) { |
|
544 if (percent > m_percent) { |
|
545 if (percent - m_percent < 10) { |
|
546 //qDebug() << "UrlSearchSnippet::setProgress" << percent << "IGNORE"; |
|
547 return; |
|
548 } |
|
549 } |
|
550 } |
|
551 } |
|
552 |
|
553 if (m_percent == percent) { |
|
554 //qDebug() << "UrlSearchSnippet::setProgress" << percent << "IGNORE"; |
|
555 return; |
|
556 } |
|
557 |
|
558 //qDebug() << "UrlSearchSnippet::setProgress" << percent << "UPDATE"; |
|
559 m_percent = percent; |
|
560 update(); |
|
561 } |
|
562 |
|
563 //A chrome item that displays a GTextEditor. This can be embedded in HTML chrome instead of an input field. |
|
564 |
|
565 TextEditItem::TextEditItem(ChromeSnippet * snippet, ChromeWidget * chrome, QGraphicsItem * parent) |
|
566 : NativeChromeItem(snippet, parent) |
|
567 , m_justFocusIn(false) |
|
568 { |
|
569 m_textEditor = new GTextEditor(snippet, chrome, this); |
|
570 |
|
571 //Style via CSS |
|
572 QWebElement we = m_snippet->element(); |
|
573 |
|
574 QColor textColor; |
|
575 NativeChromeItem::CSSToQColor(we.styleProperty("color", QWebElement::ComputedStyle), |
|
576 textColor); |
|
577 m_textEditor->setTextColor(textColor); |
|
578 |
|
579 //Background of text box |
|
580 QColor backgroundColor; |
|
581 NativeChromeItem::CSSToQColor(we.styleProperty("background-color", QWebElement::ComputedStyle), |
|
582 backgroundColor); |
|
583 m_textEditor->setBackgroundColor(backgroundColor); |
|
584 |
|
585 QColor borderColor; |
|
586 NativeChromeItem::CSSToQColor(we.styleProperty("border-top-color", QWebElement::ComputedStyle), |
|
587 borderColor); |
|
588 m_textEditor->setBorderColor(borderColor); |
|
589 |
|
590 //Padding sets the "border" width |
|
591 QString cssPadding = we.styleProperty("padding-top", QWebElement::ComputedStyle); |
|
592 m_textEditor->setPadding(cssPadding.remove("px").toInt()); |
|
593 |
|
594 safe_connect(m_textEditor, SIGNAL(focusChanged(bool)),this, SLOT(focusChanged(bool))); |
|
595 safe_connect(m_textEditor, SIGNAL(tapped(QPointF&)),this, SLOT(tapped(QPointF&))); |
|
596 } |
|
597 |
|
598 void TextEditItem::tapped(QPointF& pos) |
|
599 { |
|
600 bool hitText = m_textEditor->tappedOnText(pos.x()); |
|
601 if (!m_justFocusIn && !hitText) |
|
602 m_textEditor->unselect(); |
|
603 |
|
604 if (m_justFocusIn) { |
|
605 m_justFocusIn = false; |
|
606 if (hitText && !m_textEditor->hasSelection()) |
|
607 m_textEditor->selectAll(); |
|
608 } |
|
609 } |
|
610 |
|
611 void TextEditItem::focusChanged(bool focusIn) |
|
612 { |
|
613 if (focusIn) |
|
614 m_justFocusIn = true; |
|
615 else { |
|
616 m_justFocusIn = false; |
|
617 m_textEditor->unselect(); |
|
618 m_textEditor->shiftToLeftEnd(); |
|
619 } |
|
620 } |
|
621 |
|
622 TextEditItem::~TextEditItem() |
|
623 { |
|
624 delete m_textEditor; |
|
625 } |
|
626 |
|
627 void TextEditItem::resizeEvent(QGraphicsSceneResizeEvent * ev) |
|
628 { |
|
629 m_textEditor->resize(ev->newSize()); |
|
630 } |
|
631 |
|
632 void TextEditItem::setTextOptions(int flag) |
|
633 { |
|
634 m_textEditor->setInputMethodHints((Qt::InputMethodHints)flag); |
|
635 } |
|
636 |
|
637 } // namespace GVA |