Smoothen switch between full screen/normal view on Maemo.
[dorian] / widgets / listwindow.cpp
index db92196..5e6fa34 100644 (file)
 #include "flickcharm.h"
 #endif
 
-ListWindow::ListWindow(QWidget *parent): QMainWindow(parent), model(0)
+ListWindow::ListWindow(const QString &noItems_, QWidget *parent):
+        MainBase(parent), mModel(0), noItems(noItems_)
 {
 #if defined(Q_WS_MAEMO_5)
     setAttribute(Qt::WA_Maemo5StackedWindow, true);
 #endif
+    setAttribute(Qt::WA_DeleteOnClose);
 
     list = new QListWidget(this);
+    list->setSelectionMode(QAbstractItemView::SingleSelection);
+#if defined(Q_OS_SYMBIAN)
+    list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+#endif
     populateList();
     setCentralWidget(list);
 
 #ifdef Q_OS_SYMBIAN
     charm = new FlickCharm(this);
-    charm->activateOn(list);
+    // charm->activateOn(list);
     QAction *closeAction = new QAction(parent? tr("Back"): tr("Exit"), this);
     closeAction->setSoftKeyRole(QAction::NegativeSoftKey);
     connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
-    QMainWindow::addAction(closeAction);
+    MainBase::addAction(closeAction);
 #endif // Q_OS_SYMBIAN
 
-#ifdef Q_WS_MAC
-    // FIXME
-    // addAction(tr("Close"), this, SLOT(close()), QString(),
-    //           QDialogButtonBox::RejectRole);
-#endif // Q_WS_MAC
-
     connect(list, SIGNAL(activated(const QModelIndex &)),
-            this, SLOT(onItemActicvated(const QModelIndex &)));
+            this, SLOT(onItemActivated(const QModelIndex &)));
+    connect(list, SIGNAL(itemSelectionChanged()),
+            this, SLOT(onItemSelectionChanged()));
+    connect(list, SIGNAL(itemSelectionChanged()),
+            this, SIGNAL(itemSelectionChanged()));
 }
 
 void ListWindow::populateList()
@@ -44,50 +48,94 @@ void ListWindow::populateList()
     TRACE;
 
     list->clear();
-    if (model) {
-        for (int i = 0; i < model->rowCount(); i++) {
-            QModelIndex index = model->index(i, 0);
-            QString text = model->data(index, Qt::DisplayRole).toString();
-            QIcon icon;
-            QVariant iconData = model->data(index, Qt::DecorationRole);
-            if (iconData.canConvert<QIcon>()) {
-                icon = iconData.value<QIcon>();
-            }
+    list->setIconSize(QSize(48, 48)); // FIXME
+    list->setUniformItemSizes(true);
+    if (mModel && mModel->rowCount()) {
+        for (int i = 0; i < mModel->rowCount(); i++) {
+            QModelIndex index = mModel->index(i, 0);
+            QString text = mModel->data(index, Qt::DisplayRole).toString();
+            QVariant imageData = mModel->data(index, Qt::DecorationRole);
+            QIcon icon(QPixmap::fromImage(imageData.value<QImage>()));
             (void)new QListWidgetItem(icon, text, list);
         }
+    } else {
+        QListWidgetItem *item = new QListWidgetItem(noItems);
+        item->setFlags(Qt::NoItemFlags);
+        list->addItem(item);
     }
     for (int i = 0; i < buttons.count(); i++) {
-        QListWidgetItem *item = new QListWidgetItem();
-        list->insertItem(i, item);
-        list->setItemWidget(item, buttons[i]);
+        insertButton(i, buttons[i]);
     }
 }
 
-void ListWindow::setModel(QAbstractItemModel *model_)
+void ListWindow::insertButton(int row, const Button &b)
 {
-    model = model_;
+    QPushButton *pushButton = new QPushButton(
+        QIcon(Platform::instance()->icon(b.iconName)), b.title, this);
+#ifdef Q_OS_SYMBIAN
+    pushButton->setFixedWidth(list->width());
+#endif
+    connect(pushButton, SIGNAL(clicked()), b.receiver, b.slot);
+    QListWidgetItem *item = new QListWidgetItem();
+    item->setFlags(Qt::NoItemFlags);
+    list->insertItem(row, item);
+    list->setItemWidget(item, pushButton);
+}
+
+void ListWindow::setModel(QAbstractItemModel *aModel)
+{
+    TRACE;
+    mModel = aModel;
     populateList();
-    if (model) {
-        connect(model,
-                SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
+    if (mModel) {
+        connect(mModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
+                this, SLOT(populateList()));
+        connect(mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
+                this, SLOT(populateList()));
+        connect(mModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
                 this, SLOT(populateList()));
+        connect(mModel, SIGNAL(layoutChanged()), this, SLOT(populateList()));
     }
 }
 
+QAbstractItemModel *ListWindow::model() const
+{
+    return mModel;
+}
+
 void ListWindow::addButton(const QString &title, QObject *receiver,
                            const char *slot, const QString &iconName)
 {
     TRACE;
 
-    QPushButton *button = new QPushButton(QIcon(Platform::instance()->
-                                                icon(iconName)), title, this);
-    connect(button, SIGNAL(clicked()), receiver, slot);
-    buttons.append(button);
+#if defined(Q_WS_MAEMO_5)
+    Button b;
+    b.title = title;
+    b.receiver = receiver;
+    b.slot = slot;
+    b.iconName = iconName;
+    insertButton(buttons.length(), b);
+    buttons.append(b);
+#else
+    (void)addToolBarAction(receiver, slot, iconName, title, true);
+#endif
+}
 
-    int pos = buttons.length() - 1;
-    QListWidgetItem *item = new QListWidgetItem();
-    list->insertItem(pos, item);
-    list->setItemWidget(item, button);
+void ListWindow::addItemButton(const QString &title, QObject *receiver,
+                               const char *slot, const QString &iconName)
+{
+    TRACE;
+#if defined(Q_WS_MAEMO_5)
+    Q_UNUSED(title);
+    Q_UNUSED(receiver);
+    Q_UNUSED(slot);
+    Q_UNUSED(iconName);
+#else
+    QAction *toolBarAction =
+            addToolBarAction(receiver, slot, iconName, title, true);
+    toolBarAction->setEnabled(false);
+    itemActions.append(toolBarAction);
+#endif
 }
 
 QAction *ListWindow::addMenuAction(const QString &title, QObject *receiver,
@@ -109,14 +157,43 @@ QAction *ListWindow::addMenuAction(const QString &title, QObject *receiver,
     Q_UNUSED(slot);
     action = new QAction(this);
 #endif
-    action->setCheckable(true);
     return action;
 }
 
-void ListWindow::onItemActivated(const QModelIndex &)
+void ListWindow::onItemActivated(const QModelIndex &index)
+{
+    TRACE;
+
+    // Work around Qt/Symbian^3 bug: Disabled list items still can be selected
+    if (!mModel) {
+        return;
+    }
+    if (!mModel->rowCount()) {
+        return;
+    }
+
+    int row = index.row() - buttons.count();
+    qDebug() << "Activated" << index.row() << ", emit activated(" << row
+            << ")";
+    emit activated(mModel->index(row, 0));
+}
+
+void ListWindow::setCurrentItem(const QModelIndex &item)
+{
+    int index = item.row();
+    list->setCurrentItem(list->item(index + buttons.count()));
+}
+
+QModelIndex ListWindow::currentItem() const
 {
     TRACE;
-    // FIXME
+    QListWidgetItem *currentItem = list->currentItem();
+    if (currentItem) {
+        int row = list->row(currentItem) - buttons.count();
+        qDebug() << "Current row is" << row;
+        return mModel->index(row, 0);
+    }
+    return QModelIndex();
 }
 
 #ifdef Q_WS_MAEMO_5
@@ -125,20 +202,17 @@ void ListWindow::closeEvent(QCloseEvent *event)
 {
     // Work around Maemo/Qt bug: Menu items are not removed on close
     menuBar()->clear();
-    // FIXME: Is this needed? event->accept();
+    event->accept();
     QMainWindow::closeEvent(event);
 }
 
 #endif // Q_WS_MAEMO_5
 
-#ifdef Q_OS_SYMBIAN
-
-void ListWindow::show()
+void ListWindow::onItemSelectionChanged()
 {
-    foreach (QWidget *w, QApplication::allWidgets()) {
-        w->setContextMenuPolicy(Qt::NoContextMenu);
+    TRACE;
+    bool enabled = currentItem().isValid();
+    foreach (QAction *action, itemActions) {
+        action->setEnabled(enabled);
     }
-    showMaximized();
 }
-
-#endif // Q_OS_SYMBIAN