Updated changelog
[grr] / src / feedswindow.cpp
1 #include <QMenuBar>
2 #include <QDebug>
3 #include <QPainter>
4 #include <QHBoxLayout>
5 #include <QMaemo5InformationBox>
6 #include <QMessageBox>
7 #include "feedswindow.h"
8 #include "entrieswindow.h"
9
10 #define APPNAME "grr"
11 #define APPVERSION "0.0.4"
12
13 FeedsWindow::FeedsWindow(QWidget *) : QMainWindow(0) {
14         setAttribute(Qt::WA_Maemo5StackedWindow);
15         
16         setWindowIcon(QIcon("/usr/share/icons/hicolor/64x64/apps/grr.png"));
17         
18         settings = new QSettings("dufo.be", "grr"); 
19
20         menuBar()->addAction(tr("Settings"), this, SLOT(showSettings()));
21         menuBar()->addAction(tr("Sync now"), this, SLOT(sync()));
22         menuBar()->addAction(tr("About"), this, SLOT(about()));
23
24         QActionGroup *filter_group = new QActionGroup(this);
25         show_all = new QAction(tr("Show All"), filter_group);
26         show_all->setCheckable(true);
27         show_updated= new QAction(tr("Show Updated"), filter_group);
28         show_updated->setCheckable(true);
29
30         if(settings->value("show_updated", false).toBool())
31                 show_updated->setChecked(true);
32         else
33                 show_all->setChecked(true);
34
35         menuBar()->addActions(filter_group->actions());
36
37         setWindowTitle(APPNAME);
38
39         list = new QListView();
40         setCentralWidget(list);
41         list->setItemDelegate(new FeedListDelegate(this));
42         
43         connect(list, SIGNAL(activated(const QModelIndex &)),
44                 SLOT(feedSelected(const QModelIndex &)));
45
46         reader = new GoogleReader();
47
48         connect(reader, SIGNAL(updateUnreadComplete()), SLOT(feedsUpdated()));
49         connect(reader, SIGNAL(allReadChanged()), SLOT(refreshModel()));
50         connect(reader, SIGNAL(loginFailed(QString)), SLOT(loginFailed(QString)));
51         
52         connect(show_updated, SIGNAL(toggled(bool)), SLOT(showUpdated(bool)));
53         
54         if((settings->value("login", "").toString() == "") || 
55                 (settings->value("passwd", "").toString() == "")) {
56                 emit loginFailed("Incomplete username or password");
57         }
58         else {
59                 reader->setLogin(settings->value("login", "").toString());
60                 reader->setPasswd(settings->value("passwd", "").toString());
61                 sync();
62         }
63 }
64
65 FeedsWindow::~FeedsWindow() {
66 }
67
68 void FeedsWindow::showSettings() {
69         SettingsDialog settingsDialog(this, settings);
70         if(settingsDialog.exec() == QDialog::Accepted) {
71                 reader->logOut();
72                 reader->setLogin(settings->value("login", "").toString());
73                 reader->setPasswd(settings->value("passwd", "").toString());
74                 sync();
75         }
76 }
77
78 void FeedsWindow::sync() {
79         setAttribute(Qt::WA_Maemo5ShowProgressIndicator, true);
80         reader->updateSubscriptions();
81         reader->updateUnread();
82 }
83
84 void FeedsWindow::refreshModel() {
85         QList<Feed *>feeds = reader->getFeeds();
86         QAbstractItemModel *old_model = list->model();
87         FeedListModel *new_model = new FeedListModel(this, feeds, show_updated->isChecked());
88         list->setModel(new_model);
89         connect(show_updated, SIGNAL(toggled(bool)), new_model, SLOT(showUpdated(bool)));
90         delete(old_model);
91 }
92
93 void FeedsWindow::feedsUpdated() {
94         refreshModel();
95         setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
96 }
97
98 void FeedsWindow::feedSelected(const QModelIndex &index) {
99         Feed *f = qVariantValue<Feed *>(index.data());
100         EntriesWindow *w = new EntriesWindow(this, f);
101         w->show();
102 }
103
104 void FeedsWindow::showUpdated(bool updated) {
105         settings->setValue("show_updated", updated);
106 }
107
108 void FeedsWindow::loginFailed(QString message) {
109         setAttribute(Qt::WA_Maemo5ShowProgressIndicator, false);
110         QMaemo5InformationBox::information(this, message, QMaemo5InformationBox::DefaultTimeout);
111         showSettings();
112 }
113
114 void FeedsWindow::about() {
115         QMessageBox::about(this, APPNAME " " APPVERSION, "");
116 }
117
118 int FeedListModel::rowCount(const QModelIndex &) const {
119         int size = 0;
120         
121         if(show_updated) {
122                 for(int i = 0; i < feed_list.size(); i++) {
123                         if(feed_list.at(i)->unread || feed_list.at(i)->special)
124                                 size++;
125                 }
126         }
127         else
128                 size = feed_list.size();
129
130         return size;;
131 }
132
133 QVariant FeedListModel::data(const QModelIndex &index, int role) const {
134         if(!index.isValid())
135                 return QVariant();
136
137         if(index.row() >= rowCount() || index.row() < 0) {
138                 return QVariant();
139         }
140
141         if(role == Qt::DisplayRole) {
142                 if(show_updated) {
143                         int i, j;
144                         for(i = 0, j = 0; i < feed_list.size(); i++) {
145                                 if(feed_list.at(i)->unread || feed_list.at(i)->special) j++;
146                                 if(j > index.row())
147                                         return qVariantFromValue(feed_list.at(i));
148                         }
149                 }
150                 else
151                         return qVariantFromValue(feed_list.at(index.row()));
152         }
153
154         return QVariant();
155 }
156
157 void FeedListModel::showUpdated(bool updated) {
158         beginResetModel();
159         show_updated = updated;
160         endResetModel();
161 }
162
163 void FeedListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
164         const QModelIndex &index) const {
165    
166         QStyledItemDelegate::paint(painter, option, index);
167
168         Feed *f = qVariantValue<Feed *>(index.data());
169
170         QRect rect = option.rect;
171         rect.adjust(20, 8, -20, -8);
172         QFont font = option.font;
173         int flags = Qt::AlignVCenter;
174
175         painter->save();
176
177         if(f->cat_label != "")
178                 flags = Qt::AlignTop;
179
180         if(f->unread) {
181                 if(!(option.state & QStyle::State_Selected))
182                         painter->setPen(option.palette.highlight().color());
183
184                 painter->drawText(rect, flags | Qt::AlignRight, QString("%1").arg(f->unread)); 
185         }
186         
187         painter->drawText(rect, flags | Qt::AlignLeft, f->title); 
188
189         if(f->cat_label != "") {
190                 painter->setPen(option.palette.mid().color());
191                 font.setPointSizeF(font.pointSizeF() * 0.70);
192                 painter->setFont(font);
193                 painter->drawText(rect, Qt::AlignBottom | Qt::AlignLeft, f->cat_label);
194         }
195         
196         painter->restore();
197 }
198
199 SettingsDialog::SettingsDialog(QWidget *parent, QSettings *s) : QDialog(parent) {
200         settings = s;
201
202         loginLabel = new QLabel(tr("Login:"));
203         loginEdit = new QLineEdit(settings->value("login", "").toString());
204         loginLabel->setBuddy(loginEdit);
205
206         passwdLabel = new QLabel(tr("Password:"));
207         passwdEdit = new QLineEdit(settings->value("passwd", "").toString());
208         passwdEdit->setEchoMode(QLineEdit::PasswordEchoOnEdit);
209         passwdLabel->setBuddy(passwdEdit);
210
211         saveButton = new QPushButton(tr("Save"));
212         saveButton->setDefault(true);
213         cancelButton = new QPushButton(tr("Cancel"));
214         cancelButton->setDefault(false);
215
216         buttonBox = new QDialogButtonBox(Qt::Vertical);
217         buttonBox->addButton(cancelButton, QDialogButtonBox::ActionRole);
218         buttonBox->addButton(saveButton, QDialogButtonBox::ActionRole);
219
220         QHBoxLayout *loginLayout = new QHBoxLayout;
221         loginLayout->addWidget(loginLabel);
222         loginLayout->addWidget(loginEdit);
223
224         QHBoxLayout *passwdLayout = new QHBoxLayout;
225         passwdLayout->addWidget(passwdLabel);
226         passwdLayout->addWidget(passwdEdit);
227
228         QVBoxLayout *leftLayout = new QVBoxLayout;
229         leftLayout->addLayout(loginLayout);
230         leftLayout->addLayout(passwdLayout);
231         leftLayout->addStretch(1);
232
233         QGridLayout *mainLayout = new QGridLayout;
234         mainLayout->setSizeConstraint(QLayout::SetFixedSize);
235         mainLayout->addLayout(leftLayout, 0, 0);
236         mainLayout->addWidget(buttonBox, 0, 1);
237         setLayout(mainLayout);
238
239         setWindowTitle(tr("Settings"));
240
241         connect(saveButton, SIGNAL(clicked()), SLOT(accept()));
242         connect(cancelButton, SIGNAL(clicked()), SLOT(reject()));
243 }
244                 
245 void SettingsDialog::accept() {
246         settings->setValue("login", loginEdit->text());
247         settings->setValue("passwd", passwdEdit->text());
248         QDialog::accept();
249 }