61 class HbSelectionControlPrivate :public HbDialogPrivate |
72 class HbSelectionControlPrivate :public HbDialogPrivate |
62 { |
73 { |
63 Q_DECLARE_PUBLIC(HbSelectionControl) |
74 Q_DECLARE_PUBLIC(HbSelectionControl) |
64 |
75 |
65 public: |
76 public: |
66 HbSelectionControlPrivate(HbAbstractEdit *edit); |
77 HbSelectionControlPrivate(); |
67 void init(); |
78 void init(); |
68 void createPrimitives(); |
79 void createPrimitives(); |
69 void updateHandle(int newHandlePos, |
80 void updateHandle(int newHandlePos, |
70 Qt::AlignmentFlag handleAlignment, |
81 Qt::AlignmentFlag handleAlignment, |
71 QGraphicsItem *handle, |
82 QGraphicsItem *handle, |
72 QGraphicsItem *handleTouchArea, |
83 QGraphicsItem *handleTouchArea, |
73 HbStyle::Primitive handlePrimitive); |
84 HbStyle::Primitive handlePrimitive); |
74 QGraphicsItem * reparent(QGraphicsItem *item); |
85 QGraphicsItem * reparent(QGraphicsItem *item); |
75 void reparent(QGraphicsItem *item, QGraphicsItem *newParent); |
86 void reparent(QGraphicsItem *item, QGraphicsItem *newParent); |
76 void reparentHandles(QGraphicsItem *newParent); |
87 void reparentHandles(QGraphicsItem *newParent); |
|
88 void tapGestureFinished (const QPointF& point); |
|
89 void panGestureStarted (HbPanGesture *gesture); |
|
90 void panGestureUpdated (HbPanGesture *gesture); |
|
91 void panGestureFinished (HbPanGesture *gesture); |
|
92 void show(); |
|
93 void _q_aboutToChangeView(); |
77 |
94 |
78 public: |
95 public: |
79 |
96 |
80 HbAbstractEdit *mEdit; |
97 HbAbstractEdit *mEdit; |
|
98 QGraphicsItem *mTopLevelAncestor; |
81 QPointF mMouseOffset; |
99 QPointF mMouseOffset; |
82 |
100 |
83 QGraphicsItem *mSelectionStartHandle; |
101 QGraphicsItem *mSelectionStartHandle; |
84 QGraphicsItem *mSelectionEndHandle; |
102 QGraphicsItem *mSelectionEndHandle; |
85 HbTouchArea* mSelectionStartTouchArea; |
103 HbTouchArea* mSelectionStartTouchArea; |
86 HbTouchArea* mSelectionEndTouchArea; |
104 HbTouchArea* mSelectionEndTouchArea; |
87 |
105 |
88 HbSelectionControl::HandleType mPressed; |
106 HbSelectionControl::HandleType mPressed; |
89 bool mHandlesDisabled; |
|
90 bool mPanInProgress; |
107 bool mPanInProgress; |
91 bool mHandlesMoved; |
|
92 QBasicTimer mWordSnapTimer; |
108 QBasicTimer mWordSnapTimer; |
93 }; |
109 }; |
94 |
110 |
95 |
111 |
96 HbSelectionControlPrivate::HbSelectionControlPrivate(HbAbstractEdit *edit): |
112 HbSelectionControlPrivate::HbSelectionControlPrivate(): |
97 mEdit(edit), |
113 mEdit(0), |
|
114 mTopLevelAncestor(0), |
98 mSelectionStartHandle(0), |
115 mSelectionStartHandle(0), |
99 mSelectionEndHandle(0), |
116 mSelectionEndHandle(0), |
100 mSelectionStartTouchArea(0), |
117 mSelectionStartTouchArea(0), |
101 mSelectionEndTouchArea(0), |
118 mSelectionEndTouchArea(0), |
102 mPressed(HbSelectionControl::HandleType(0)), |
119 mPressed(HbSelectionControl::HandleType(0)), |
103 mHandlesDisabled(true), |
120 mPanInProgress(false) |
104 mPanInProgress(false), |
121 { |
105 mHandlesMoved(false) |
|
106 { |
|
107 } |
122 } |
108 |
123 |
109 void HbSelectionControlPrivate::init() |
124 void HbSelectionControlPrivate::init() |
110 { |
125 { |
111 Q_Q(HbSelectionControl); |
126 Q_Q(HbSelectionControl); |
112 createPrimitives(); |
127 createPrimitives(); |
113 |
128 |
114 q->setBackgroundItem(HbStyle::P_None); |
129 q->setVisible(false); |
|
130 q->setFlag(QGraphicsItem::ItemIsFocusable,false); |
|
131 q->setFlag(QGraphicsItem::ItemIsPanel,true); |
115 q->setFocusPolicy(Qt::NoFocus); |
132 q->setFocusPolicy(Qt::NoFocus); |
116 q->setTimeout(HbPopup::NoTimeout); |
133 q->setActive(false); |
117 q->setBackgroundFaded(false); |
|
118 q->setVisible(false); |
|
119 q->setDismissPolicy(HbPopup::NoDismiss); |
|
120 q->setModal(false); |
|
121 |
|
122 #ifdef HB_EFFECTS |
|
123 HbEffect::disable(q); |
|
124 #endif |
|
125 |
|
126 q->setParent(mEdit); |
|
127 |
134 |
128 // Control will handle all events going to different handlers. |
135 // Control will handle all events going to different handlers. |
129 q->setHandlesChildEvents(true); |
136 q->setHandlesChildEvents(true); |
130 |
|
131 QObject::connect(mEdit, SIGNAL(cursorPositionChanged(int, int)), q, SLOT(updatePrimitives())); |
|
132 QObject::connect(mEdit, SIGNAL(selectionChanged(const QTextCursor&, const QTextCursor&)), q, SLOT(updatePrimitives())); |
|
133 QObject::connect(mEdit, SIGNAL(contentsChanged()), q, SLOT(updatePrimitives())); |
|
134 |
|
135 q->updatePrimitives(); |
|
136 |
|
137 } |
137 } |
138 |
138 |
139 void HbSelectionControlPrivate::createPrimitives() |
139 void HbSelectionControlPrivate::createPrimitives() |
140 { |
140 { |
141 Q_Q(HbSelectionControl); |
141 Q_Q(HbSelectionControl); |
142 if (!mSelectionStartHandle) { |
142 if (!mSelectionStartHandle) { |
143 mSelectionStartHandle = mEdit->style()->createPrimitive(HbStyle::P_SelectionControl_selectionstart, q); |
143 mSelectionStartHandle = q->style()->createPrimitive(HbStyle::P_SelectionControl_selectionstart, q); |
144 mSelectionStartHandle->hide(); |
144 mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsPanel); |
|
145 mSelectionStartHandle->setFlag(QGraphicsItem::ItemIsFocusable,false); |
|
146 mSelectionStartHandle->setActive(false); |
145 } |
147 } |
146 |
148 |
147 if (!mSelectionEndHandle) { |
149 if (!mSelectionEndHandle) { |
148 mSelectionEndHandle = mEdit->style()->createPrimitive(HbStyle::P_SelectionControl_selectionend, q); |
150 mSelectionEndHandle = q->style()->createPrimitive(HbStyle::P_SelectionControl_selectionend, q); |
149 mSelectionEndHandle->hide(); |
151 mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsPanel); |
|
152 mSelectionEndHandle->setFlag(QGraphicsItem::ItemIsFocusable,false); |
|
153 mSelectionEndHandle->setActive(false); |
150 } |
154 } |
151 |
155 |
152 if (!mSelectionStartTouchArea) { |
156 if (!mSelectionStartTouchArea) { |
153 mSelectionStartTouchArea = new HbTouchArea(q); |
157 mSelectionStartTouchArea = new HbTouchArea(q); |
154 mSelectionStartTouchArea->hide(); |
158 mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsPanel); |
|
159 mSelectionStartTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false); |
|
160 mSelectionStartTouchArea->setActive(false); |
155 HbStyle::setItemName(mSelectionStartTouchArea, "handle-toucharea"); |
161 HbStyle::setItemName(mSelectionStartTouchArea, "handle-toucharea"); |
156 |
162 mSelectionStartTouchArea->grabGesture(Qt::TapGesture); |
|
163 mSelectionStartTouchArea->grabGesture(Qt::PanGesture); |
157 } |
164 } |
158 |
165 |
159 if (!mSelectionEndTouchArea) { |
166 if (!mSelectionEndTouchArea) { |
160 mSelectionEndTouchArea = new HbTouchArea(q); |
167 mSelectionEndTouchArea = new HbTouchArea(q); |
161 mSelectionEndTouchArea->hide(); |
168 mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsPanel); |
|
169 mSelectionEndTouchArea->setFlag(QGraphicsItem::ItemIsFocusable,false); |
|
170 mSelectionEndTouchArea->setActive(false); |
162 HbStyle::setItemName(mSelectionEndTouchArea, "handle-toucharea"); |
171 HbStyle::setItemName(mSelectionEndTouchArea, "handle-toucharea"); |
|
172 mSelectionEndTouchArea->grabGesture(Qt::TapGesture); |
|
173 mSelectionEndTouchArea->grabGesture(Qt::PanGesture); |
163 } |
174 } |
164 } |
175 } |
165 |
176 |
166 /* |
177 /* |
167 Updates given handle associated with handleTouchArea to place it |
178 Updates given handle associated with handleTouchArea to place it |
262 reparent(mSelectionEndHandle, newParent); |
281 reparent(mSelectionEndHandle, newParent); |
263 reparent(mSelectionEndTouchArea, newParent); |
282 reparent(mSelectionEndTouchArea, newParent); |
264 } |
283 } |
265 |
284 |
266 |
285 |
267 HbSelectionControl::HbSelectionControl(HbAbstractEdit *edit) : |
286 void HbSelectionControlPrivate::tapGestureFinished(const QPointF &pos) |
268 HbPopup(*new HbSelectionControlPrivate(edit),0) |
287 { |
269 |
288 if (mEdit->contextMenuFlags().testFlag(Hb::ShowTextContextMenuOnSelectionClicked)) { |
270 { |
289 mEdit->showContextMenu(pos); |
271 Q_D(HbSelectionControl); |
290 } |
272 d->q_ptr = this; |
291 } |
273 d->init(); |
292 |
274 //TODO: selection control could be singleton per main window |
293 void HbSelectionControlPrivate::panGestureStarted(HbPanGesture *gesture) |
275 // since only one selection control is used at a time |
294 { |
276 } |
295 Q_Q(HbSelectionControl); |
277 |
296 |
278 |
297 QPointF point = q->mapFromScene(gesture->sceneStartPos()); |
279 void HbSelectionControl::updatePrimitives() |
298 mPressed = HbSelectionControl::DummyHandle; |
280 { |
|
281 Q_D(HbSelectionControl); |
|
282 if (!d->mHandlesDisabled && d->polished) { |
|
283 if (d->mEdit->textCursor().hasSelection() || |
|
284 (!d->mEdit->textCursor().hasSelection() && (d->mPressed == SelectionStartHandle || d->mPressed == SelectionEndHandle))) { |
|
285 |
|
286 int selStartPos = qMin(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
|
287 int selEndPos = qMax(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
|
288 |
|
289 d->updateHandle(selStartPos,Qt::AlignTop,d->mSelectionStartHandle,d->mSelectionStartTouchArea,HbStyle::P_SelectionControl_selectionstart); |
|
290 d->updateHandle(selEndPos,Qt::AlignBottom,d->mSelectionEndHandle,d->mSelectionEndTouchArea,HbStyle::P_SelectionControl_selectionend); |
|
291 } |
|
292 else { |
|
293 d->mSelectionStartHandle->hide(); |
|
294 d->mSelectionStartTouchArea->hide() ; |
|
295 d->mSelectionEndHandle->hide(); |
|
296 d->mSelectionEndTouchArea->hide() ; |
|
297 } |
|
298 } |
|
299 } |
|
300 |
|
301 void HbSelectionControl::hideHandles() |
|
302 { |
|
303 Q_D(HbSelectionControl); |
|
304 if (!d->mHandlesDisabled) { |
|
305 d->mHandlesDisabled = true; |
|
306 hide(); |
|
307 d->reparentHandles(this); |
|
308 } |
|
309 } |
|
310 |
|
311 void HbSelectionControl::showHandles() |
|
312 { |
|
313 Q_D(HbSelectionControl); |
|
314 if (d->mHandlesDisabled) { |
|
315 d->mHandlesDisabled = false; |
|
316 show(); |
|
317 } |
|
318 } |
|
319 |
|
320 void HbSelectionControl::mouseMoveEvent(QGraphicsSceneMouseEvent *event) |
|
321 { |
|
322 Q_D(HbSelectionControl); |
|
323 |
|
324 QPointF editPos = d->mEdit->mapFromScene(event->scenePos()); |
|
325 |
|
326 QRectF handleRect = d->mSelectionStartHandle->boundingRect(); |
|
327 handleRect.moveTopLeft(editPos + d->mMouseOffset); |
|
328 |
|
329 QPointF hitTestPos = handleRect.center(); |
|
330 |
|
331 if (d->mPressed == SelectionStartHandle) { |
|
332 hitTestPos.setY(handleRect.bottom()+1); |
|
333 } else { |
|
334 hitTestPos.setY(handleRect.top()-1); |
|
335 } |
|
336 |
|
337 // Hit test for the center of current selection touch area |
|
338 int hitPos = HbAbstractEditPrivate::d_ptr(d->mEdit)->hitTest(hitTestPos,Qt::FuzzyHit); |
|
339 if (hitPos == -1) { |
|
340 return; |
|
341 } |
|
342 |
|
343 QTextCursor cursor = d->mEdit->textCursor(); |
|
344 |
|
345 if (hitPos != cursor.position()) { |
|
346 d->mHandlesMoved = true; |
|
347 } |
|
348 cursor.setPosition(hitPos, QTextCursor::KeepAnchor); |
|
349 if (d->mHandlesMoved) { |
|
350 if (d->mEdit) { |
|
351 HbWidgetFeedback::triggered(d->mEdit, Hb::InstantDraggedOver); |
|
352 } |
|
353 // Restart timer every time when a selection handle moved |
|
354 d->mWordSnapTimer.start(SNAP_DELAY, this); |
|
355 d->mEdit->setTextCursor(cursor); |
|
356 } |
|
357 |
|
358 // Ensure that the hitPos is visible |
|
359 HbAbstractEditPrivate::d_ptr(d->mEdit)->ensurePositionVisible(hitPos); |
|
360 updatePrimitives(); |
|
361 } |
|
362 |
|
363 void HbSelectionControl::mousePressEvent (QGraphicsSceneMouseEvent *event) |
|
364 { |
|
365 Q_D(HbSelectionControl); |
|
366 |
|
367 if (d->mEdit) { |
|
368 HbWidgetFeedback::triggered(d->mEdit, Hb::InstantPressed); |
|
369 } |
|
370 |
|
371 d->mPressed = DummyHandle; |
|
372 |
299 |
373 // Find out which handle is being moved |
300 // Find out which handle is being moved |
374 if (d->mSelectionStartTouchArea->contains(mapToItem(d->mSelectionStartTouchArea, event->pos()))) { |
301 if (mSelectionStartTouchArea->contains(q->mapToItem(mSelectionStartTouchArea, point))) { |
375 d->mPressed = SelectionStartHandle; |
302 mPressed = HbSelectionControl::SelectionStartHandle; |
376 d->mMouseOffset = d->mSelectionStartHandle->pos() - event->pos(); |
303 mMouseOffset = mSelectionStartHandle->pos() - point; |
377 } |
304 } |
378 if (d->mSelectionEndTouchArea->contains(mapToItem(d->mSelectionEndTouchArea, event->pos()))) { |
305 if (mSelectionEndTouchArea->contains(q->mapToItem(mSelectionEndTouchArea, point))) { |
379 bool useArea = true; |
306 bool useArea = true; |
380 if(d->mPressed != DummyHandle) { |
307 if(mPressed != HbSelectionControl::DummyHandle) { |
381 |
308 |
382 // The press point was inside in both of the touch areas |
309 // The press point was inside in both of the touch areas |
383 // choose the touch area whose center is closer to the press point |
310 // choose the touch area whose center is closer to the press point |
384 QRectF rect = d->mSelectionStartTouchArea->boundingRect(); |
311 QRectF rect = mSelectionStartTouchArea->boundingRect(); |
385 rect.moveTopLeft(d->mSelectionStartTouchArea->pos()); |
312 rect.moveTopLeft(mSelectionStartTouchArea->pos()); |
386 QLineF lineEventPosSelStartCenter(event->pos(),rect.center()); |
313 QLineF lineEventPosSelStartCenter(point,rect.center()); |
387 |
314 |
388 rect = d->mSelectionEndTouchArea->boundingRect(); |
315 rect = mSelectionEndTouchArea->boundingRect(); |
389 rect.moveTopLeft(d->mSelectionEndTouchArea->pos()); |
316 rect.moveTopLeft(mSelectionEndTouchArea->pos()); |
390 QLineF lineEventPosSelEndCenter(event->pos(),rect.center()); |
317 QLineF lineEventPosSelEndCenter(point,rect.center()); |
391 |
318 |
392 if (lineEventPosSelStartCenter.length() < lineEventPosSelEndCenter.length()) { |
319 if (lineEventPosSelStartCenter.length() < lineEventPosSelEndCenter.length()) { |
393 useArea = false; |
320 useArea = false; |
394 } |
321 } |
395 } |
322 } |
396 if (useArea) { |
323 if (useArea) { |
397 d->mPressed = SelectionEndHandle; |
324 mPressed = HbSelectionControl::SelectionEndHandle; |
398 d->mMouseOffset = d->mSelectionEndHandle->pos() - event->pos(); |
325 mMouseOffset = mSelectionEndHandle->pos() - point; |
399 } |
326 } |
400 } |
327 } |
401 |
328 |
402 if (d->mPressed == DummyHandle) { |
329 if (mPressed == HbSelectionControl::DummyHandle) { |
403 // Hit is outside touch areas, ignore |
330 // Hit is outside touch areas, ignore |
404 event->ignore(); |
|
405 return; |
331 return; |
406 } |
332 } |
407 |
333 |
408 // Position cursor at the pressed selection handle |
334 // Position cursor at the pressed selection handle |
409 |
335 |
410 QTextCursor cursor = d->mEdit->textCursor(); |
336 QTextCursor cursor = mEdit->textCursor(); |
411 int selStartPos = qMin(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
337 int selStartPos = qMin(mEdit->textCursor().anchor(),mEdit->textCursor().position()); |
412 int selEndPos = qMax(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
338 int selEndPos = qMax(mEdit->textCursor().anchor(),mEdit->textCursor().position()); |
413 |
339 |
414 if (d->mPressed == SelectionStartHandle) { |
340 if (mPressed == HbSelectionControl::SelectionStartHandle) { |
415 cursor.setPosition(selEndPos); |
341 cursor.setPosition(selEndPos); |
416 cursor.setPosition(selStartPos, QTextCursor::KeepAnchor); |
342 cursor.setPosition(selStartPos, QTextCursor::KeepAnchor); |
417 } else { |
343 } else { |
418 cursor.setPosition(selStartPos); |
344 cursor.setPosition(selStartPos); |
419 cursor.setPosition(selEndPos, QTextCursor::KeepAnchor); |
345 cursor.setPosition(selEndPos, QTextCursor::KeepAnchor); |
420 } |
346 } |
421 d->mEdit->setTextCursor(cursor); |
347 mEdit->setTextCursor(cursor); |
422 |
348 |
423 } |
349 } |
424 |
350 |
425 void HbSelectionControl::mouseReleaseEvent (QGraphicsSceneMouseEvent *event) |
351 |
426 { |
352 void HbSelectionControlPrivate::panGestureFinished(HbPanGesture *gesture) |
427 Q_D(HbSelectionControl); |
353 { |
428 Q_UNUSED(event); |
354 Q_Q(HbSelectionControl); |
429 |
355 Q_UNUSED(gesture) |
430 if (d->mEdit) { |
356 |
431 HbWidgetFeedback::triggered(d->mEdit, Hb::InstantReleased); |
357 if (mWordSnapTimer.isActive()) { |
432 } |
|
433 |
|
434 if (d->mWordSnapTimer.isActive()) { |
|
435 |
358 |
436 // Snap selection to word beginning or end |
359 // Snap selection to word beginning or end |
437 QTextCursor cursor = d->mEdit->textCursor(); |
360 QTextCursor cursor = mEdit->textCursor(); |
438 int curPos = d->mEdit->textCursor().position(); |
361 int curPos = mEdit->textCursor().position(); |
439 int anchPos = d->mEdit->textCursor().anchor(); |
362 int anchPos = mEdit->textCursor().anchor(); |
440 cursor.select(QTextCursor::WordUnderCursor); |
363 cursor.select(QTextCursor::WordUnderCursor); |
441 |
364 |
442 // Snap direction depends on cursor position |
365 // Snap direction depends on cursor position |
443 curPos = ((curPos > anchPos)?cursor.position():cursor.anchor()); |
366 curPos = ((curPos > anchPos)?cursor.position():cursor.anchor()); |
444 |
367 |
445 cursor.setPosition(anchPos); |
368 cursor.setPosition(anchPos); |
446 cursor.setPosition(curPos, QTextCursor::KeepAnchor); |
369 cursor.setPosition(curPos, QTextCursor::KeepAnchor); |
447 d->mEdit->setTextCursor(cursor); |
370 mEdit->setTextCursor(cursor); |
448 } |
371 } |
449 |
372 |
450 d->mPressed = DummyHandle; |
373 mPressed = HbSelectionControl::DummyHandle; |
451 updatePrimitives(); |
374 q->updatePrimitives(); |
452 |
375 } |
453 if (!d->mHandlesMoved) { |
376 |
454 if (d->mEdit->contextMenuFlags().testFlag(Hb::ShowTextContextMenuOnSelectionClicked)) { |
377 |
455 d->mEdit->showContextMenu(event->scenePos()); |
378 void HbSelectionControlPrivate::panGestureUpdated(HbPanGesture *gesture) |
456 } |
379 { |
457 } |
380 Q_Q(HbSelectionControl); |
458 d->mHandlesMoved = false; |
381 |
459 } |
382 QPointF editPos = mEdit->mapFromScene(gesture->sceneStartPos() + gesture->sceneOffset()); |
460 |
383 |
461 void HbSelectionControl::panStarted() |
384 QRectF handleRect = mSelectionStartHandle->boundingRect(); |
462 { |
385 handleRect.moveTopLeft(editPos + mMouseOffset); |
463 Q_D(HbSelectionControl); |
386 |
464 |
387 QPointF hitTestPos = handleRect.center(); |
465 if (!d->mHandlesDisabled) { |
388 |
|
389 if (mPressed == HbSelectionControl::SelectionStartHandle) { |
|
390 hitTestPos.setY(handleRect.bottom()+1); |
|
391 } else { |
|
392 hitTestPos.setY(handleRect.top()-1); |
|
393 } |
|
394 |
|
395 QTextCursor cursor = mEdit->textCursor(); |
|
396 // Hit test for the center of current selection touch area |
|
397 int hitPos = HbAbstractEditPrivate::d_ptr(mEdit)->hitTest(hitTestPos,Qt::FuzzyHit); |
|
398 if (hitPos == -1 || hitPos == cursor.anchor()) { |
|
399 return; |
|
400 } |
|
401 |
|
402 |
|
403 bool handlesMoved(false); |
|
404 if (hitPos != cursor.position()) { |
|
405 handlesMoved = true; |
|
406 } |
|
407 cursor.setPosition(hitPos, QTextCursor::KeepAnchor); |
|
408 if (handlesMoved) { |
|
409 if (mEdit) { |
|
410 HbWidgetFeedback::triggered(mEdit, Hb::InstantDraggedOver); |
|
411 } |
|
412 // Restart timer every time when a selection handle moved |
|
413 mWordSnapTimer.start(SNAP_DELAY, q); |
|
414 mEdit->setTextCursor(cursor); |
|
415 } |
|
416 |
|
417 // Ensure that the hitPos is visible |
|
418 HbAbstractEditPrivate::d_ptr(mEdit)->ensurePositionVisible(hitPos); |
|
419 q->updatePrimitives(); |
|
420 } |
|
421 |
|
422 void HbSelectionControlPrivate::show() { |
|
423 Q_Q(HbSelectionControl); |
|
424 |
|
425 // Set the z-value of the selection control above its top-level ancestor |
|
426 if (mTopLevelAncestor) { |
|
427 qreal zValue = mTopLevelAncestor->zValue() + HbPrivate::SelectionControlHandlesValueUnit; |
|
428 |
|
429 q->setZValue(zValue); |
|
430 } |
|
431 |
|
432 if (q->scene() != mEdit->scene() && mEdit->scene()) { |
|
433 mEdit->scene()->addItem(q); |
|
434 } |
|
435 q->show(); |
|
436 q->updatePrimitives(); |
|
437 } |
|
438 |
|
439 |
|
440 void HbSelectionControlPrivate::_q_aboutToChangeView() |
|
441 { |
|
442 Q_Q(HbSelectionControl); |
|
443 |
|
444 if (mEdit && q->isVisible()) { |
|
445 mEdit->deselect(); |
|
446 } |
|
447 } |
|
448 |
|
449 |
|
450 HbSelectionControl::HbSelectionControl() : HbWidget(*new HbSelectionControlPrivate(),0) |
|
451 |
|
452 { |
|
453 Q_D(HbSelectionControl); |
|
454 d->q_ptr = this; |
|
455 d->init(); |
|
456 //TODO: selection control could be singleton per main window |
|
457 // since only one selection control is used at a time |
|
458 } |
|
459 |
|
460 HbSelectionControl* HbSelectionControl::attachEditor(HbAbstractEdit *edit) |
|
461 { |
|
462 if(!edit || !edit->mainWindow()) { |
|
463 qWarning("HbSelectionControl: attempting to attach to null editor pointer!"); |
|
464 } |
|
465 |
|
466 HbSelectionControl *control = globalSelectionControlHash()->value(edit->mainWindow()); |
|
467 |
|
468 if (!control) { |
|
469 control = new HbSelectionControl(); |
|
470 globalSelectionControlHash()->insert(edit->mainWindow(),control); |
|
471 QObject::connect(edit->mainWindow(), SIGNAL(aboutToChangeView(HbView *, HbView *)), control, SLOT(_q_aboutToChangeView())); |
|
472 } |
|
473 |
|
474 HbSelectionControlPrivate *d = control->d_func(); |
|
475 |
|
476 if (edit != d->mEdit) { |
|
477 control->detachEditor(); |
|
478 d->mEdit = edit; |
|
479 QObject::connect(d->mEdit, SIGNAL(cursorPositionChanged(int, int)), control, SLOT(updatePrimitives())); |
|
480 QObject::connect(d->mEdit, SIGNAL(contentsChanged()), control, SLOT(updatePrimitives())); |
|
481 |
|
482 // find first top-level ancestor of d->mEdit |
|
483 for(d->mTopLevelAncestor = d->mEdit; |
|
484 d->mTopLevelAncestor->parentItem(); |
|
485 d->mTopLevelAncestor = d->mTopLevelAncestor->parentItem()){}; |
|
486 } |
|
487 return control; |
|
488 } |
|
489 |
|
490 void HbSelectionControl::detachEditor() |
|
491 { |
|
492 Q_D(HbSelectionControl); |
|
493 if (d->mEdit) { |
|
494 hideHandles(); |
|
495 d->reparentHandles(this); |
|
496 d->mEdit->disconnect(this); |
|
497 d->mEdit->d_func()->selectionControl = 0; |
|
498 d->mEdit->deselect(); |
|
499 d->mEdit = 0; |
|
500 d->mTopLevelAncestor = 0; |
|
501 } |
|
502 } |
|
503 |
|
504 |
|
505 void HbSelectionControl::hideHandles() |
|
506 { |
|
507 Q_D(HbSelectionControl); |
|
508 if (isVisible() && d->mEdit) { |
|
509 hide(); |
|
510 d->reparentHandles(this); |
|
511 } |
|
512 } |
|
513 |
|
514 void HbSelectionControl::showHandles() |
|
515 { |
|
516 Q_D(HbSelectionControl); |
|
517 if (!isVisible() && d->mEdit) { |
|
518 d->show(); |
|
519 } |
|
520 } |
|
521 |
|
522 void HbSelectionControl::scrollStarted() |
|
523 { |
|
524 Q_D(HbSelectionControl); |
|
525 |
|
526 if (isVisible() && d->mEdit) { |
466 d->mPanInProgress = true; |
527 d->mPanInProgress = true; |
467 // Reparent handle items to editor canvas on pan start |
528 // Reparent handle items to editor canvas on pan start |
468 d->reparentHandles(HbAbstractEditPrivate::d_ptr(d->mEdit)->canvas); |
529 d->reparentHandles(HbAbstractEditPrivate::d_ptr(d->mEdit)->canvas); |
469 } |
530 } |
470 } |
531 } |
471 |
532 |
472 void HbSelectionControl::panFinished() |
533 void HbSelectionControl::scrollFinished() |
473 { |
534 { |
474 Q_D(HbSelectionControl); |
535 Q_D(HbSelectionControl); |
475 |
536 |
476 if (!d->mHandlesDisabled) { |
537 if (isVisible() && d->mEdit) { |
477 d->mPanInProgress = false; |
538 d->mPanInProgress = false; |
478 updatePrimitives(); |
539 updatePrimitives(); |
479 } |
540 } |
480 } |
541 } |
481 |
542 |
491 |
552 |
492 void HbSelectionControl::polish( HbStyleParameters& params ) |
553 void HbSelectionControl::polish( HbStyleParameters& params ) |
493 { |
554 { |
494 Q_D(HbSelectionControl); |
555 Q_D(HbSelectionControl); |
495 |
556 |
496 HbPopup::polish(params); |
557 HbWidget::polish(params); |
497 QSizeF size = d->mSelectionStartTouchArea->preferredSize(); |
558 QSizeF size = d->mSelectionStartTouchArea->preferredSize(); |
498 d->mSelectionStartTouchArea->resize(size); |
559 d->mSelectionStartTouchArea->resize(size); |
499 d->mSelectionEndTouchArea->resize(size); |
560 d->mSelectionEndTouchArea->resize(size); |
|
561 updatePrimitives(); |
500 } |
562 } |
501 |
563 |
502 QVariant HbSelectionControl::itemChange(GraphicsItemChange change, const QVariant &value) |
564 QVariant HbSelectionControl::itemChange(GraphicsItemChange change, const QVariant &value) |
503 { |
565 { |
504 if (change == QGraphicsItem::ItemPositionChange) { |
566 if (change == QGraphicsItem::ItemPositionChange) { |
505 return qVariantFromValue(QPointF(0,0)); |
567 return qVariantFromValue(QPointF(0,0)); |
506 } else if (change == QGraphicsItem::ItemVisibleChange) { |
568 } |
507 updatePrimitives(); |
569 |
508 } |
570 return HbWidget::itemChange(change, value); |
509 |
571 } |
510 return HbPopup::itemChange(change, value); |
572 |
511 } |
573 void HbSelectionControl::gestureEvent(QGestureEvent* event) { |
|
574 Q_D(HbSelectionControl); |
|
575 if(HbTapGesture *tap = qobject_cast<HbTapGesture*>(event->gesture(Qt::TapGesture))) { |
|
576 QPointF pos = event->mapToGraphicsScene(tap->position()); |
|
577 switch(tap->state()) { |
|
578 case Qt::GestureStarted: |
|
579 if (d->mEdit) { |
|
580 HbWidgetFeedback::triggered(d->mEdit, Hb::InstantPressed); |
|
581 } |
|
582 break; |
|
583 case Qt::GestureUpdated: |
|
584 break; |
|
585 case Qt::GestureFinished: |
|
586 if (d->mEdit) { |
|
587 d->tapGestureFinished(pos); |
|
588 HbWidgetFeedback::triggered(d->mEdit, Hb::InstantReleased); |
|
589 } |
|
590 break; |
|
591 case Qt::GestureCanceled: |
|
592 break; |
|
593 default: |
|
594 break; |
|
595 } |
|
596 } |
|
597 |
|
598 if(HbPanGesture *pan = qobject_cast<HbPanGesture*>(event->gesture(Qt::PanGesture))) { |
|
599 switch(pan->state()) { |
|
600 case Qt::GestureStarted: |
|
601 if (d->mEdit) { |
|
602 d->panGestureStarted(pan); |
|
603 } |
|
604 break; |
|
605 case Qt::GestureUpdated: |
|
606 if (d->mEdit) { |
|
607 d->panGestureUpdated(pan); |
|
608 } |
|
609 break; |
|
610 case Qt::GestureFinished: |
|
611 if (d->mEdit) { |
|
612 d->panGestureFinished(pan); |
|
613 HbWidgetFeedback::triggered(d->mEdit, Hb::InstantReleased); |
|
614 } |
|
615 break; |
|
616 case Qt::GestureCanceled: |
|
617 break; |
|
618 default: |
|
619 break; |
|
620 } |
|
621 } |
|
622 } |
|
623 |
|
624 bool HbSelectionControl::event(QEvent *event) |
|
625 { |
|
626 Q_D(HbSelectionControl); |
|
627 |
|
628 if (event->type() == HbEvent::DeviceProfileChanged && d->mEdit) { |
|
629 HbDeviceProfileChangedEvent* dpEvent = static_cast<HbDeviceProfileChangedEvent*>(event); |
|
630 if ( dpEvent->profile().alternateProfileName() == dpEvent->oldProfile().name() ) { |
|
631 updatePrimitives(); |
|
632 } |
|
633 } |
|
634 return HbWidget::event(event); |
|
635 } |
|
636 |
|
637 void HbSelectionControl::updatePrimitives() |
|
638 { |
|
639 Q_D(HbSelectionControl); |
|
640 |
|
641 if (isVisible() && d->polished && d->mEdit) { |
|
642 if (d->mEdit->textCursor().hasSelection() ) { |
|
643 |
|
644 int selStartPos = qMin(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
|
645 int selEndPos = qMax(d->mEdit->textCursor().anchor(),d->mEdit->textCursor().position()); |
|
646 |
|
647 d->updateHandle(selStartPos,Qt::AlignTop,d->mSelectionStartHandle,d->mSelectionStartTouchArea,HbStyle::P_SelectionControl_selectionstart); |
|
648 d->updateHandle(selEndPos,Qt::AlignBottom,d->mSelectionEndHandle,d->mSelectionEndTouchArea,HbStyle::P_SelectionControl_selectionend); |
|
649 } |
|
650 else { |
|
651 hide(); |
|
652 } |
|
653 } |
|
654 } |
|
655 #include "moc_hbselectioncontrol_p.cpp" |