Fix forward navigation control on Linux.
[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         MainBase(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 #if defined(Q_OS_SYMBIAN)
24     list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
25 #endif
26     populateList();
27     setCentralWidget(list);
28
29 #ifdef Q_OS_SYMBIAN
30     charm = new FlickCharm(this);
31     // charm->activateOn(list);
32     QAction *closeAction = new QAction(parent? tr("Back"): tr("Exit"), this);
33     closeAction->setSoftKeyRole(QAction::NegativeSoftKey);
34     connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
35     MainBase::addAction(closeAction);
36 #endif // Q_OS_SYMBIAN
37
38     connect(list, SIGNAL(activated(const QModelIndex &)),
39             this, SLOT(onItemActivated(const QModelIndex &)));
40     connect(list, SIGNAL(itemSelectionChanged()),
41             this, SLOT(onItemSelectionChanged()));
42     connect(list, SIGNAL(itemSelectionChanged()),
43             this, SIGNAL(itemSelectionChanged()));
44 }
45
46 void ListWindow::populateList()
47 {
48     TRACE;
49
50     list->clear();
51     list->setIconSize(QSize(48, 48)); // FIXME
52     list->setUniformItemSizes(true);
53     if (mModel && mModel->rowCount()) {
54         for (int i = 0; i < mModel->rowCount(); i++) {
55             QModelIndex index = mModel->index(i, 0);
56             QString text = mModel->data(index, Qt::DisplayRole).toString();
57             QVariant imageData = mModel->data(index, Qt::DecorationRole);
58             QIcon icon(QPixmap::fromImage(imageData.value<QImage>()));
59             (void)new QListWidgetItem(icon, text, list);
60         }
61     } else {
62         QListWidgetItem *item = new QListWidgetItem(noItems);
63         item->setFlags(Qt::NoItemFlags);
64         list->addItem(item);
65     }
66     for (int i = 0; i < buttons.count(); i++) {
67         insertButton(i, buttons[i]);
68     }
69 }
70
71 void ListWindow::insertButton(int row, const Button &b)
72 {
73     QPushButton *pushButton = new QPushButton(
74         QIcon(Platform::instance()->icon(b.iconName)), b.title, this);
75 #ifdef Q_OS_SYMBIAN
76     pushButton->setFixedWidth(list->width());
77 #endif
78     connect(pushButton, SIGNAL(clicked()), b.receiver, b.slot);
79     QListWidgetItem *item = new QListWidgetItem();
80     item->setFlags(Qt::NoItemFlags);
81     list->insertItem(row, item);
82     list->setItemWidget(item, pushButton);
83 }
84
85 void ListWindow::setModel(QAbstractItemModel *aModel)
86 {
87     TRACE;
88     mModel = aModel;
89     populateList();
90     if (mModel) {
91         connect(mModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)),
92                 this, SLOT(populateList()));
93         connect(mModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
94                 this, SLOT(populateList()));
95         connect(mModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
96                 this, SLOT(populateList()));
97         connect(mModel, SIGNAL(layoutChanged()), this, SLOT(populateList()));
98     }
99 }
100
101 QAbstractItemModel *ListWindow::model() const
102 {
103     return mModel;
104 }
105
106 void ListWindow::addButton(const QString &title, QObject *receiver,
107                            const char *slot, const QString &iconName)
108 {
109     TRACE;
110
111 #if defined(Q_WS_MAEMO_5)
112     Button b;
113     b.title = title;
114     b.receiver = receiver;
115     b.slot = slot;
116     b.iconName = iconName;
117     insertButton(buttons.length(), b);
118     buttons.append(b);
119 #else
120     (void)addToolBarAction(receiver, slot, iconName, title, true);
121 #endif
122 }
123
124 void ListWindow::addItemButton(const QString &title, QObject *receiver,
125                                const char *slot, const QString &iconName)
126 {
127     TRACE;
128 #if defined(Q_WS_MAEMO_5)
129     Q_UNUSED(title);
130     Q_UNUSED(receiver);
131     Q_UNUSED(slot);
132     Q_UNUSED(iconName);
133 #else
134     QAction *toolBarAction =
135             addToolBarAction(receiver, slot, iconName, title, true);
136     toolBarAction->setEnabled(false);
137     itemActions.append(toolBarAction);
138 #endif
139 }
140
141 QAction *ListWindow::addMenuAction(const QString &title, QObject *receiver,
142                                    const char *slot)
143 {
144     TRACE;
145     QAction *action = 0;
146 #if defined(Q_WS_MAEMO_5)
147     action = menuBar()->addAction(title);
148     connect(action, SIGNAL(triggered()), receiver, slot);
149 #elif defined(Q_OS_SYMBIAN)
150     action = new QAction(title, this);
151     connect(action, SIGNAL(triggered()), receiver, slot);
152     action->setSoftKeyRole(QAction::PositiveSoftKey);
153     menuBar()->addAction(action);
154 #else
155     Q_UNUSED(title);
156     Q_UNUSED(receiver);
157     Q_UNUSED(slot);
158     action = new QAction(this);
159 #endif
160     return action;
161 }
162
163 void ListWindow::onItemActivated(const QModelIndex &index)
164 {
165     TRACE;
166
167     // Work around Qt/Symbian^3 bug: Disabled list items still can be selected
168     if (!mModel) {
169         return;
170     }
171     if (!mModel->rowCount()) {
172         return;
173     }
174
175     int row = index.row() - buttons.count();
176     qDebug() << "Activated" << index.row() << ", emit activated(" << row
177             << ")";
178     emit activated(mModel->index(row, 0));
179 }
180
181 void ListWindow::setCurrentItem(const QModelIndex &item)
182 {
183     int index = item.row();
184     list->setCurrentItem(list->item(index + buttons.count()));
185 }
186
187 QModelIndex ListWindow::currentItem() const
188 {
189     TRACE;
190     QListWidgetItem *currentItem = list->currentItem();
191     if (currentItem) {
192         int row = list->row(currentItem) - buttons.count();
193         qDebug() << "Current row is" << row;
194         return mModel->index(row, 0);
195     }
196     return QModelIndex();
197 }
198
199 #ifdef Q_WS_MAEMO_5
200
201 void ListWindow::closeEvent(QCloseEvent *event)
202 {
203     // Work around Maemo/Qt bug: Menu items are not removed on close
204     menuBar()->clear();
205     event->accept();
206     QMainWindow::closeEvent(event);
207 }
208
209 #endif // Q_WS_MAEMO_5
210
211 void ListWindow::onItemSelectionChanged()
212 {
213     TRACE;
214     bool enabled = currentItem().isValid();
215     foreach (QAction *action, itemActions) {
216         action->setEnabled(enabled);
217     }
218 }