Make modal dialogs closeable on Mac.
[dorian] / widgets / listwindow.cpp
1 #include <QtGui>
2
3 #include "listwindow.h"
4 #include "trace.h"
5 #include "listview.h"
6
7 ListWindow::ListWindow(QWidget *parent): QMainWindow(parent), list(0)
8 {
9 #ifdef Q_WS_MAEMO_5
10     setAttribute(Qt::WA_Maemo5StackedWindow, true);
11     popup = new QMenu(this);
12
13     QScrollArea *scroller = new QScrollArea(this);
14     setCentralWidget(scroller);
15     scroller->setProperty("FingerScrollable", true);
16     // scroller->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
17     // scroller->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
18     scroller->setFrameStyle(QFrame::NoFrame);
19     scroller->show();
20
21     QWidget *content = new QWidget(scroller);
22     contentLayout = new QVBoxLayout(content);
23     contentLayout->setMargin(0);
24     content->setLayout(contentLayout);
25     content->show();
26
27     scroller->setWidget(content);
28     scroller->setWidgetResizable(true);
29 #else
30     QFrame *frame = new QFrame(this);
31     setCentralWidget(frame);
32     contentLayout = new QHBoxLayout();
33     frame->setLayout(contentLayout);
34 #   ifdef Q_OS_SYMBIAN
35     QAction *closeAction = new QAction(parent? tr("Back"): tr("Exit"), this);
36     closeAction->setSoftKeyRole(QAction::NegativeSoftKey);
37     connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
38     QMainWindow::addAction(closeAction);
39 #   else
40     buttonBox = new QDialogButtonBox(Qt::Vertical, this);
41     contentLayout->addWidget(buttonBox);
42 #   endif // Q_OS_SYMBIAN
43 #endif // Q_WS_MAEMO_5
44
45 #ifdef Q_WS_MAC
46     addAction(tr("Close"), this, SLOT(close()), QString(),
47               QDialogButtonBox::RejectRole);
48 #endif // Q_WS_MAC
49 }
50
51 void ListWindow::addList(ListView *listView)
52 {
53     Trace t("ListWindow::addList");
54     list = listView;
55 #ifdef Q_WS_MAEMO_5
56     list->installEventFilter(this);
57     list->setMinimumHeight(list->contentsHeight());
58     contentLayout->addWidget(list);
59     connect(list->model(),
60             SIGNAL(rowsInserted(const QModelIndex &, int, int)),
61             this, SLOT(onModelChanged()));
62     connect(list->model(),
63             SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
64             this, SLOT(onModelChanged()));
65 #else
66     contentLayout->insertWidget(0, list);
67 #endif
68     connect(list->selectionModel(),
69       SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
70       this,
71       SLOT(onSelectionChanged(const QItemSelection &, const QItemSelection &)));
72 }
73
74 void ListWindow::addAction(const QString &title, QObject *receiver,
75                            const char *slot, const QString &iconPath,
76                            QDialogButtonBox::ButtonRole role)
77 {
78     Trace t("ListWindow::addAction");
79 #ifdef Q_WS_MAEMO_5
80     Q_UNUSED(role);
81     QPushButton *button = new QPushButton(QIcon(iconPath), title, this);
82     contentLayout->addWidget(button);
83     connect(button, SIGNAL(clicked()), receiver, slot);
84 #elif defined(Q_OS_SYMBIAN)
85     Q_UNUSED(role);
86     QAction *action = new QAction(title, this);
87     connect(action, SIGNAL(triggered()), receiver, slot);
88     action->setSoftKeyRole(QAction::PositiveSoftKey);
89     menuBar()->addAction(action);
90 #else
91     Q_UNUSED(iconPath);
92     QPushButton *button = buttonBox->addButton(title, role);
93     connect(button, SIGNAL(clicked()), receiver, slot);
94 #endif // Q_WS_MAEMO_5
95 }
96
97 void ListWindow::addItemAction(const QString &title, QObject *receiver,
98                                const char *slot)
99 {
100     Trace t("ListWindow::addItemAction");
101 #ifdef Q_WS_MAEMO_5
102     popup->addAction(title, receiver, slot);
103 #elif defined Q_OS_SYMBIAN
104     QAction *action = new QAction(title, this);
105     connect(action, SIGNAL(triggered()), receiver, slot);
106     action->setSoftKeyRole(QAction::PositiveSoftKey);
107     menuBar()->addAction(action);
108     // FIXME: Add action to the list of item specific actions
109 #else
110     QPushButton *button =
111             buttonBox->addButton(title, QDialogButtonBox::ActionRole);
112     connect(button, SIGNAL(clicked()), receiver, slot);
113     itemButtons.append(button);
114     activateItemButtons();
115 #endif // Q_WS_MAEMO_5
116 }
117
118 #ifdef Q_WS_MAEMO_5
119
120 void ListWindow::closeEvent(QCloseEvent *event)
121 {
122     // Work around Maemo/Qt but: Menu items are not removed on close
123     menuBar()->clear();
124     event->accept();
125 }
126
127 #endif // Q_WS_MAEMO_5
128
129 void ListWindow::onSelectionChanged(const QItemSelection &selected,
130                                     const QItemSelection &deselected)
131 {
132     Q_UNUSED(selected);
133     Q_UNUSED(deselected);
134 #ifndef Q_WS_MAEMO_5
135     activateItemButtons();
136 #endif
137 }
138
139 #ifndef Q_WS_MAEMO_5
140
141 void ListWindow::activateItemButtons()
142 {
143     bool enable = false;
144     if (list) {
145         enable = list->selectionModel()->hasSelection();
146     }
147     foreach (QPushButton *button, itemButtons) {
148         button->setEnabled(enable);
149     }
150 }
151
152 #endif // ! Q_WS_MAEMO_5
153
154 #ifdef Q_WS_MAEMO_5
155
156 bool ListWindow::eventFilter(QObject *obj, QEvent *event)
157 {
158     if (event->type() == QEvent::ContextMenu) {
159         qDebug() << "ListWindow::eventFiler: Received QEvent::ContextMenu";
160         if (popup->actions().size()) {
161             QMouseEvent *mouseEvent = static_cast<QMouseEvent*> (event);
162             QPoint pos = mouseEvent->globalPos();
163             pos.setX(pos.x() - 150);
164             if (pos.x() < 0) {
165                 pos.setX(0);
166             }
167             popup->exec(pos);
168         }
169         return true;
170     } else {
171         return QObject::eventFilter(obj, event);
172     }
173 }
174
175 void ListWindow::onModelChanged()
176 {
177     qDebug() << "ListWindow::onModelChanged";
178     list->setMinimumHeight(list->contentsHeight());
179 }
180
181 #endif // Q_WS_MAEMO_5
182
183 #ifdef Q_OS_SYMBIAN
184
185 void ListWindow::show()
186 {
187     foreach (QWidget *w, QApplication::allWidgets()) {
188         w->setContextMenuPolicy(Qt::NoContextMenu);
189     }
190     showMaximized();
191 }
192
193 #endif // Q_OS_SYMBIAN