00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ui/flipscrollview.h"
00022
00023
00024 #include <QMouseEvent>
00025 #include <QPainter>
00026 #include <QScrollBar>
00027 #include <QStack>
00028 #include <QTimeLine>
00029
00030
00031 #include <KDebug>
00032 #include <KGlobalSettings>
00033 #include <KIconLoader>
00034 #include <KColorScheme>
00035
00036 #include "ui/itemdelegate.h"
00037
00038 using namespace Kickoff;
00039
00040 class FlipScrollView::Private
00041 {
00042 public:
00043 Private(FlipScrollView *view)
00044 : q(view)
00045 , backArrowHover(false)
00046 , flipAnimTimeLine(new QTimeLine())
00047 , animLeftToRight(true)
00048 , itemHeight(-1) {
00049 }
00050
00051 ~Private() {
00052 delete flipAnimTimeLine;
00053 }
00054
00055 QModelIndex currentRoot() const {
00056 if (currentRootIndex.isValid()) {
00057 return currentRootIndex;
00058 } else {
00059 return q->rootIndex();
00060 }
00061 }
00062 QModelIndex previousRoot() const {
00063 if (previousRootIndices.isEmpty()) {
00064 return QModelIndex();
00065 }
00066 return previousRootIndices.top();
00067 }
00068
00069 void setCurrentRoot(const QModelIndex& index) {
00070 if (previousRootIndices.isEmpty() || previousRootIndices.top() != index) {
00071
00072
00073 animLeftToRight = true;
00074 hoveredIndex = QModelIndex();
00075 previousRootIndices.push(currentRootIndex);
00076 currentRootIndex = index;
00077 previousVerticalOffsets.append(q->verticalOffset());
00078 updateScrollBarRange();
00079 q->verticalScrollBar()->setValue(0);
00080 } else {
00081
00082
00083 animLeftToRight = false;
00084 hoveredIndex = currentRootIndex;
00085 previousRootIndices.pop();
00086
00087
00088
00089 currentRootIndex = index;
00090 updateScrollBarRange();
00091 q->verticalScrollBar()->setValue(previousVerticalOffsets.pop());
00092 }
00093
00094 if (q->viewOptions().direction == Qt::RightToLeft) {
00095 animLeftToRight = !animLeftToRight;
00096 }
00097
00098 flipAnimTimeLine->setCurrentTime(0);
00099 q->update();
00100 }
00101
00102 int previousVerticalOffset() {
00103 return previousVerticalOffsets.isEmpty() ? 0 : previousVerticalOffsets.top();
00104 }
00105 int treeDepth(const QModelIndex& headerIndex) const {
00106 int depth = 0;
00107 QModelIndex index = headerIndex;
00108 while (index.isValid()) {
00109 index = index.parent();
00110 depth++;
00111 }
00112 return depth;
00113 }
00114
00115 QRect headerRect(const QModelIndex& headerIndex = QModelIndex()) const {
00116 Q_UNUSED(headerIndex)
00117 QFontMetrics fm(KGlobalSettings::smallestReadableFont());
00118 const int top = ItemDelegate::TOP_OFFSET - q->verticalScrollBar()->value();
00119 int minHeight = ItemDelegate::FIRST_HEADER_HEIGHT;
00120
00121 QRect rect(backArrowRect().right() + ItemDelegate::BACK_ARROW_SPACING, top,
00122 q->width() - backArrowRect().width() - ItemDelegate::BACK_ARROW_SPACING + 1,
00123 qMax(fm.height(), minHeight) + 4 + ItemDelegate::HEADER_BOTTOM_MARGIN);
00124
00125
00126 return rect;
00127 }
00128
00129 void drawHeader(QPainter *painter, const QRectF& rect,
00130 const QModelIndex& headerIndex, QStyleOptionViewItem options) {
00131 QFontMetrics fm(KGlobalSettings::smallestReadableFont());
00132 QModelIndex branchIndex = headerIndex;
00133
00134 painter->save();
00135 painter->setFont(KGlobalSettings::smallestReadableFont());
00136 painter->setPen(QPen(q->palette().text(), 0));
00137
00138 QString currentText = i18n("All Applications");
00139 QString previousText;
00140 bool ltr = options.direction == Qt::LeftToRight;
00141 QString sep = ltr ? " > " : " < ";
00142
00143 if (branchIndex.isValid()) {
00144 currentText = branchIndex.data(Qt::DisplayRole).value<QString>();
00145 branchIndex = branchIndex.parent();
00146
00147 while (branchIndex.isValid()) {
00148 previousText.prepend(branchIndex.data(Qt::DisplayRole).value<QString>() + sep);
00149 branchIndex = branchIndex.parent();
00150 }
00151 }
00152
00153 const qreal rightMargin = q->style()->pixelMetric(QStyle::PM_ScrollBarExtent) + 6;
00154 const qreal top = rect.bottom() - fm.height() - 1 - ItemDelegate::HEADER_BOTTOM_MARGIN;
00155 QRectF textRect(rect.left(), top, rect.width() - rightMargin, fm.height());
00156 painter->setPen(QPen(KColorScheme(QPalette::Active).foreground(KColorScheme::InactiveText), 1));
00157 painter->drawText(textRect, Qt::AlignRight | Qt::AlignVCenter, currentText);
00158
00159 if (!previousText.isEmpty()) {
00160 int textWidth = fm.width(currentText) + fm.width(' ');
00161 if (ltr) {
00162 textRect.adjust(0, 0, -textWidth, 0);
00163 } else {
00164 textRect.adjust(textWidth, 0, 0, 0);
00165 }
00166
00167 painter->drawText(textRect, Qt::AlignRight, previousText);
00168 }
00169
00170 painter->restore();
00171 }
00172
00173 void drawBackArrow(QPainter *painter, QStyle::State state) {
00174 painter->save();
00175 if (state & QStyle::State_MouseOver) {
00176 painter->setBrush(q->palette().highlight());
00177 } else {
00178 painter->setBrush(q->palette().mid());
00179 }
00180
00181 QRect rect = backArrowRect();
00182
00183
00184 painter->setPen(Qt::NoPen);
00185 painter->drawRect(rect);
00186
00187 painter->setPen(QPen(q->palette().dark(), 0));
00188 painter->drawLine(backArrowRect().topRight() + QPointF(0.5, 0),
00189 backArrowRect().bottomRight() + QPointF(0.5, 0));
00190
00191
00192 if (state & QStyle::State_Enabled) {
00193 painter->setPen(Qt::NoPen);
00194
00195 if (state & QStyle::State_MouseOver) {
00196 painter->setBrush(q->palette().highlightedText());
00197 } else {
00198 painter->setBrush(q->palette().dark());
00199 }
00200 painter->translate(rect.center());
00201 if (painter->layoutDirection() == Qt::RightToLeft) {
00202 painter->rotate(180);
00203 }
00204 painter->drawPath(trianglePath());
00205 painter->resetTransform();
00206 }
00207 painter->restore();
00208 }
00209
00210 QPainterPath trianglePath(qreal width = 5, qreal height = 10) {
00211 QPainterPath path(QPointF(-width / 2, 0.0));
00212 path.lineTo(width, -height / 2);
00213 path.lineTo(width, height / 2);
00214 path.lineTo(-width / 2, 0.0);
00215
00216 return path;
00217 }
00218
00219 QRect backArrowRect() const {
00220 return QRect(0, 0, ItemDelegate::BACK_ARROW_WIDTH, q->height());
00221 }
00222
00223 void updateScrollBarRange() {
00224 int childCount = q->model()->rowCount(currentRootIndex);
00225 int pageSize = q->height();
00226 int headerHeight = headerRect(currentRoot()).height();
00227 int itemH = q->sizeHintForIndex(q->model()->index(0, 0)).height();
00228 q->verticalScrollBar()->setRange(0, (childCount * itemH) +
00229 headerHeight - pageSize);
00230 q->verticalScrollBar()->setPageStep(pageSize);
00231 q->verticalScrollBar()->setSingleStep(itemH);
00232 }
00233
00234 FlipScrollView * const q;
00235 bool backArrowHover;
00236 QPersistentModelIndex hoveredIndex;
00237 QPersistentModelIndex watchedIndexForDrag;
00238
00239 QTimeLine *flipAnimTimeLine;
00240 bool animLeftToRight;
00241
00242 int itemHeight;
00243 static const int FLIP_ANIM_DURATION = 200;
00244
00245 private:
00246 QPersistentModelIndex currentRootIndex;
00247 QStack<QPersistentModelIndex> previousRootIndices;
00248 QStack<int> previousVerticalOffsets;
00249 };
00250
00251 FlipScrollView::FlipScrollView(QWidget *parent)
00252 : QAbstractItemView(parent)
00253 , d(new Private(this))
00254 {
00255 connect(this, SIGNAL(clicked(QModelIndex)), this, SLOT(openItem(QModelIndex)));
00256 connect(d->flipAnimTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(updateFlipAnimation(qreal)));
00257 d->flipAnimTimeLine->setDuration(Private::FLIP_ANIM_DURATION);
00258 d->flipAnimTimeLine->setCurrentTime(Private::FLIP_ANIM_DURATION);
00259 setIconSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium));
00260 setMouseTracking(true);
00261 setAutoScroll(true);
00262 QPalette viewPalette(palette());
00263 viewPalette.setColor(QPalette::Window, palette().color(QPalette::Active, QPalette::Base));
00264 setPalette(viewPalette);
00265 setAutoFillBackground(true);
00266 }
00267 FlipScrollView::~FlipScrollView()
00268 {
00269 delete d;
00270 }
00271 void FlipScrollView::viewRoot()
00272 {
00273 QModelIndex index;
00274 while (d->currentRoot().isValid()) {
00275 index = d->currentRoot();
00276 d->setCurrentRoot(d->currentRoot().parent());
00277 setCurrentIndex(index);
00278 }
00279 update(d->hoveredIndex);
00280 d->hoveredIndex = index;
00281 }
00282
00283 QModelIndex FlipScrollView::indexAt(const QPoint& point) const
00284 {
00285 int topOffset = d->headerRect(d->currentRoot()).height() - verticalOffset();
00286 int items = model()->rowCount(d->currentRoot());
00287
00288 int rowIndex = (point.y() - topOffset) / itemHeight();
00289
00290 QRect itemRect = rect();
00291 itemRect.setTop(itemRect.top() + topOffset);
00292 itemRect.setLeft(d->backArrowRect().right() + ItemDelegate::BACK_ARROW_SPACING);
00293
00294 if (rowIndex < items && itemRect.contains(point)) {
00295 return model()->index(rowIndex, 0, d->currentRoot());
00296 } else {
00297 return QModelIndex();
00298 }
00299 }
00300
00301 int FlipScrollView::itemHeight() const
00302 {
00303
00304 if (d->itemHeight < 1) {
00305 QModelIndex index = model()->index(0, 0, d->currentRoot());
00306 d->itemHeight = sizeHintForIndex(index).height();
00307 }
00308
00309 return d->itemHeight;
00310 }
00311
00312 void FlipScrollView::scrollTo(const QModelIndex& index , ScrollHint hint)
00313 {
00314 if (!index.isValid()) {
00315 return;
00316 }
00317
00318 QRect itemRect = visualRect(index);
00319 if (itemRect.isValid() && hint == EnsureVisible) {
00320 if (itemRect.top() < 0) {
00321 verticalScrollBar()->setValue(verticalScrollBar()->value() +
00322 itemRect.top());
00323 } else if (itemRect.bottom() > height()) {
00324 verticalScrollBar()->setValue(verticalScrollBar()->value() +
00325 (itemRect.bottom() - height()));
00326 }
00327 }
00328 }
00329
00330 bool FlipScrollView::isIndexHidden(const QModelIndex&) const
00331 {
00332 return false;
00333 }
00334
00335 QRect FlipScrollView::visualRect(const QModelIndex& index) const
00336 {
00337 int topOffset = d->headerRect(index.parent()).height();
00338 int leftOffset = d->backArrowRect().width() + ItemDelegate::BACK_ARROW_SPACING;
00339
00340 if (index.parent() != d->currentRoot() &&
00341 index.parent() != d->previousRoot() &&
00342 index.parent() != (QModelIndex)d->hoveredIndex) {
00343 return QRect();
00344 }
00345
00346 bool parentIsPreviousRoot = d->previousRoot().isValid() && index.parent() == d->previousRoot();
00347 if (parentIsPreviousRoot && d->flipAnimTimeLine->state() == QTimeLine::NotRunning) {
00348 return QRect();
00349 }
00350
00351 if (parentIsPreviousRoot) {
00352 topOffset -= d->previousVerticalOffset();
00353 } else {
00354 topOffset -= verticalOffset();
00355 }
00356
00357
00358
00359
00360
00361
00362
00363 int scrollBarWidth = verticalScrollBar()->isVisible() ?
00364 verticalScrollBar()->width() : 0;
00365 QRectF itemRect(leftOffset, topOffset + index.row() * itemHeight(),
00366 width() - leftOffset - scrollBarWidth - ItemDelegate::BACK_ARROW_SPACING,
00367 itemHeight());
00368
00369 const qreal timeValue = d->flipAnimTimeLine->currentValue();
00370 if (index.parent() == d->currentRoot()) {
00371 if (d->animLeftToRight) {
00372 itemRect.translate(itemRect.width() * (1 - timeValue), 0);
00373 } else {
00374 itemRect.translate(-itemRect.width() * (1 - timeValue), 0);
00375 }
00376 } else {
00377 if (d->animLeftToRight) {
00378 itemRect.translate((-timeValue*itemRect.width()), 0);
00379 } else {
00380 itemRect.translate((timeValue*itemRect.width()), 0);
00381 }
00382 }
00383 return itemRect.toRect();
00384 }
00385
00386 int FlipScrollView::horizontalOffset() const
00387 {
00388 return 0;
00389 }
00390
00391 int FlipScrollView::verticalOffset() const
00392 {
00393 return verticalScrollBar()->value();
00394 }
00395
00396 QRegion FlipScrollView::visualRegionForSelection(const QItemSelection& selection) const
00397 {
00398 QRegion region;
00399 foreach(const QModelIndex& index , selection.indexes()) {
00400 region |= visualRect(index);
00401 }
00402 return region;
00403 }
00404 QModelIndex FlipScrollView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers)
00405 {
00406 QModelIndex index = currentIndex();
00407
00408 switch (cursorAction) {
00409 case MoveUp:
00410 if (!currentIndex().isValid()) {
00411 index = model()->index(model()->rowCount(d->currentRoot()) - 1, 0, d->currentRoot());
00412 } else if (currentIndex().row() > 0) {
00413 index = currentIndex().sibling(currentIndex().row() - 1,
00414 currentIndex().column());
00415 }
00416 break;
00417 case MoveDown:
00418 if (!currentIndex().isValid()) {
00419 index = model()->index(0, 0, d->currentRoot());
00420 } else if (currentIndex().row() <
00421 model()->rowCount(currentIndex().parent()) - 1) {
00422 index = currentIndex().sibling(currentIndex().row() + 1,
00423 currentIndex().column());
00424 }
00425 break;
00426 case MoveLeft:
00427 if (d->currentRoot().isValid()) {
00428 index = d->currentRoot();
00429 d->setCurrentRoot(d->currentRoot().parent());
00430 setCurrentIndex(index);
00431 }
00432 break;
00433 case MoveRight:
00434 if (model()->hasChildren(currentIndex())) {
00435 openItem(currentIndex());
00436
00437 index = currentIndex();
00438 }
00439 break;
00440 default:
00441
00442 break;
00443 }
00444
00445
00446 update(d->hoveredIndex);
00447 d->hoveredIndex = index;
00448
00449
00450
00451 return index;
00452 }
00453
00454 void FlipScrollView::setSelection(const QRect& rect , QItemSelectionModel::SelectionFlags flags)
00455 {
00456 QItemSelection selection;
00457 selection.select(indexAt(rect.topLeft()), indexAt(rect.bottomRight()));
00458 selectionModel()->select(selection, flags);
00459 }
00460
00461 void FlipScrollView::openItem(const QModelIndex& index)
00462 {
00463 if (model()->canFetchMore(index)) {
00464 model()->fetchMore(index);
00465 }
00466
00467 bool hasChildren = model()->hasChildren(index);
00468
00469 if (hasChildren) {
00470 d->setCurrentRoot(index);
00471 setCurrentIndex(model()->index(0, 0, index));
00472 } else {
00473
00474 }
00475 }
00476
00477 void FlipScrollView::resizeEvent(QResizeEvent*)
00478 {
00479 d->updateScrollBarRange();
00480 }
00481
00482 void FlipScrollView::mousePressEvent(QMouseEvent *event)
00483 {
00484 d->watchedIndexForDrag = indexAt(event->pos());
00485 QAbstractItemView::mousePressEvent(event);
00486 }
00487
00488 void FlipScrollView::mouseReleaseEvent(QMouseEvent *event)
00489 {
00490 d->watchedIndexForDrag = QModelIndex();
00491
00492 if (d->backArrowRect().contains(event->pos()) && d->currentRoot().isValid()) {
00493
00494 d->setCurrentRoot(d->currentRoot().parent());
00495 setDirtyRegion(rect());
00496 } else {
00497 QAbstractItemView::mouseReleaseEvent(event);
00498 }
00499 }
00500
00501 void FlipScrollView::mouseMoveEvent(QMouseEvent *event)
00502 {
00503 bool mouseOverBackArrow = d->backArrowRect().contains(event->pos());
00504
00505 if (mouseOverBackArrow != d->backArrowHover) {
00506 d->backArrowHover = mouseOverBackArrow;
00507 setDirtyRegion(d->backArrowRect());
00508 } else {
00509 const QModelIndex itemUnderMouse = indexAt(event->pos());
00510 if (itemUnderMouse != d->hoveredIndex) {
00511 update(itemUnderMouse);
00512 update(d->hoveredIndex);
00513
00514 d->hoveredIndex = itemUnderMouse;
00515 setCurrentIndex(d->hoveredIndex);
00516 }
00517
00518 QAbstractItemView::mouseMoveEvent(event);
00519 }
00520 }
00521
00522 void FlipScrollView::keyPressEvent(QKeyEvent *event)
00523 {
00524 if (event->key() == Qt::Key_Enter ||
00525 event->key() == Qt::Key_Return) {
00526 moveCursor(MoveRight, event->modifiers());
00527 event->accept();
00528 return;
00529 }
00530
00531 if (event->key() == Qt::Key_Escape &&
00532 d->currentRoot().isValid()) {
00533 moveCursor(MoveLeft, event->modifiers());
00534 event->accept();
00535 return;
00536 }
00537
00538 QAbstractItemView::keyPressEvent(event);
00539 }
00540
00541 void FlipScrollView::leaveEvent(QEvent *event)
00542 {
00543 d->hoveredIndex = QModelIndex();
00544 setCurrentIndex(QModelIndex());
00545 }
00546
00547 void FlipScrollView::paintItems(QPainter &painter, QPaintEvent *event, QModelIndex &root)
00548 {
00549 const int rows = model()->rowCount(root);
00550
00551
00552 for (int i = 0; i < rows; ++i) {
00553 QModelIndex index = model()->index(i, 0, root);
00554
00555 QStyleOptionViewItem option = viewOptions();
00556 option.rect = visualRect(index);
00557
00558
00559
00560 if (!event->rect().intersects(option.rect)) {
00561 continue;
00562 }
00563
00564 if (selectionModel()->isSelected(index)) {
00565 option.state |= QStyle::State_Selected;
00566 }
00567
00568 if (index == d->hoveredIndex) {
00569 option.state |= QStyle::State_MouseOver;
00570 }
00571
00572 if (index == currentIndex()) {
00573 option.state |= QStyle::State_HasFocus;
00574 }
00575
00576 itemDelegate(index)->paint(&painter, option, index);
00577
00578 if (model()->hasChildren(index)) {
00579 painter.save();
00580 painter.setPen(Qt::NoPen);
00581
00582
00583
00584 if (option.state & QStyle::State_MouseOver) {
00585 painter.setBrush(palette().highlight());
00586 } else {
00587 painter.setBrush(palette().text());
00588 }
00589
00590 QRect triRect = option.rect;
00591 QPainterPath tPath = d->trianglePath();
00592 if (option.direction == Qt::LeftToRight) {
00593 triRect.setLeft(triRect.right() - ItemDelegate::ITEM_RIGHT_MARGIN);
00594 painter.translate(triRect.center().x() - 6, triRect.y() + (option.rect.height() / 2));
00595
00596 } else {
00597 triRect.setRight(triRect.left() + ItemDelegate::ITEM_RIGHT_MARGIN);
00598 painter.translate(triRect.center().x() + 6, triRect.y() + (option.rect.height() / 2));
00599
00600 }
00601
00602
00603 if (option.direction == Qt::LeftToRight) {
00604 painter.rotate(180);
00605 }
00606
00607 painter.drawPath(tPath);
00608 painter.resetTransform();
00609 painter.restore();
00610 }
00611 }
00612 }
00613
00614 void FlipScrollView::paintEvent(QPaintEvent * event)
00615 {
00616 QPalette viewPalette(palette());
00617 viewPalette.setColor(QPalette::Window, palette().color(QPalette::Active, QPalette::Base));
00618 setPalette(viewPalette);
00619 setAutoFillBackground(true);
00620
00621 QPainter painter(viewport());
00622 painter.setRenderHint(QPainter::Antialiasing);
00623
00624
00625 QModelIndex currentRoot = d->currentRoot();
00626 QModelIndex previousRoot = d->animLeftToRight ? d->previousRoot() : (QModelIndex)d->hoveredIndex;
00627
00628
00629 paintItems(painter, event, currentRoot);
00630
00631 const qreal timerValue = d->flipAnimTimeLine->currentValue();
00632
00633 if (timerValue < 1.0) {
00634
00635 paintItems(painter, event, previousRoot);
00636
00637 if (d->flipAnimTimeLine->state() != QTimeLine::Running) {
00638 d->flipAnimTimeLine->start();
00639 }
00640 }
00641
00642 QRectF eventRect = event->rect();
00643
00644
00645 QRectF headerRect = d->headerRect(currentRoot);
00646 if (d->animLeftToRight) {
00647 headerRect.translate(headerRect.width() * (1 - timerValue), 0);
00648 } else {
00649 headerRect.translate(-headerRect.width() * (1 - timerValue), 0);
00650 }
00651
00652 if (eventRect.intersects(headerRect)) {
00653 d->drawHeader(&painter, headerRect, currentRoot, viewOptions());
00654 }
00655
00656
00657 QRectF prevHeaderRect = d->headerRect(previousRoot);
00658 if (d->animLeftToRight) {
00659 prevHeaderRect.translate(-prevHeaderRect.width() * timerValue, 0);
00660 } else {
00661 prevHeaderRect.translate(prevHeaderRect.width() * timerValue, 0);
00662 }
00663
00664 if (eventRect.intersects(prevHeaderRect) && timerValue < 1.0) {
00665 d->drawHeader(&painter, prevHeaderRect, previousRoot, viewOptions());
00666 }
00667
00668
00669 QStyle::State state = 0;
00670 if (currentRoot.isValid()) {
00671 state |= QStyle::State_Enabled;
00672 }
00673
00674 if (d->backArrowHover) {
00675 state |= QStyle::State_MouseOver;
00676 }
00677
00678 if (currentRoot.isValid() || previousRoot.isValid()) {
00679 qreal opacity = 1.0;
00680 if (!previousRoot.isValid()) {
00681 opacity = timerValue;
00682 } else if (!currentRoot.isValid()) {
00683 opacity = 1 - timerValue;
00684 }
00685
00686 painter.save();
00687 painter.setOpacity(opacity);
00688 d->drawBackArrow(&painter, state);
00689 painter.restore();
00690 }
00691 }
00692
00693 void FlipScrollView::startDrag(Qt::DropActions supportedActions)
00694 {
00695 kDebug() << "Starting UrlItemView drag with actions" << supportedActions;
00696
00697 if (!d->watchedIndexForDrag.isValid()) {
00698 return;
00699 }
00700
00701 QDrag *drag = new QDrag(this);
00702 QMimeData *mimeData = model()->mimeData(selectionModel()->selectedIndexes());
00703
00704 if (mimeData->text().isNull()) {
00705 return;
00706 }
00707
00708 drag->setMimeData(mimeData);
00709
00710 QModelIndex idx = selectionModel()->selectedIndexes().first();
00711 QIcon icon = idx.data(Qt::DecorationRole).value<QIcon>();
00712 drag->setPixmap(icon.pixmap(IconSize(KIconLoader::Desktop)));
00713
00714 Qt::DropAction dropAction = drag->exec();
00715 QAbstractItemView::startDrag(supportedActions);
00716 }
00717
00718 void FlipScrollView::updateFlipAnimation(qreal)
00719 {
00720 setDirtyRegion(rect());
00721 }
00722
00723 #include "flipscrollview.moc"