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