.
[dorian] / widgets / listwindow.cpp
1 #include <QtGui>
2 #include <QListWidget>
3 #include <QAbstractItemModel>
4
5 #include "listwindow.h"
6 #include "trace.h"
7 #include "platform.h"
8
9 #ifdef Q_OS_SYMBIAN
10 #include "flickcharm.h"
11 #endif
12
13 ListWindow::ListWindow(const QString &noItems_, QWidget *parent):
14         QMainWindow(parent), mModel(0), noItems(noItems_)
15 {
16 #if defined(Q_WS_MAEMO_5)
17     setAttribute(Qt::WA_Maemo5StackedWindow, true);
18 #endif
19     setAttribute(Qt::WA_DeleteOnClose);
20
21     list = new QListWidget(this);
22     list->setSelectionMode(QAbstractItemView::SingleSelection);
23     populateList();
24     setCentralWidget(list);
25
26 #ifdef Q_OS_SYMBIAN
27     charm = new FlickCharm(this);
28     charm->activateOn(list);
29     QAction *closeAction = new QAction(parent? tr("Back"): tr("Exit"), this);
30     closeAction->setSoftKeyRole(QAction::NegativeSoftKey);
31     connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
32     QMainWindow::addAction(closeAction);
33 #endif // Q_OS_SYMBIAN
34
35     connect(list, SIGNAL(activated(const QModelIndex &)),
36             this, SLOT(onItemActivated(const QModelIndex &)));
37 }
38
39 void ListWindow::populateList()
40 {
41     TRACE;
42
43     list->clear();
44     list->setIconSize(QSize(48, 48)); // FIXME
45     list->setUniformItemSizes(true);
46     if (mModel && mModel->rowCount()) {
47         for (int i = 0; i < mModel->rowCount(); i++) {
48             QModelIndex index = mModel->index(i, 0);
49             QString text = mModel->data(index, Qt::DisplayRole).toString();
50             QVariant imageData = mModel->data(index, Qt::DecorationRole);
51             QIcon icon(QPixmap::fromImage(imageData.value<QImage>()));
52             (void)new QListWidgetItem(icon, text, list);
53         }
54     } else {
55         QListWidgetItem *item = new QListWidgetItem(noItems);
56         item->setFlags(Qt::NoItemFlags);
57         list->addItem(item);
58     }
59     for (int i = 0; i < buttons.count(); i++) {
60         insertButton(i, buttons[i]);
61     }
62 }
63
64 void ListWindow::insertButton(int row, const Button &b)
65 {
66     QPushButton *pushButton = new QPushButton(
67         QIcon(Platform::instance()->icon(b.iconName)), b.title, this);
68     connect(pushButton, SIGNAL(clicked()), b.receiver, b.slot);
69     QListWidgetItem *item = new QListWidgetItem();
70     item->setFlags(Qt::NoItemFlags);
71     list->insertItem(row, item);
72     list->setItemWidget(item, pushButton);
73 }
74
75 void ListWindow::setModel(QAbstractItemModel *aModel)
76 {
77     TRACE;
78     mModel = aModel;
79     populateList();
80     if (mModel) {
81         connect(mModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
82                 this, SLOT(populateList()));
83         connect(mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
84                 this, SLOT(populateList()));
85         connect(mModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
86                 this, SLOT(populateList()));
87         connect(mModel, SIGNAL(layoutChanged()), this, SLOT(populateList()));
88     }
89 }
90
91 QAbstractItemModel *ListWindow::model() const
92 {
93     return mModel;
94 }
95
96 void ListWindow::addButton(const QString &title, QObject *receiver,
97                            const char *slot, const QString &iconName)
98 {
99     TRACE;
100
101     Button b;
102     b.title = title;
103     b.receiver = receiver;
104     b.slot = slot;
105     b.iconName = iconName;
106
107     insertButton(buttons.length(), b);
108     buttons.append(b);
109 }
110
111 QAction *ListWindow::addMenuAction(const QString &title, QObject *receiver,
112                                    const char *slot)
113 {
114     TRACE;
115     QAction *action = 0;
116 #if defined(Q_WS_MAEMO_5)
117     action = menuBar()->addAction(title);
118     connect(action, SIGNAL(triggered()), receiver, slot);
119 #elif defined(Q_OS_SYMBIAN)
120     action = new QAction(title, this);
121     connect(action, SIGNAL(triggered()), receiver, slot);
122     action->setSoftKeyRole(QAction::PositiveSoftKey);
123     menuBar()->addAction(action);
124 #else
125     Q_UNUSED(title);
126     Q_UNUSED(receiver);
127     Q_UNUSED(slot);
128     action = new QAction(this);
129 #endif
130     action->setCheckable(true);
131     return action;
132 }
133
134 void ListWindow::onItemActivated(const QModelIndex &index)
135 {
136     TRACE;
137     int row = index.row() - buttons.count();
138     qDebug() << "Activated" << index.row() << ", emit activated(" << row << ")";
139     emit activated(mModel->index(row, 0));
140 }
141
142 void ListWindow::setCurrentItem(const QModelIndex &item)
143 {
144     int index = item.row();
145     list->setCurrentItem(list->item(index + buttons.count()));
146 }
147
148 QModelIndex ListWindow::currentItem() const
149 {
150     TRACE;
151     QListWidgetItem *currentItem = list->currentItem();
152     if (currentItem) {
153         int row = list->row(currentItem) - buttons.count();
154         qDebug() << "Current row is" << row;
155         return mModel->index(row, 0);
156     }
157     return QModelIndex();
158 }
159
160 #ifdef Q_WS_MAEMO_5
161
162 void ListWindow::closeEvent(QCloseEvent *event)
163 {
164     // Work around Maemo/Qt bug: Menu items are not removed on close
165     menuBar()->clear();
166     event->accept();
167     QMainWindow::closeEvent(event);
168 }
169
170 #endif // Q_WS_MAEMO_5
171
172 #ifdef Q_OS_SYMBIAN
173
174 void ListWindow::show()
175 {
176     foreach (QWidget *w, QApplication::allWidgets()) {
177         w->setContextMenuPolicy(Qt::NoContextMenu);
178     }
179     showMaximized();
180 }
181
182 #endif // Q_OS_SYMBIAN