27 #include "hgwidgetitem.h" |
26 #include "hgwidgetitem.h" |
28 #include "trace.h" |
27 #include "trace.h" |
29 //#include "hgindexfeedback.h" |
28 //#include "hgindexfeedback.h" |
30 |
29 |
31 static const int INITIAL_SCROLLBAR_HIDE_TIMEOUT(4000); |
30 static const int INITIAL_SCROLLBAR_HIDE_TIMEOUT(4000); |
32 static const int DEFAULT_BUFFER_SIZE(30); |
31 static const int DEFAULT_BUFFER_SIZE(25); |
33 |
32 |
34 HgWidgetPrivate::HgWidgetPrivate() : |
33 HgWidgetPrivate::HgWidgetPrivate() : |
35 mLayout(0), |
|
36 mContainer(0), |
34 mContainer(0), |
37 mBufferManager(0), |
35 mBufferManager(0), |
38 mModel(0), |
36 mModel(0), |
39 mSelectionModel(0), |
|
40 mDefaultSelectionModel(0), |
37 mDefaultSelectionModel(0), |
41 mScrollBar(0), |
38 mScrollBar(0), |
42 mAbleToScroll(false), |
39 mAbleToScroll(false), |
43 mHandleLongPress(false), |
40 mHandleLongPress(false), |
44 mBufferSize(DEFAULT_BUFFER_SIZE), |
41 mBufferSize(DEFAULT_BUFFER_SIZE), |
67 q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
64 q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
68 q->setFlag( QGraphicsItem::ItemClipsChildrenToShape, true ); |
65 q->setFlag( QGraphicsItem::ItemClipsChildrenToShape, true ); |
69 q->setFocusPolicy(Qt::StrongFocus); |
66 q->setFocusPolicy(Qt::StrongFocus); |
70 |
67 |
71 createScrollBar(container->scrollDirection()); |
68 createScrollBar(container->scrollDirection()); |
72 |
69 |
73 //QObject::connect(&(mScrollBarHideTimer), SIGNAL(timeout()), q, SLOT(_q_hideScrollBars())); |
70 //QObject::connect(&(mScrollBarHideTimer), SIGNAL(timeout()), q, SLOT(_q_hideScrollBars())); |
74 |
71 |
75 mContainer = container; |
72 mContainer = container; |
76 |
73 |
77 mScrollBarPolicy = HgWidget::ScrollBarAutoHide; |
74 mScrollBarPolicy = HgWidget::ScrollBarAutoHide; |
83 q->connect(mContainer, SIGNAL(longPressed(const QModelIndex&, const QPointF &)), |
80 q->connect(mContainer, SIGNAL(longPressed(const QModelIndex&, const QPointF &)), |
84 q, SIGNAL(longPressed(const QModelIndex&, const QPointF &))); |
81 q, SIGNAL(longPressed(const QModelIndex&, const QPointF &))); |
85 q->connect(mContainer, SIGNAL(scrollingStarted()), q, SIGNAL(scrollingStarted())); |
82 q->connect(mContainer, SIGNAL(scrollingStarted()), q, SIGNAL(scrollingStarted())); |
86 q->connect(mContainer, SIGNAL(scrollingEnded()), q, SIGNAL(scrollingEnded())); |
83 q->connect(mContainer, SIGNAL(scrollingEnded()), q, SIGNAL(scrollingEnded())); |
87 q->connect(mScrollBarHideTimer, SIGNAL(timeout()), q, SLOT(_q_hideScrollBars())); |
84 q->connect(mScrollBarHideTimer, SIGNAL(timeout()), q, SLOT(_q_hideScrollBars())); |
88 |
85 |
89 // mIndexFeedback = new HgIndexFeedback(q); |
86 // mIndexFeedback = new HgIndexFeedback(q); |
90 // mIndexFeedback->setWidget(q); |
87 // mIndexFeedback->setWidget(q); |
91 |
88 |
92 } |
89 } |
93 |
90 |
94 void HgWidgetPrivate::setModel( QAbstractItemModel *model ) |
91 void HgWidgetPrivate::setModel( QAbstractItemModel *model ) |
95 { |
92 { |
96 FUNC_LOG; |
93 FUNC_LOG; |
103 } |
100 } |
104 |
101 |
105 void HgWidgetPrivate::setSelectionModel(QItemSelectionModel *selectionModel) |
102 void HgWidgetPrivate::setSelectionModel(QItemSelectionModel *selectionModel) |
106 { |
103 { |
107 FUNC_LOG; |
104 FUNC_LOG; |
108 |
105 |
109 Q_Q(HgWidget); |
106 Q_Q(HgWidget); |
110 |
107 |
111 if (mContainer) { |
108 if (mContainer) { |
|
109 if (mContainer->selectionModel()) { |
|
110 q->disconnect(mContainer->selectionModel(), |
|
111 SIGNAL(currentChanged(QModelIndex, QModelIndex)), |
|
112 q, |
|
113 SLOT(_q_updateCurrentItem(QModelIndex, QModelIndex))); |
|
114 } |
|
115 |
|
116 QModelIndex defaultItem; |
|
117 if (mModel && mModel->rowCount() > 0) { |
|
118 defaultItem = mModel->index(0, 0); |
|
119 } |
|
120 |
112 if (selectionModel == 0) { |
121 if (selectionModel == 0) { |
113 QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel; |
122 QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel; |
114 mDefaultSelectionModel = 0; |
123 mDefaultSelectionModel = 0; |
115 mDefaultSelectionModel = new QItemSelectionModel(mModel); |
124 mDefaultSelectionModel = new QItemSelectionModel(mModel); |
116 mContainer->setSelectionModel(mDefaultSelectionModel); |
125 q->connect(mDefaultSelectionModel, |
|
126 SIGNAL(currentChanged(QModelIndex, QModelIndex)), |
|
127 SLOT(_q_updateCurrentItem(QModelIndex, QModelIndex))); |
|
128 mContainer->setSelectionModel(mDefaultSelectionModel, defaultItem); |
117 delete oldSelectionModel; |
129 delete oldSelectionModel; |
118 } |
130 } |
119 else if (selectionModel != mContainer->selectionModel()) { |
131 else if (selectionModel != mContainer->selectionModel()) { |
120 QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel; |
132 QItemSelectionModel *oldSelectionModel = mDefaultSelectionModel; |
121 mDefaultSelectionModel = 0; |
133 mDefaultSelectionModel = 0; |
122 mContainer->setSelectionModel(selectionModel); |
134 q->connect(selectionModel, |
|
135 SIGNAL(currentChanged(QModelIndex, QModelIndex)), |
|
136 SLOT(_q_updateCurrentItem(QModelIndex, QModelIndex))); |
|
137 mContainer->setSelectionModel(selectionModel, defaultItem); |
123 delete oldSelectionModel; |
138 delete oldSelectionModel; |
124 } |
139 } |
|
140 |
125 if (mContainer->selectionModel()) { |
141 if (mContainer->selectionModel()) { |
126 // if (mIndexFeedback) { |
142 // if (mIndexFeedback) { |
127 // delete mIndexFeedback; |
143 // delete mIndexFeedback; |
128 // mIndexFeedback = 0; |
144 // mIndexFeedback = 0; |
129 // } |
145 // } |
130 // mIndexFeedback = new HgIndexFeedback(q); |
146 // mIndexFeedback = new HgIndexFeedback(q); |
131 // mIndexFeedback->setWidget(q); |
147 // mIndexFeedback->setWidget(q); |
132 } |
148 |
|
149 } |
133 } |
150 } |
134 } |
151 } |
135 |
152 |
136 QItemSelectionModel *HgWidgetPrivate::selectionModel() const |
153 QItemSelectionModel *HgWidgetPrivate::selectionModel() const |
137 { |
154 { |
247 q->connect(mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), |
264 q->connect(mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), |
248 SLOT(_q_removeRows(QModelIndex, int, int))); |
265 SLOT(_q_removeRows(QModelIndex, int, int))); |
249 q->connect(mModel, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)), |
266 q->connect(mModel, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)), |
250 SLOT(_q_moveRows(QModelIndex, int, int, QModelIndex, int))); |
267 SLOT(_q_moveRows(QModelIndex, int, int, QModelIndex, int))); |
251 q->connect(mModel, SIGNAL(modelReset()),SLOT(_q_modelReset())); |
268 q->connect(mModel, SIGNAL(modelReset()),SLOT(_q_modelReset())); |
252 |
269 |
253 mContainer->setItemCount(mModel->rowCount(QModelIndex())); |
270 mContainer->setItemCount(mModel->rowCount(QModelIndex())); |
254 QList<HgWidgetItem*> items = mContainer->items(); |
271 QList<HgWidgetItem*> items = mContainer->items(); |
255 |
272 |
256 // set model indexes for the items firsts |
273 // set model indexes for the items firsts |
257 const int itemCount = items.count(); |
274 const int itemCount = items.count(); |
259 { |
276 { |
260 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
277 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
261 } |
278 } |
262 |
279 |
263 initBufferManager(itemCount); |
280 initBufferManager(itemCount); |
264 |
281 |
265 setSelectionModel(0); // Default |
282 setSelectionModel(0); // Default |
266 |
|
267 if (mModel->rowCount() > 0) |
|
268 { |
|
269 setCurrentIndex(mModel->index(0, 0)); |
|
270 scrollTo(mModel->index(0, 0)); |
|
271 } |
|
272 } |
283 } |
273 } |
284 } |
274 |
285 |
275 void HgWidgetPrivate::clearCurrentModel() |
286 void HgWidgetPrivate::clearCurrentModel() |
276 { |
287 { |
338 // notify container which items have updated data available. |
349 // notify container which items have updated data available. |
339 // container is responsible to redraw view if some of the items |
350 // container is responsible to redraw view if some of the items |
340 // is visible. |
351 // is visible. |
341 if (firstUpdated != -1 && lastUpdated != -1) { |
352 if (firstUpdated != -1 && lastUpdated != -1) { |
342 mContainer->itemDataChanged(firstUpdated, lastUpdated); |
353 mContainer->itemDataChanged(firstUpdated, lastUpdated); |
343 } |
354 // if item data for current has changed we need to update current. |
|
355 if (mContainer->selectionModel()) { |
|
356 QModelIndex currentIndex = mContainer->selectionModel()->currentIndex(); |
|
357 if (currentIndex.isValid() && |
|
358 currentIndex.row() >= firstUpdated && |
|
359 currentIndex.row() <= lastUpdated) { |
|
360 updateCurrentItem(currentIndex); |
|
361 } |
|
362 } |
|
363 } |
344 } |
364 } |
345 |
365 |
346 void HgWidgetPrivate::_q_scrollPositionChanged(qreal index,bool scrollBarAnimation) |
366 void HgWidgetPrivate::_q_scrollPositionChanged(qreal index,bool scrollBarAnimation) |
347 { |
367 { |
348 int newPos = index; |
368 int newPos = index; |
408 } |
428 } |
409 } |
429 } |
410 |
430 |
411 void HgWidgetPrivate::setScrollBarPolicy(HgWidget::ScrollBarPolicy policy) |
431 void HgWidgetPrivate::setScrollBarPolicy(HgWidget::ScrollBarPolicy policy) |
412 { |
432 { |
413 mScrollBarPolicy = policy; |
433 Q_Q(HgWidget); |
414 |
434 |
415 if (mScrollBarPolicy == HgWidget::ScrollBarAlwaysOff && |
435 if (mScrollBarPolicy != policy) { |
416 mScrollBar->isVisible()){ |
436 mScrollBarPolicy = policy; |
417 mScrollBar->setVisible(false); |
437 |
418 } |
438 if (mScrollBarPolicy == HgWidget::ScrollBarAlwaysOff && |
419 |
439 mScrollBar->isVisible()){ |
420 if(policy != HgWidget::ScrollBarAlwaysOff){ |
440 mScrollBar->setVisible(false); |
421 updateScrollMetrics(); |
441 } |
|
442 |
|
443 if(policy != HgWidget::ScrollBarAlwaysOff){ |
|
444 updateScrollMetrics(); |
|
445 } |
422 } |
446 } |
423 } |
447 } |
424 |
448 |
425 void HgWidgetPrivate::_q_hideScrollBars() |
449 void HgWidgetPrivate::_q_hideScrollBars() |
426 { |
450 { |
469 // rows have been inserted to empty model. This is a special case |
493 // rows have been inserted to empty model. This is a special case |
470 // that reset function should handle. |
494 // that reset function should handle. |
471 _q_modelReset(); |
495 _q_modelReset(); |
472 return; |
496 return; |
473 } |
497 } |
474 |
498 |
475 mBufferManager->addItems(start, end); |
499 mBufferManager->addItems(start, end); |
476 mContainer->addItems(start, end); |
500 mContainer->addItems(start, end); |
477 // re-set model indexes for the items including and after the added indexes |
501 // re-set model indexes for the items including and after the added indexes |
478 QList<HgWidgetItem *> items = mContainer->items(); |
502 QList<HgWidgetItem *> items = mContainer->items(); |
479 int newItemCount = items.count(); |
503 int newItemCount = items.count(); |
480 for (int i = start; i < newItemCount; i++) { |
504 for (int i = start; i < newItemCount; i++) { |
481 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
505 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
482 } |
506 } |
483 mBufferManager->flushRequestBuffers(); |
507 mBufferManager->flushRequestBuffers(); |
484 if (oldItemCount == 0 && newItemCount > 0) { |
|
485 setCurrentIndex(mModel->index(0, 0)); |
|
486 } |
|
487 q->update(); |
508 q->update(); |
488 } |
509 } |
489 } |
510 } |
490 |
511 |
491 void HgWidgetPrivate::_q_removeRows(const QModelIndex &parent, int start, int end) |
512 void HgWidgetPrivate::_q_removeRows(const QModelIndex &parent, int start, int end) |
537 } |
558 } |
538 } |
559 } |
539 |
560 |
540 void HgWidgetPrivate::_q_modelReset() |
561 void HgWidgetPrivate::_q_modelReset() |
541 { |
562 { |
|
563 FUNC_LOG; |
|
564 |
542 if (mContainer && mBufferManager) { |
565 if (mContainer && mBufferManager) { |
543 const int oldItemCount = mContainer->itemCount(); |
566 const int oldItemCount = mContainer->itemCount(); |
544 const int newItemCount = mModel->rowCount(); |
567 const int newItemCount = mModel->rowCount(); |
545 if (newItemCount == oldItemCount) { |
568 if (newItemCount == oldItemCount) { |
546 // Model is reseted but itemcount is still the same. |
569 // Model is reseted but itemcount is still the same. |
555 QList<HgWidgetItem*> items = mContainer->items(); |
578 QList<HgWidgetItem*> items = mContainer->items(); |
556 const int itemCount = items.count(); |
579 const int itemCount = items.count(); |
557 for( int i=0; i<itemCount; i++) { |
580 for( int i=0; i<itemCount; i++) { |
558 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
581 items.at(i)->setModelIndex(mModel->index(i, 0, QModelIndex())); |
559 } |
582 } |
560 |
583 |
561 // Buffermanager requests items to be updated. |
584 // Buffermanager requests items to be updated. |
562 mBufferManager->resetBuffer(0, newItemCount); |
585 mBufferManager->resetBuffer(0, newItemCount); |
563 if (mModel->rowCount() > 0) { |
586 } |
|
587 |
|
588 // Update selection model's current. |
|
589 QItemSelectionModel *selectionModel = mContainer->selectionModel(); |
|
590 if (mModel->rowCount() > 0) { |
|
591 if (selectionModel && selectionModel->currentIndex().isValid()) { |
|
592 scrollTo(selectionModel->currentIndex()); |
|
593 } |
|
594 else { |
564 setCurrentIndex(mModel->index(0, 0)); |
595 setCurrentIndex(mModel->index(0, 0)); |
565 scrollTo(mModel->index(0, 0)); |
596 scrollTo(mModel->index(0, 0)); |
566 } |
597 } |
567 } |
598 } |
568 } |
599 } |
569 } |
600 } |
570 |
601 |
571 void HgWidgetPrivate::setScrollBarMetrics(qreal pos) |
602 void HgWidgetPrivate::setScrollBarMetrics(qreal pos) |
572 { |
603 { |
625 prepareScrollBars( pos/worldSize ); |
656 prepareScrollBars( pos/worldSize ); |
626 } |
657 } |
627 |
658 |
628 void HgWidgetPrivate::adjustGeometry() |
659 void HgWidgetPrivate::adjustGeometry() |
629 { |
660 { |
630 Q_Q(HgWidget); |
661 FUNC_LOG; |
631 |
662 Q_Q(HgWidget); |
|
663 |
632 QRectF scrollAreaBoundingRect = q->boundingRect(); |
664 QRectF scrollAreaBoundingRect = q->boundingRect(); |
633 if( scrollAreaBoundingRect.isNull() || |
665 if( scrollAreaBoundingRect.isNull() || |
634 !scrollAreaBoundingRect.isValid() || |
666 !scrollAreaBoundingRect.isValid() || |
635 !mContainer || |
667 !mContainer || |
636 scrollAreaBoundingRect == mContainer->boundingRect() ) |
668 scrollAreaBoundingRect == mContainer->boundingRect() ) |
643 |
675 |
644 |
676 |
645 void HgWidgetPrivate::lostForeground() |
677 void HgWidgetPrivate::lostForeground() |
646 { |
678 { |
647 if( !mForeground ) return; |
679 if( !mForeground ) return; |
648 |
680 |
649 mForeground = false; |
681 mForeground = false; |
650 QList<HgWidgetItem*> list = mContainer->items(); |
682 QList<HgWidgetItem*> list = mContainer->items(); |
651 foreach(HgWidgetItem* item, list){ |
683 foreach(HgWidgetItem* item, list){ |
652 item->releaseItemData(); |
684 item->releaseItemData(); |
653 } |
685 } |
654 } |
686 } |
655 |
687 |
656 void HgWidgetPrivate::gainedForeground() |
688 void HgWidgetPrivate::gainedForeground() |
657 { |
689 { |
658 if( mForeground ) return; |
690 if( mForeground ) return; |
659 |
691 |
660 mForeground = true; |
692 mForeground = true; |
661 QList<HgWidgetItem*> list = mContainer->items(); |
693 QList<HgWidgetItem*> list = mContainer->items(); |
662 int bufferStart = 0; |
694 int bufferStart = 0; |
663 int bufferEnd = 0; |
695 int bufferEnd = 0; |
664 mBufferManager->currentBuffer(bufferStart,bufferEnd); |
696 mBufferManager->currentBuffer(bufferStart,bufferEnd); |
665 for(;bufferStart<=bufferEnd;bufferStart++){ |
697 for(;bufferStart<=bufferEnd;bufferStart++){ |
666 list.at(bufferStart)->updateItemData(); |
698 list.at(bufferStart)->updateItemData(); |
667 } |
699 } |
668 } |
700 } |
669 |
701 |
|
702 void HgWidgetPrivate::updateCurrentItem(const QModelIndex ¤tItem) |
|
703 { |
|
704 Q_UNUSED(currentItem); |
|
705 |
|
706 // By default do nothing |
|
707 } |
|
708 |
670 bool HgWidgetPrivate::getItemOutline(const QModelIndex& index, QPolygonF& points) |
709 bool HgWidgetPrivate::getItemOutline(const QModelIndex& index, QPolygonF& points) |
671 { |
710 { |
672 return mContainer->getItemPoints(index.row(), points); |
711 return mContainer->getItemPoints(index.row(), points); |
673 } |
712 } |
674 |
713 |
683 if (mContainer->orientation() != orientation) { |
722 if (mContainer->orientation() != orientation) { |
684 mContainer->setOrientation(orientation, q->isVisible()); |
723 mContainer->setOrientation(orientation, q->isVisible()); |
685 if (!mStaticScrollDirection) { |
724 if (!mStaticScrollDirection) { |
686 createScrollBar(orientation); |
725 createScrollBar(orientation); |
687 } |
726 } |
688 q->repolish(); |
|
689 adjustGeometry(); |
727 adjustGeometry(); |
690 } |
728 } |
691 } |
729 } |
692 |
730 |
693 void HgWidgetPrivate::_q_groovePressed(qreal value, Qt::Orientation orientation) |
731 void HgWidgetPrivate::_q_groovePressed(qreal value, Qt::Orientation orientation) |
694 { |
732 { |
695 Q_UNUSED(value); |
733 Q_UNUSED(value); |
696 Q_UNUSED(orientation); |
734 Q_UNUSED(orientation); |
697 } |
735 } |
698 |
736 |
|
737 void HgWidgetPrivate::_q_updateCurrentItem(const QModelIndex ¤t, const QModelIndex &previous) |
|
738 { |
|
739 Q_UNUSED(previous); |
|
740 |
|
741 updateCurrentItem(current); |
|
742 } |
|
743 |
699 Qt::Orientation HgWidgetPrivate::scrollDirection() const |
744 Qt::Orientation HgWidgetPrivate::scrollDirection() const |
700 { |
745 { |
701 return mContainer->orientation(); |
746 return mContainer->orientation(); |
702 } |
747 } |
703 |
748 |
704 void HgWidgetPrivate::createScrollBar(Qt::Orientation orientation) |
749 void HgWidgetPrivate::createScrollBar(Qt::Orientation orientation) |
705 { |
750 { |
706 Q_Q(HgWidget); |
751 Q_Q(HgWidget); |
707 |
752 |
708 delete mScrollBar; |
753 delete mScrollBar; |
709 mScrollBar = 0; |
754 mScrollBar = 0; |
710 mScrollBar = new HbScrollBar(orientation,q); |
755 mScrollBar = new HbScrollBar(orientation,q); |
711 if (orientation == Qt::Vertical) { |
756 if (orientation == Qt::Vertical) { |
712 HbStyle::setItemName(mScrollBar, "scrollbar-vertical"); |
757 HbStyle::setItemName(mScrollBar, "scrollbar-vertical"); |
713 } |
758 } |
714 else { |
759 else { |
715 HbStyle::setItemName(mScrollBar, "scrollbar-horizontal"); |
760 HbStyle::setItemName(mScrollBar, "scrollbar-horizontal"); |
716 } |
761 } |
717 |
762 |
718 mScrollBar->setZValue(q->zValue() + 1); |
763 mScrollBar->setZValue(q->zValue() + 1); |
719 QObject::connect(mScrollBar, SIGNAL(valueChanged(qreal, Qt::Orientation)), |
764 QObject::connect(mScrollBar, SIGNAL(valueChanged(qreal, Qt::Orientation)), |
720 q, SLOT(_q_thumbPositionChanged(qreal, Qt::Orientation))); |
765 q, SLOT(_q_thumbPositionChanged(qreal, Qt::Orientation))); |
759 item->updateItemData(); |
805 item->updateItemData(); |
760 } |
806 } |
761 } |
807 } |
762 } |
808 } |
763 mContainer->itemDataChanged(topLeft, bottomRight); |
809 mContainer->itemDataChanged(topLeft, bottomRight); |
|
810 |
|
811 if (mContainer->selectionModel()) { |
|
812 QModelIndex currentIndex = mContainer->selectionModel()->currentIndex(); |
|
813 if (currentIndex.isValid() && |
|
814 currentIndex.row() >= topLeft.row() && |
|
815 currentIndex.row() <= bottomRight.row()) { |
|
816 updateCurrentItem(currentIndex); |
|
817 } |
|
818 } |
764 } |
819 } |
765 |
820 |
766 void HgWidgetPrivate::setItemSizePolicy(HgWidget::ItemSizePolicy policy) |
821 void HgWidgetPrivate::setItemSizePolicy(HgWidget::ItemSizePolicy policy) |
767 { |
822 { |
768 mContainer->setItemSizePolicy(policy); |
823 mContainer->setItemSizePolicy(policy); |