diff options
author | Stanislav Ionascu <stanislav.ionascu@nokia.com> | 2010-04-28 13:55:56 +0300 |
---|---|---|
committer | Daniel d'Andrada <daniel.dandrada@nokia.com> | 2010-05-06 10:21:27 +0300 |
commit | 2cc6e40c2229e8ca5300016c06aeb1d777edcef3 (patch) | |
tree | 21944c09978595296dd5d2d9c786ec78f1cc0f2c | |
parent | 4b3e1fb373589217991394ed324743a3a64b3bd4 (diff) |
Changes: List index widget implementations for fast navigation in list content.
RevBy: Daniel d'Andrada, Sergyi Dubovik, Tomas Junnonen.
Details: Widget container of shortcuts to list group headers, for fast navigation through grouped list content.
-rw-r--r-- | demos/widgetsgallery/mlistpage.cpp | 25 | ||||
-rw-r--r-- | demos/widgetsgallery/mlistpage.h | 1 | ||||
-rw-r--r-- | demos/widgetsgallery/phonebookmodel.cpp | 203 | ||||
-rw-r--r-- | demos/widgetsgallery/phonebookmodel.h | 13 | ||||
-rw-r--r-- | src/corelib/widgets/widgets.pri | 1 | ||||
-rw-r--r-- | src/views/mlistindexview.cpp | 290 | ||||
-rw-r--r-- | src/views/mlistindexview.h | 67 | ||||
-rw-r--r-- | src/views/mlistindexview_p.h | 83 | ||||
-rw-r--r-- | src/views/mlistview.cpp | 8 | ||||
-rw-r--r-- | src/views/mlistview.h | 2 | ||||
-rw-r--r-- | src/views/mlistview_p.cpp | 21 | ||||
-rw-r--r-- | src/views/mlistview_p.h | 6 | ||||
-rw-r--r-- | src/views/style/mlistindexstyle.h | 38 | ||||
-rw-r--r-- | src/views/style/style.pri | 1 | ||||
-rw-r--r-- | src/views/views.pri | 4 | ||||
-rw-r--r-- | src/views/widgets/mlistindex.cpp | 50 | ||||
-rw-r--r-- | src/views/widgets/mlistindex.h | 78 | ||||
-rw-r--r-- | src/views/widgets/mlistindexmodel.h | 39 | ||||
-rw-r--r-- | src/views/widgets/widgets.pri | 3 | ||||
-rw-r--r-- | tests/ut_mlistviewgroupheader/ut_mlistviewgroupheader.pro | 20 | ||||
-rw-r--r-- | tests/ut_mlistviewmulticolumn/ut_mlistviewmulticolumn.pro | 20 | ||||
-rw-r--r-- | tests/ut_mlistviewseparators/ut_mlistviewseparators.pro | 22 |
22 files changed, 926 insertions, 69 deletions
diff --git a/demos/widgetsgallery/mlistpage.cpp b/demos/widgetsgallery/mlistpage.cpp index de841c4a..e7304c1e 100644 --- a/demos/widgetsgallery/mlistpage.cpp +++ b/demos/widgetsgallery/mlistpage.cpp @@ -115,11 +115,11 @@ public: int flatRow = index.row(); int row = flatRow / amountOfColumns; int column = flatRow % amountOfColumns; - int totalItems = index.model()->rowCount(); + int totalItems = index.model()->rowCount(index.parent()); int columns = amountOfColumns; - int rows = index.model()->rowCount() / amountOfColumns; - if(index.model()->rowCount() % amountOfColumns) + int rows = totalItems / amountOfColumns; + if (totalItems % amountOfColumns) rows += 1; bool last = (row == (rows - 1) && flatRow == (totalItems - 1)); @@ -267,9 +267,7 @@ void MListPage::createActions() connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(changeSortingOrder(int))); QStringList listModeList; - listModeList << "Plain"; - // Not implemented yet - // listModeList << "Grouped"; + listModeList << "Plain" << "Grouped"; combo = createComboBoxAction("List mode", listModeList); connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(changeListMode(int))); @@ -325,15 +323,22 @@ void MListPage::changeSortingOrder(int index) #ifndef HAVE_N900 void MListPage::changeAmountOfItemInList(int index) -{ +{ Q_ASSERT(index >= 0 && index < 4); + if(currentListModeIndex == Grouped) { + proxyModel->setShowGroups(false); + list->setShowGroups(false); + } + + if (model->rowCount() > 0) model->removeRows(0, model->rowCount()); int amountOfItems[4] = {50, 100, 200, 1000}; model->insertRows(0, amountOfItems[index]); changeSortingOrder(currentSortingIndex); + changeListMode(currentListModeIndex); } #endif @@ -345,6 +350,7 @@ void MListPage::changeListMode(int index) #ifndef HAVE_N900 proxyModel->setShowGroups(false); #endif + break; case Grouped: @@ -354,6 +360,9 @@ void MListPage::changeListMode(int index) #endif break; } + + currentListModeIndex = index; + changeSortingOrder(currentSortingIndex); loadPicturesInVisibleItems(); } @@ -386,7 +395,7 @@ void MListPage::changeSeparatorsMode(int index) Q_ASSERT(index >= 0 && index <= 1); bool enableSeparators = (index == 1); - if(enableSeparators) + if (enableSeparators) list->setObjectName("wgListWithSeparators"); else list->setObjectName("wgList"); diff --git a/demos/widgetsgallery/mlistpage.h b/demos/widgetsgallery/mlistpage.h index 4c90f12b..aea16d5f 100644 --- a/demos/widgetsgallery/mlistpage.h +++ b/demos/widgetsgallery/mlistpage.h @@ -111,6 +111,7 @@ private: QModelIndex longTappedIndex; int currentSortingIndex; + int currentListModeIndex; }; diff --git a/demos/widgetsgallery/phonebookmodel.cpp b/demos/widgetsgallery/phonebookmodel.cpp index 302ab792..17878d85 100644 --- a/demos/widgetsgallery/phonebookmodel.cpp +++ b/demos/widgetsgallery/phonebookmodel.cpp @@ -24,15 +24,15 @@ #include <QStringList> #include <QTextStream> #include <QTimer> -#include <QDebug> + #include <MTheme> -#include <MDebug> PhoneBookModel::PhoneBookModel() { namesList = loadFakeNames(); imageIdList = loadFakeImageIds(); defaultThumbnail = QImage(Utils::imagesDir() + "DefaultAvatar.png"); + modelRowCount = 0; } PhoneBookModel::~PhoneBookModel() @@ -130,7 +130,7 @@ int PhoneBookModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return phoneBookEntries.size(); + return modelRowCount; } int PhoneBookModel::columnCount(const QModelIndex &parent) const @@ -142,26 +142,33 @@ int PhoneBookModel::columnCount(const QModelIndex &parent) const bool PhoneBookModel::insertRows(int row, int count, const QModelIndex &parent) { + emit layoutAboutToBeChanged(); beginInsertRows(parent, row, row + count - 1); - for (int i = 0; i < count; i++) { + for (int i = phoneBookEntries.size(); i < count; i++) { PhoneBookEntry *entry = generateEntry(); phoneBookEntries.append(entry); } + if(!parent.isValid()) + modelRowCount += count; + endInsertRows(); + emit layoutChanged(); return true; } bool PhoneBookModel::removeRows(int row, int count, const QModelIndex &parent) { + emit layoutAboutToBeChanged(); if (count <= 0) return true; //Successfully removed 0 rows. beginRemoveRows(parent, row, row + count - 1); - qDeleteAll(phoneBookEntries.begin() + row, phoneBookEntries.begin() + row + count); - phoneBookEntries.remove(row, count); + modelRowCount -= count; endRemoveRows(); + + emit layoutChanged(); return true; } @@ -170,6 +177,24 @@ void PhoneBookModel::thumbnailWasLoaded(const QModelIndex &index) emit dataChanged(index, index); } +void PhoneBookModel::sort(int column, Qt::SortOrder order) +{ + Q_UNUSED(column); + + for (int i = 0; i < phoneBookEntries.size(); i++) { + for (int j = i + 1; j < phoneBookEntries.size(); j++) { + PhoneBookEntry *iEntry = phoneBookEntries.at(i); + PhoneBookEntry *jEntry = phoneBookEntries.at(j); + if((order == Qt::AscendingOrder && iEntry->fullName > jEntry->fullName) || + (order == Qt::DescendingOrder && iEntry->fullName < jEntry->fullName)) { + phoneBookEntries.replace(i, jEntry); + phoneBookEntries.replace(j, iEntry); + } + } + } +} + + PhoneBookImageLoader::PhoneBookImageLoader() { @@ -182,26 +207,33 @@ PhoneBookImageLoader::~PhoneBookImageLoader() void PhoneBookImageLoader::loadPictures(const QModelIndex &firstVisibleRow, const QModelIndex &lastVisibleRow) { - int rowCount = lastVisibleRow.row(); + if (!firstVisibleRow.isValid() || !lastVisibleRow.isValid()) + return; - for (int i = firstVisibleRow.row(); i <= rowCount; i++) { - QModelIndex index(firstVisibleRow.sibling(i, 0)); - if (!index.isValid()) - continue; - QVariant data = index.data(Qt::DisplayRole); - PhoneBookEntry *entry = static_cast<PhoneBookEntry *>(data.value<void *>()); + QModelIndex topLeftRow = firstVisibleRow; + QModelIndex bottomRightRow = lastVisibleRow; - // May happen if size of list model was changed - if (entry == NULL) - continue; + if (firstVisibleRow.parent().isValid()) + topLeftRow = firstVisibleRow.parent(); - if (entry->thumbnailId.isEmpty()) - continue; + if (lastVisibleRow.parent().isValid()) + bottomRightRow = lastVisibleRow.parent(); - Job job; - job.entry = entry; - job.row = index; - thumbnailLoadingJobs << job; + int rowCount = bottomRightRow.row(); + + for (int i = topLeftRow.row(); i <= rowCount; i++) { + QModelIndex index(topLeftRow.sibling(i, 0)); + + if (index.isValid()) { + if (index.model()->hasChildren(index) && !index.parent().isValid()) { + for (int ci = 0; ci < index.model()->rowCount(index); ci++) { + QModelIndex cIndex(index.model()->index(ci, 0, index)); + if (cIndex.isValid()) + addJob(cIndex); + } + } else + addJob(index); + } } // processJobQueue will issue single shots to continue loading images @@ -209,6 +241,24 @@ void PhoneBookImageLoader::loadPictures(const QModelIndex &firstVisibleRow, cons QTimer::singleShot(0, this, SLOT(processJobQueue())); } +void PhoneBookImageLoader::addJob(const QModelIndex &index) +{ + QVariant data = index.data(Qt::DisplayRole); + PhoneBookEntry *entry = static_cast<PhoneBookEntry *>(data.value<void *>()); + + // May happen if size of list model was changed + if (entry == NULL) + return; + + if (entry->thumbnailId.isEmpty()) + return; + + Job job; + job.entry = entry; + job.row = index; + thumbnailLoadingJobs << job; +} + void PhoneBookImageLoader::stopLoadingPictures() { // Lets not process any more requests to load image because list is panning now @@ -227,7 +277,10 @@ void PhoneBookImageLoader::processJobQueue() // indicate that thumbnail was loaded entry->thumbnailId = ""; - notifyModel(job.row); + if (job.row.parent().isValid()) + notifyModel(job.row.model()->index(job.row.row(), 0, job.row.parent())); + else + notifyModel(job.row); // Continue loading and letting UI thread do something if (thumbnailLoadingJobs.count() > 0) @@ -278,32 +331,75 @@ void PhoneBookSortedModel::thumbnailWasLoaded(const QModelIndex &index) void PhoneBookSortedModel::setShowGroups(bool showGroups) { - this->showGroups = showGroups; - if (showGroups) - populateGroupHeaderIndex(); + if (this->showGroups != showGroups) { + this->showGroups = showGroups; + if (this->showGroups) { + sort(0, Qt::AscendingOrder); + createGroupedModel(); + } + else + createPlainModel(); + } +} + + +void PhoneBookSortedModel::createPlainModel() +{ + int plainRowCount = totalRowCount(); + treeHeaderIndex.clear(); + + removeRows(0, rowCount()); + insertRows(0, plainRowCount); } -void PhoneBookSortedModel::populateGroupHeaderIndex() +void PhoneBookSortedModel::createGroupedModel() { - int count = QSortFilterProxyModel::rowCount(); - for (int i = 0; i < count; i++) { - QString name = QSortFilterProxyModel::data(index(i, 0), PhoneBookModel::PhoneBookSortRole).toString(); - QChar firstLetter = name[0]; - if (groupHeaderIndex.contains(firstLetter)) - continue; + treeHeaderIndex.clear(); + + QVector<PhoneBookEntry *> phoneBookEntries; + for (int i = 0; i < sourceModel()->rowCount(); i++) { + PhoneBookEntry *entry = static_cast<PhoneBookEntry *>(sourceModel()->data(sourceModel()->index(i, 0), Qt::DisplayRole).value<void *>()); + phoneBookEntries.append(entry); + QChar firstLetter = sourceModel()->data(sourceModel()->index(i, 0), PhoneBookModel::PhoneBookSortRole).toString()[0]; - groupHeaderIndex.insert(firstLetter, i); + treeHeaderIndex[firstLetter].push_back(entry); + } + + removeRows(0, rowCount()); + + insertRows(0, treeHeaderIndex.keys().count(), QModelIndex()); + for (int i = 0; i < treeHeaderIndex.keys().count(); i++) { + QChar key = treeHeaderIndex.keys()[i]; + int count = treeHeaderIndex[key].count(); + insertRows(0, count, index(i, 0, QModelIndex())); } } -QModelIndex PhoneBookSortedModel::parent(const QModelIndex &child) const +int PhoneBookSortedModel::totalRowCount() { - if (showGroups) { + int totalRowCount = 0; - } else { - return QSortFilterProxyModel::parent(child); + foreach(PhoneBookEntryVector entries, treeHeaderIndex.values()) { + totalRowCount += entries.count(); } + return totalRowCount; +} + +void PhoneBookSortedModel::sort(int column, Qt::SortOrder order) +{ + Q_UNUSED(column); + + if(showGroups) + return; + + sourceModel()->sort(column, order); + + emit dataChanged(index(0, 0), index(rowCount(), 0)); +} + +QModelIndex PhoneBookSortedModel::parent(const QModelIndex &child) const +{ return QSortFilterProxyModel::parent(child); } @@ -311,25 +407,38 @@ int PhoneBookSortedModel::rowCount(const QModelIndex &parent) const { if (showGroups) { if (!parent.isValid()) { - return groupHeaderIndex.count(); - } else { - return 2; + return treeHeaderIndex.keys().count(); + } else if (parent.row() < treeHeaderIndex.keys().count()) { + QChar key = treeHeaderIndex.keys().at(parent.row()); + return treeHeaderIndex[key].count(); } } - return QSortFilterProxyModel::rowCount(parent); } bool PhoneBookSortedModel::hasChildren(const QModelIndex &parent) const { - if (showGroups) { + if (showGroups && parent.isValid() && !parent.parent().isValid()) return true; - } - - return QSortFilterProxyModel::hasChildren(parent); + else + return false; } QVariant PhoneBookSortedModel::data(const QModelIndex &index, int role) const { - return QSortFilterProxyModel::data(index, role); + if (showGroups && index.isValid()) { + if (role == Qt::DisplayRole) { + if (!index.parent().isValid()) { + return QVariant::fromValue(treeHeaderIndex.keys().at(index.row())); + } else { + QChar key = treeHeaderIndex.uniqueKeys().at(index.parent().row()); + PhoneBookEntry *entry = treeHeaderIndex[key].at(index.row()); + return QVariant::fromValue(static_cast<void *>(entry)); + } + } + } + if (index.isValid()) + return QSortFilterProxyModel::data(index, role); + + return QVariant(); } diff --git a/demos/widgetsgallery/phonebookmodel.h b/demos/widgetsgallery/phonebookmodel.h index 852d9494..b3e849ea 100644 --- a/demos/widgetsgallery/phonebookmodel.h +++ b/demos/widgetsgallery/phonebookmodel.h @@ -55,6 +55,7 @@ public Q_SLOTS: void processJobQueue(); private: + void addJob(const QModelIndex &index); void notifyModel(const QModelIndex &index); private: @@ -84,6 +85,7 @@ public: void thumbnailWasLoaded(const QModelIndex &index); + void sort(int column, Qt::SortOrder order); private: QStringList loadFakeNames(); QStringList loadFakeImageIds(); @@ -95,11 +97,14 @@ private: QStringList namesList; QStringList imageIdList; QImage defaultThumbnail; + int modelRowCount; }; class PhoneBookSortedModel : public QSortFilterProxyModel { public: + typedef QVector<PhoneBookEntry*> PhoneBookEntryVector; +public: PhoneBookSortedModel(); virtual ~PhoneBookSortedModel(); void thumbnailWasLoaded(const QModelIndex &index); @@ -107,6 +112,7 @@ public: void setShowGroups(bool showGroups); public: + void sort(int column, Qt::SortOrder order); QModelIndex parent(const QModelIndex &child) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; bool hasChildren(const QModelIndex &parent = QModelIndex()) const; @@ -117,11 +123,14 @@ public: QModelIndex mapToSource(const QModelIndex &proxyIndex) const; private: - void populateGroupHeaderIndex(); + void createPlainModel(); + void createGroupedModel(); + + int totalRowCount(); private: bool showGroups; - QHash<QChar, int> groupHeaderIndex; + QMap<QChar, PhoneBookEntryVector> treeHeaderIndex; }; #endif diff --git a/src/corelib/widgets/widgets.pri b/src/corelib/widgets/widgets.pri index 7055cd11..be1ef10f 100644 --- a/src/corelib/widgets/widgets.pri +++ b/src/corelib/widgets/widgets.pri @@ -54,7 +54,6 @@ PUBLIC_HEADERS += \ $$WIDGETS_SRC_DIR/mabstractcellcreator.h \ $$WIDGETS_SRC_DIR/mcontentitem.h \ - MGEN_MODEL_HEADERS += \ $$WIDGETS_SRC_DIR/mwidgetmodel.h \ $$WIDGETS_SRC_DIR/mbuttonmodel.h \ diff --git a/src/views/mlistindexview.cpp b/src/views/mlistindexview.cpp new file mode 100644 index 00000000..bf95cf35 --- /dev/null +++ b/src/views/mlistindexview.cpp @@ -0,0 +1,290 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "mlistindexview.h" +#include "mlistindexview_p.h" +#include "mlistview_p.h" + +#include <MApplicationPage> +#include <MLabel> +#include <MPannableViewport> +#include <MScalableImage> +#include <MSceneManager> + +#include <QGraphicsSceneMouseEvent> +#include <qmath.h> + +#include "mlistindex.h" +#include "mlist.h" + +MListIndexViewPrivate::MListIndexViewPrivate() +{ + shortcutHeight = 0; + eventScene = NULL; + container = NULL; +} + +MListIndexViewPrivate::~MListIndexViewPrivate() +{ + clearVisible(); +} + +void MListIndexViewPrivate::initLayout() +{ + clearVisible(); + + if (controller->model()) { + controllerModel = controller->model(); + shortcutsCount = 0; + + createContainer(); + installSceneEventHandler(); + + if (controller->model()->shortcutLabels().count() > 0) { + //create the first shortcut label and get the font metrics from it + MLabel *firstShortcut = createLabel(0); + shortcuts.append(firstShortcut); + + QFontMetrics fm(firstShortcut->font()); + shortcutHeight = fm.height(); + + shortcutsCount = controllerModel->shortcutLabels().count(); + updateVisible(); + } + + disconnect(this, SLOT(listParentChanged())); + if (controllerModel && controllerModel->list()) { + connect(controllerModel->list(), SIGNAL(parentChanged()), this, SLOT(listParentChanged())); + } + + } +} + +void MListIndexViewPrivate::updateLayout() +{ + if(container) { + controller->resize(controller->preferredWidth(), containerRect.height()); + controller->setPos((containerRect.x() + containerRect.width()) - controller->preferredWidth(), containerRect.y()); + } + updateShortcutPositions(); +} + +void MListIndexViewPrivate::updateShortcutPositions() const +{ + if (shortcuts.count() > 0) { + int shortcutsGap = controller->size().height() / shortcuts.count(); + QFontMetrics fm(shortcuts[0]->font()); + for (int i = 0; i < shortcuts.count(); i++) { + shortcuts[i]->setPos((controller->size().width() - fm.width(shortcuts[i]->text())) / 2, i*shortcutsGap); + } + } +} + +QModelIndex MListIndexViewPrivate::locateShortcutIndex(int y, int x) +{ + Q_UNUSED(x); + + foreach (MLabel *shortcut, shortcuts) { + if (shortcut->pos().y() <= y && shortcut->pos().y() + shortcut->contentsRect().height() >= y ) { + int flatIndex = controller->model()->shortcutLabels().indexOf(shortcut->text()); + return controller->model()->shortcutIndexes()[flatIndex]; + } + } + return QModelIndex(); +} + +MLabel *MListIndexViewPrivate::createLabel(int index) +{ + Q_Q(MListIndexView); + Q_ASSERT(index < controllerModel->shortcutLabels().count()); + + MLabel *shortcut = new MLabel(controller); + shortcut->setObjectName(q->style()->shortcutObjectName()); + shortcut->setText(controllerModel->shortcutLabels()[index]); + + return shortcut; +} + +void MListIndexViewPrivate::clearVisible() +{ + foreach (MLabel *shortcut, shortcuts) { + delete shortcut; + } + shortcuts.clear(); +} + +void MListIndexViewPrivate::updateVisible() +{ + if (shortcutHeight == 0) + return; + + int fitCount = (controller->contentsRect().height()) / shortcutHeight; + + if (fitCount > 0 && fitCount != shortcuts.count()) { + int skipCount = qCeil((qreal)shortcutsCount / (qreal)fitCount); + if (skipCount > 0 && shortcuts.count() != shortcutsCount / skipCount) { + clearVisible(); + for (int i = 0; i < shortcutsCount; i += skipCount) { + if (shortcutsCount - i <= skipCount) + shortcuts.append(createLabel(shortcutsCount - 1)); + else + shortcuts.append(createLabel(i)); + } + } + } + updateShortcutPositions(); +} + +void MListIndexViewPrivate::createContainer() +{ + disconnect(this, SLOT(exposedContentRectChanged())); + if (controller->model()->list()) { + container = MListViewPrivateNamespace::findParentWidgetOfType<MApplicationPage>(controller->model()->list()); + controller->setParentItem(container); + + connect(container, SIGNAL(exposedContentRectChanged()), this, SLOT(exposedContentRectChanged())); + exposedContentRectChanged(); + } + +} + +void MListIndexViewPrivate::installSceneEventHandler() +{ + uninstallSceneEventHandler(); + + if (controller->scene()) { + eventScene = controller->scene(); + eventScene->installEventFilter(this); + } +} + +void MListIndexViewPrivate::uninstallSceneEventHandler() +{ + if (eventScene) + eventScene->removeEventFilter(this); +} + +bool MListIndexViewPrivate::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object); + + QGraphicsSceneMouseEvent *mouseEvent = dynamic_cast<QGraphicsSceneMouseEvent*>(event); + if (mouseEvent && controller->isVisible()) { + QPointF mousePos = controller->mapFromScene(mouseEvent->scenePos()); + + bool mouseOver = false; + if (mousePos.y() >= 0 && mousePos.y() <= controller->size().height() && + mousePos.x() >= 0 && mousePos.x() <= controller->size().width()) + mouseOver = true; + + switch (mouseEvent->type()) { + case QGraphicsSceneMouseEvent::GraphicsSceneMousePress: + case QGraphicsSceneMouseEvent::GraphicsSceneMouseMove:{ + if (mouseOver) { + QModelIndex scrollTo = locateShortcutIndex(mousePos.y(), 0); + if (scrollTo.isValid()) { + controllerModel->list()->scrollTo(scrollTo, MList::PositionAtTopHint); + } + return true; + } + } + break; + default: + break; + } + } + + return false; +} + +void MListIndexViewPrivate::listParentChanged() +{ + initLayout(); +} + +void MListIndexViewPrivate::exposedContentRectChanged() +{ + containerRect = container->exposedContentRect(); + updateLayout(); +} + +MListIndexView::MListIndexView(MListIndex *controller) : MWidgetView(controller), d_ptr(new MListIndexViewPrivate) +{ + Q_D(MListIndexView); + + d->q_ptr = this; + d->controller = controller; +} + +MListIndexView::~MListIndexView() +{ + delete d_ptr; +} + +void MListIndexView::setGeometry(const QRectF &rect) +{ + Q_D(MListIndexView); + + d->updateVisible(); + MWidgetView::setGeometry(rect); +} + +void MListIndexView::setupModel() +{ + Q_D(MListIndexView); + + MWidgetView::setupModel(); + + d->initLayout(); +} + +void MListIndexView::applyStyle() +{ + Q_D(MListIndexView); + + MWidgetView::applyStyle(); + + if (style()->preferredSize().isValid()) + d->controller->setPreferredWidth(style()->preferredSize().width()); + else + d->controller->setPreferredWidth(0.0); + + foreach (MLabel *shortcut, d->shortcuts) { + shortcut->setObjectName(style()->shortcutObjectName()); + } +} + +void MListIndexView::updateData(const QList<const char *> &modifications) +{ + Q_D(MListIndexView); + + const char *member; + for (int i = 0; i < modifications.count(); i++) { + member = modifications[i]; + + if (member == MListIndexModel::ShortcutLabels || member == MListIndexModel::List) { + if (model()->list()) + d->initLayout(); + } + } + + MWidgetView::updateData(modifications); +} + +M_REGISTER_VIEW_NEW(MListIndexView, MListIndex) diff --git a/src/views/mlistindexview.h b/src/views/mlistindexview.h new file mode 100644 index 00000000..9634299d --- /dev/null +++ b/src/views/mlistindexview.h @@ -0,0 +1,67 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MLISTINDEXVIEW_H +#define MLISTINDEXVIEW_H + +#include <MWidgetView> +#include "mlistindexmodel.h" +#include "mlistindexstyle.h" + +class MListIndex; +class MListIndexViewPrivate; + +class MListIndexView : public MWidgetView +{ + Q_OBJECT + M_VIEW(MListIndexModel, MListIndexStyle) + +public: + MListIndexView(MListIndex *controller); + virtual ~MListIndexView(); + + //! \reimp + virtual void setGeometry(const QRectF &rect); + //! \reimp_end + +protected: + //! \reimp + virtual void setupModel(); + virtual void applyStyle(); + //! \reimp_end + + //! \internal + MListIndexViewPrivate *d_ptr; + //! \internal_end + +protected Q_SLOTS: + //! \reimp + virtual void updateData(const QList<const char *> &modifications); + //! \reimp_end + +private: + Q_DISABLE_COPY(MListIndexView) + Q_DECLARE_PRIVATE(MListIndexView) + +#ifdef UNIT_TEST + friend class Ut_MListIndex; +#endif +}; + +#endif diff --git a/src/views/mlistindexview_p.h b/src/views/mlistindexview_p.h new file mode 100644 index 00000000..b765ac45 --- /dev/null +++ b/src/views/mlistindexview_p.h @@ -0,0 +1,83 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MLISTINDEXVIEW_P_H +#define MLISTINDEXVIEW_P_H + +#include <QModelIndex> +#include <QRectF> +#include <QVector> + +class MApplicationPage; +class MListIndex; +class MListIndexModel; +class MListIndexView; +class MLabel; +class MWidgetController; + +class QGraphicsScene; + +class MListIndexViewPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(MListIndexView) +public: + MListIndexViewPrivate(); + virtual ~MListIndexViewPrivate(); + + + virtual void initLayout(); + virtual void updateLayout(); + virtual void updateShortcutPositions() const; + + virtual QModelIndex locateShortcutIndex(int y, int x = 0); + + virtual MLabel *createLabel(int index); + virtual void clearVisible(); + virtual void updateVisible(); + + virtual void createContainer(); + virtual void installSceneEventHandler(); + virtual void uninstallSceneEventHandler(); + +protected: + virtual bool eventFilter(QObject *object, QEvent *event); + +protected Q_SLOTS: + virtual void listParentChanged(); + virtual void exposedContentRectChanged(); + +public: + MListIndex *controller; + const MListIndexModel *controllerModel; + + MApplicationPage *container; + QGraphicsScene *eventScene; + + QVector<MLabel *> shortcuts; + int shortcutHeight; + int shortcutsCount; + QRectF containerRect; + +protected: + MListIndexView *q_ptr; +}; + +#endif + diff --git a/src/views/mlistview.cpp b/src/views/mlistview.cpp index e83b329a..16ec55d5 100644 --- a/src/views/mlistview.cpp +++ b/src/views/mlistview.cpp @@ -126,6 +126,14 @@ void MListView::applyStyle() } } +void MListView::notifyItemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) +{ + MWidgetView::notifyItemChange(change, value); + + if(change == QGraphicsItem::ItemSceneHasChanged) + emit controller->parentChanged(); +} + QSizeF MListView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { if (!d_ptr) diff --git a/src/views/mlistview.h b/src/views/mlistview.h index 5c90ee0b..10acd0aa 100644 --- a/src/views/mlistview.h +++ b/src/views/mlistview.h @@ -69,6 +69,8 @@ protected: virtual void setupModel(); virtual void applyStyle(); + virtual void notifyItemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value); + private: void init(); void connectSelectionModel(); diff --git a/src/views/mlistview_p.cpp b/src/views/mlistview_p.cpp index 02690e6a..b0f3c53e 100644 --- a/src/views/mlistview_p.cpp +++ b/src/views/mlistview_p.cpp @@ -25,6 +25,7 @@ #include <QItemSelectionModel> #include "mcontentitem.h" +#include "mlistindex.h" #include "mabstractcellcreator.h" #include "mlistview_p.h" @@ -761,10 +762,12 @@ void MPlainMultiColumnListViewPrivate::drawVerticalSeparator(int row, int column //////////// MGroupHeaderListViewPrivate::MGroupHeaderListViewPrivate() { + listIndexWidget = NULL; } MGroupHeaderListViewPrivate::~MGroupHeaderListViewPrivate() { + delete listIndexWidget; } void MGroupHeaderListViewPrivate::createVisibleItems(const QModelIndex &firstVisibleRow, @@ -801,9 +804,14 @@ void MGroupHeaderListViewPrivate::resetModel(MListModel *mListModel) { MListViewPrivate::resetModel(mListModel); + if(!listIndexWidget) { + listIndexWidget = new MListIndex(controller); + } + headersPositions.resize(this->headersCount()); updateHeadersPositions(); updateHeadersRows(); + updateHeadersIndexes(); } int MGroupHeaderListViewPrivate::locatePosOfItem(const QModelIndex &index) @@ -918,6 +926,18 @@ void MGroupHeaderListViewPrivate::updateHeadersRows() } } +void MGroupHeaderListViewPrivate::updateHeadersIndexes() +{ + if(listIndexWidget) { + QMap<QModelIndex, QString> shortcuts; + for (int i = 0; i < headersCount(); i++) { + QModelIndex headerRowIndex = flatRowToIndex(headersRows[i]); + shortcuts[headerRowIndex] = model->data(headerRowIndex).toString(); + } + listIndexWidget->setShortcuts(shortcuts); + } +} + int MGroupHeaderListViewPrivate::indexToFlatRow(const QModelIndex &index) const { if (!index.isValid()) @@ -1025,6 +1045,7 @@ void MGroupHeaderListViewPrivate::layoutChanged() updateHeadersPositions(); updateHeadersRows(); + updateHeadersIndexes(); } void MGroupHeaderListViewPrivate::drawSeparator(int row, QPainter *painter, const QStyleOptionGraphicsItem *option) diff --git a/src/views/mlistview_p.h b/src/views/mlistview_p.h index 20c9d1ac..f8e5feac 100644 --- a/src/views/mlistview_p.h +++ b/src/views/mlistview_p.h @@ -35,7 +35,9 @@ class MWidget; class MListView; class MList; class MListModel; +class MListIndex; class MPannableViewport; +class MSideBar; class MWidgetRecycler; class QAbstractItemModel; class QItemSelectionModel; @@ -246,6 +248,7 @@ public: int itemsCount(int index) const; void updateHeadersPositions(); void updateHeadersRows(); + void updateHeadersIndexes(); public: virtual int indexToFlatRow(const QModelIndex &index) const; @@ -272,9 +275,12 @@ public: virtual void layoutChanged(); virtual void drawSeparator(const int row, QPainter *painter, const QStyleOptionGraphicsItem *option); + public: QVector<int> headersPositions; QVector<int> headersRows; + + MListIndex *listIndexWidget; }; class MMultiColumnListViewPrivate : public MGroupHeaderListViewPrivate diff --git a/src/views/style/mlistindexstyle.h b/src/views/style/mlistindexstyle.h new file mode 100644 index 00000000..006e8843 --- /dev/null +++ b/src/views/style/mlistindexstyle.h @@ -0,0 +1,38 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MLISTINDEXSTYLE_H +#define MLISTINDEXSTYLE_H + +#include "mwidgetstyle.h" + +class MListIndexStyle : public MWidgetStyle +{ + Q_OBJECT + M_STYLE(MListIndexStyle) + + M_STYLE_ATTRIBUTE(QString, shortcutObjectName, ShortcutObjectName) +}; + +class MListIndexStyleContainer : public MWidgetStyleContainer +{ + M_STYLE_CONTAINER(MListIndexStyle) +}; + +#endif diff --git a/src/views/style/style.pri b/src/views/style/style.pri index 9a9634dd..ba8b3176 100644 --- a/src/views/style/style.pri +++ b/src/views/style/style.pri @@ -45,6 +45,7 @@ MGEN_STYLE_HEADERS += \ $$STYLE_SRC_DIR/mcontainerheaderstyle.h \ $$STYLE_SRC_DIR/mcontentitemstyle.h \ $$STYLE_SRC_DIR/mvideowidgetstyle.h \ + $$STYLE_SRC_DIR/mlistindexstyle.h \ PUBLIC_HEADERS += \ $$MGEN_STYLE_HEADERS \ diff --git a/src/views/views.pri b/src/views/views.pri index 6e3578c4..00f5ab9a 100644 --- a/src/views/views.pri +++ b/src/views/views.pri @@ -45,7 +45,7 @@ PUBLIC_HEADERS += \ mcontentitemview.h \ mnavigationbarview.h \ mscenelayereffectdimview.h \ - + mlistindexview.h \ PRIVATE_HEADERS += \ mstylablewidgetview_p.h \ @@ -61,6 +61,7 @@ PRIVATE_HEADERS += \ mbuttongrouplayoutpolicy_p.h \ mtoolbartabview_p.h \ mpannablewidgetview_p.h \ + mlistindexview_p.h \ SOURCES += \ mapplicationpageview.cpp \ @@ -110,3 +111,4 @@ SOURCES += \ mcontentitemview.cpp \ mnavigationbarview.cpp \ mscenelayereffectdimview.cpp \ + mlistindexview.cpp \ diff --git a/src/views/widgets/mlistindex.cpp b/src/views/widgets/mlistindex.cpp new file mode 100644 index 00000000..cfbb9e01 --- /dev/null +++ b/src/views/widgets/mlistindex.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#include "mlistindex.h" +#include "mlistindexview.h" + +#include "mlist.h" + +#include "mwidgetcreator.h" +M_REGISTER_WIDGET(MListIndex) + +MListIndex::MListIndex(MList *parent) : MWidgetController(new MListIndexModel, parent) +{ + setView(new MListIndexView(this)); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + model()->setList(parent); +} + +MListIndex::~MListIndex() +{ +} + +void MListIndex::setShortcuts(const QMap<QModelIndex, QString> &shortcuts) +{ + model()->beginTransaction(); + model()->setShortcutIndexes(shortcuts.keys()); + model()->setShortcutLabels(shortcuts.values()); + model()->commitTransaction(); +} + +void MListIndex::setList(MList *list) +{ + model()->setList(list); +} diff --git a/src/views/widgets/mlistindex.h b/src/views/widgets/mlistindex.h new file mode 100644 index 00000000..d533bd60 --- /dev/null +++ b/src/views/widgets/mlistindex.h @@ -0,0 +1,78 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MLISTINDEX_H +#define MLISTINDEX_H + +#include "mwidgetcontroller.h" +#include "mlistindexmodel.h" + +#include <QMap> + +class MListIndexPrivate; +class DuiList; + +/*! + * \class MListIndex + * \brief MListIndex is a container for list indexes, for fast navigation through the + * list content. + * + * MListIndex creates a stylable container on the right side of the window in which the list + * is rendered. It's main duty is to provide a way for fast navigation through list contents. + * The content of the list index is dynamic and is controlled by the list itself. + * The list index widget creates a scene window container and places itself into it. + * Thus the positioning and sizing of the list index are controlled by the scene window. + * Its contents is controlled by the list. + * + */ +class MListIndex : public MWidgetController +{ + Q_OBJECT + M_CONTROLLER(MListIndex) + +public: + /*! + * \brief Default constructor. Constructs the list index widget. + * \param parent The list controller of the list index content. + */ + MListIndex(MList *parent = NULL); + + /*! + * \brief Default destructor. Cleanups and destroys the list index widget. + */ + virtual ~MListIndex(); + + /*! + * \brief Sets the navigation indexes of the list to be displayed. + * \param shortcuts The mapping between a string label and it's index position in list. + */ + void setShortcuts(const QMap<QModelIndex, QString> &shortcuts); + + /*! + * \brief Sets the content controller of the list index. + * \param list The list widget that the index widget provides fast navigation for. + */ + void setList(MList *list); + +private: + Q_DECLARE_PRIVATE(MListIndex) + Q_DISABLE_COPY(MListIndex) +}; + +#endif diff --git a/src/views/widgets/mlistindexmodel.h b/src/views/widgets/mlistindexmodel.h new file mode 100644 index 00000000..aa33e1fc --- /dev/null +++ b/src/views/widgets/mlistindexmodel.h @@ -0,0 +1,39 @@ +/*************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (directui@nokia.com) +** +** This file is part of libmeegotouch. +** +** If you have questions regarding the use of this file, please contact +** Nokia at directui@nokia.com. +** +** This library is free software; you can redistribute it and/or +** modify it under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation +** and appearing in the file LICENSE.LGPL included in the packaging +** of this file. +** +****************************************************************************/ + +#ifndef MLISTINDEXMODEL_H +#define MLISTINDEXMODEL_H + +#include "mwidgetmodel.h" +#include <QModelIndexList> + +class MList; + +class MListIndexModel : public MWidgetModel +{ + Q_OBJECT + M_MODEL_INTERNAL(MListIndexModel) + +public: + M_MODEL_PROPERTY(QStringList, shortcutLabels, ShortcutLabels, true, QStringList()) + M_MODEL_PROPERTY(QModelIndexList, shortcutIndexes, ShortcutIndexes, true, QModelIndexList()) + M_MODEL_PTR_PROPERTY(MList*, list, List, true, NULL) +}; + +#endif diff --git a/src/views/widgets/widgets.pri b/src/views/widgets/widgets.pri index 739da501..4c20959d 100644 --- a/src/views/widgets/widgets.pri +++ b/src/views/widgets/widgets.pri @@ -3,9 +3,11 @@ INCLUDEPATH+=./widgets PUBLIC_HEADERS += \ $$WIDGETS_SRC_DIR/mapplicationmenubutton.h \ + $$WIDGETS_SRC_DIR/mlistindex.h \ MGEN_MODEL_HEADERS += \ $$WIDGETS_SRC_DIR/mapplicationmenubuttonmodel.h \ + $$WIDGETS_SRC_DIR/mlistindexmodel.h \ PRIVATE_HEADERS += \ $$MGEN_MODEL_HEADERS \ @@ -14,3 +16,4 @@ PRIVATE_HEADERS += \ SOURCES += \ $$WIDGETS_SRC_DIR/mapplicationmenubutton.cpp \ $$WIDGETS_SRC_DIR/mcontainerheader.cpp \ + $$WIDGETS_SRC_DIR/mlistindex.cpp \ diff --git a/tests/ut_mlistviewgroupheader/ut_mlistviewgroupheader.pro b/tests/ut_mlistviewgroupheader/ut_mlistviewgroupheader.pro index 48e213c6..1f876ac9 100644 --- a/tests/ut_mlistviewgroupheader/ut_mlistviewgroupheader.pro +++ b/tests/ut_mlistviewgroupheader/ut_mlistviewgroupheader.pro @@ -2,13 +2,27 @@ include(../common_top.pri) TARGET = ut_mlistviewgroupheader -INCLUDEPATH += ../mlistviewcommon +INCLUDEPATH += ../mlistviewcommon \ + ../../src/corelib/widgets \ + ../../src/views/widgets \ + ../../src/views \ + ../../src/corelib/.gen + HEADERS += ut_mlistviewgroupheader.h \ - ../mlistviewcommon/myindexedmodel.h + ../mlistviewcommon/myindexedmodel.h \ + ../../src/views/widgets/mlistindexmodel.h \ + ../../src/views/style/mlistindexstyle.h \ SOURCES += ut_mlistviewgroupheader.cpp \ ../mlistviewcommon/myindexedmodel.cpp \ ../../src/views/mlistview_p.cpp \ - ../../src/views/.moc/moc_mlistview_p.cpp + ../../src/views/.moc/moc_mlistview_p.cpp \ + ../../src/views/widgets/mlistindex.cpp \ + ../../src/views/.moc/moc_mlistindex.cpp \ + ../../src/views/.gen/gen_mlistindexmodeldata.cpp \ + ../../src/views/mlistindexview.cpp \ + ../../src/views/.moc/moc_mlistindexview.cpp \ + ../../src/views/.moc/moc_mlistindexview_p.cpp \ + ../../src/views/.gen/gen_mlistindexstyledata.cpp \ include(../common_bot.pri) diff --git a/tests/ut_mlistviewmulticolumn/ut_mlistviewmulticolumn.pro b/tests/ut_mlistviewmulticolumn/ut_mlistviewmulticolumn.pro index d1f48f2c..0c5d197b 100644 --- a/tests/ut_mlistviewmulticolumn/ut_mlistviewmulticolumn.pro +++ b/tests/ut_mlistviewmulticolumn/ut_mlistviewmulticolumn.pro @@ -2,13 +2,27 @@ include(../common_top.pri) TARGET = ut_mlistviewmulticolumn -INCLUDEPATH += ../mlistviewcommon +INCLUDEPATH += ../mlistviewcommon \ + ../../src/corelib/widgets \ + ../../src/views/widgets \ + ../../src/views \ + ../../src/corelib/.gen + HEADERS += ut_mlistviewmulticolumn.h \ - ../mlistviewcommon/myindexedmodel.h + ../mlistviewcommon/myindexedmodel.h \ + ../../src/views/widgets/mlistindexmodel.h \ + ../../src/views/style/mlistindexstyle.h \ SOURCES += ut_mlistviewmulticolumn.cpp \ ../mlistviewcommon/myindexedmodel.cpp \ ../../src/views/mlistview_p.cpp \ - ../../src/views/.moc/moc_mlistview_p.cpp + ../../src/views/.moc/moc_mlistview_p.cpp \ + ../../src/views/widgets/mlistindex.cpp \ + ../../src/views/.moc/moc_mlistindex.cpp \ + ../../src/views/.gen/gen_mlistindexmodeldata.cpp \ + ../../src/views/mlistindexview.cpp \ + ../../src/views/.moc/moc_mlistindexview.cpp \ + ../../src/views/.moc/moc_mlistindexview_p.cpp \ + ../../src/views/.gen/gen_mlistindexstyledata.cpp \ include(../common_bot.pri) diff --git a/tests/ut_mlistviewseparators/ut_mlistviewseparators.pro b/tests/ut_mlistviewseparators/ut_mlistviewseparators.pro index 57466613..f838db0c 100644 --- a/tests/ut_mlistviewseparators/ut_mlistviewseparators.pro +++ b/tests/ut_mlistviewseparators/ut_mlistviewseparators.pro @@ -2,14 +2,28 @@ include(../common_top.pri) TARGET = ut_mlistviewseparators -INCLUDEPATH += ../ut_mlistviewcommon \ - ../mlistviewcommon +INCLUDEPATH += ../mlistviewcommon \ + ../../src/corelib/widgets \ + ../../src/views/widgets \ + ../../src/views \ + ../../src/corelib/.gen + HEADERS += ut_mlistviewseparators.h \ - ../mlistviewcommon/myindexedmodel.h + ../mlistviewcommon/myindexedmodel.h \ + ../../src/views/widgets/mlistindexmodel.h \ + ../../src/views/style/mlistindexstyle.h \ SOURCES += ut_mlistviewseparators.cpp \ ../mlistviewcommon/myindexedmodel.cpp \ ../../src/views/mlistview_p.cpp \ - ../../src/views/.moc/moc_mlistview_p.cpp + ../../src/views/.moc/moc_mlistview_p.cpp \ + ../../src/views/widgets/mlistindex.cpp \ + ../../src/views/.moc/moc_mlistindex.cpp \ + ../../src/views/.gen/gen_mlistindexmodeldata.cpp \ + ../../src/views/mlistindexview.cpp \ + ../../src/views/.moc/moc_mlistindexview.cpp \ + ../../src/views/.moc/moc_mlistindexview_p.cpp \ + ../../src/views/.gen/gen_mlistindexstyledata.cpp \ + include(../common_bot.pri) |