1 #include "channelsview.h"
4 #include "searchparams.h"
5 #include "channelmodel.h"
6 #include "channelsitemdelegate.h"
9 #include "channelaggregator.h"
10 #include "aggregatevideosource.h"
11 #include "painterutils.h"
12 #include "mainwindow.h"
18 static const char *sortByKey = "subscriptionsSortBy";
19 static const char *showUpdatedKey = "subscriptionsShowUpdated";
21 ChannelsView::ChannelsView(QWidget *parent) : QListView(parent),
25 setItemDelegate(new ChannelsItemDelegate(this));
26 setSelectionMode(QAbstractItemView::ExtendedSelection);
30 setFlow(QListView::LeftToRight);
32 setResizeMode(QListView::Adjust);
33 setMovement(QListView::Static);
34 setUniformItemSizes(true);
37 setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
38 setFrameShape(QFrame::NoFrame);
39 setAttribute(Qt::WA_MacShowFocusRect, false);
41 QPalette p = palette();
42 p.setColor(QPalette::Disabled, QPalette::Base, p.base().color());
43 p.setColor(QPalette::Disabled, QPalette::Text, p.text().color());
46 verticalScrollBar()->setPageStep(3);
47 verticalScrollBar()->setSingleStep(1);
49 setMouseTracking(true);
51 connect(this, SIGNAL(clicked(const QModelIndex &)),
52 SLOT(itemActivated(const QModelIndex &)));
53 connect(this, SIGNAL(entered(const QModelIndex &)),
54 SLOT(itemEntered(const QModelIndex &)));
56 channelsModel = new ChannelsModel(this);
57 setModel(channelsModel);
58 connect(this, SIGNAL(viewportEntered()),
59 channelsModel, SLOT(clearHover()));
63 connect(ChannelAggregator::instance(), SIGNAL(channelChanged(YTUser*)),
64 channelsModel, SLOT(updateChannel(YTUser*)));
65 connect(ChannelAggregator::instance(), SIGNAL(unwatchedCountChanged(int)),
66 SLOT(unwatchedCountChanged(int)));
68 unwatchedCountChanged(ChannelAggregator::instance()->getUnwatchedCount());
71 void ChannelsView::setupActions() {
74 markAsWatchedAction = new QAction(
75 Utils::icon("mark-watched"), tr("Mark all as watched"), this);
76 markAsWatchedAction->setEnabled(false);
77 markAsWatchedAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_W));
78 connect(markAsWatchedAction, SIGNAL(triggered()), SLOT(markAllAsWatched()));
79 statusActions << markAsWatchedAction;
81 showUpdated = settings.value(showUpdatedKey, false).toBool();
82 QAction *showUpdatedAction = new QAction(
83 Utils::icon("show-updated"), tr("Show Updated"), this);
84 showUpdatedAction->setCheckable(true);
85 showUpdatedAction->setChecked(showUpdated);
86 showUpdatedAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_U));
87 connect(showUpdatedAction, SIGNAL(toggled(bool)), SLOT(toggleShowUpdated(bool)));
88 statusActions << showUpdatedAction;
90 SortBy sortBy = static_cast<SortBy>(settings.value(sortByKey, SortByName).toInt());
92 QMenu *sortMenu = new QMenu(this);
93 QActionGroup *sortGroup = new QActionGroup(this);
95 QAction *sortByNameAction = new QAction(tr("Name"), this);
96 sortByNameAction->setActionGroup(sortGroup);
97 sortByNameAction->setCheckable(true);
98 if (sortBy == SortByName) sortByNameAction->setChecked(true);
99 connect(sortByNameAction, SIGNAL(triggered()), SLOT(setSortByName()));
100 sortMenu->addAction(sortByNameAction);
102 QAction *sortByUpdatedAction = new QAction(tr("Last Updated"), this);
103 sortByUpdatedAction->setActionGroup(sortGroup);
104 sortByUpdatedAction->setCheckable(true);
105 if (sortBy == SortByUpdated) sortByUpdatedAction->setChecked(true);
106 connect(sortByUpdatedAction, SIGNAL(triggered()), SLOT(setSortByUpdated()));
107 sortMenu->addAction(sortByUpdatedAction);
109 QAction *sortByAddedAction = new QAction(tr("Last Added"), this);
110 sortByAddedAction->setActionGroup(sortGroup);
111 sortByAddedAction->setCheckable(true);
112 if (sortBy == SortByAdded) sortByAddedAction->setChecked(true);
113 connect(sortByAddedAction, SIGNAL(triggered()), SLOT(setSortByAdded()));
114 sortMenu->addAction(sortByAddedAction);
116 QAction *sortByLastWatched = new QAction(tr("Last Watched"), this);
117 sortByLastWatched->setActionGroup(sortGroup);
118 sortByLastWatched->setCheckable(true);
119 if (sortBy == SortByLastWatched) sortByLastWatched->setChecked(true);
120 connect(sortByLastWatched, SIGNAL(triggered()), SLOT(setSortByLastWatched()));
121 sortMenu->addAction(sortByLastWatched);
123 QAction *sortByMostWatched = new QAction(tr("Most Watched"), this);
124 sortByMostWatched->setActionGroup(sortGroup);
125 sortByMostWatched->setCheckable(true);
126 if (sortBy == SortByMostWatched) sortByMostWatched->setChecked(true);
127 connect(sortByMostWatched, SIGNAL(triggered()), SLOT(setSortByMostWatched()));
128 sortMenu->addAction(sortByMostWatched);
130 QToolButton *sortButton = new QToolButton(this);
131 sortButton->setText(tr("Sort by"));
132 sortButton->setIcon(Utils::icon("sort"));
133 sortButton->setIconSize(QSize(16, 16));
134 sortButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
135 sortButton->setPopupMode(QToolButton::InstantPopup);
136 sortButton->setMenu(sortMenu);
137 QWidgetAction *widgetAction = new QWidgetAction(this);
138 widgetAction->setDefaultWidget(sortButton);
139 widgetAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_O));
140 statusActions << widgetAction;
142 foreach (QAction *action, statusActions)
143 Utils::setupAction(action);
146 void ChannelsView::appear() {
148 foreach (QAction* action, statusActions)
149 MainWindow::instance()->showActionInStatusBar(action, true);
151 ChannelAggregator::instance()->run();
154 void ChannelsView::disappear() {
155 foreach (QAction* action, statusActions)
156 MainWindow::instance()->showActionInStatusBar(action, false);
159 void ChannelsView::mouseMoveEvent(QMouseEvent *event) {
160 QListView::mouseMoveEvent(event);
161 const QModelIndex index = indexAt(event->pos());
162 if (index.isValid()) setCursor(Qt::PointingHandCursor);
166 void ChannelsView::leaveEvent(QEvent *event) {
167 QListView::leaveEvent(event);
168 channelsModel->clearHover();
171 void ChannelsView::itemEntered(const QModelIndex &index) {
172 // channelsModel->setHoveredRow(index.row());
175 void ChannelsView::itemActivated(const QModelIndex &index) {
176 ChannelsModel::ItemTypes itemType = channelsModel->typeForIndex(index);
177 if (itemType == ChannelsModel::ItemChannel) {
178 YTUser *user = channelsModel->userForIndex(index);
179 SearchParams *params = new SearchParams();
180 params->setAuthor(user->getUserId());
181 params->setSortBy(SearchParams::SortByNewest);
182 params->setTransient(true);
183 YTSearch *videoSource = new YTSearch(params, this);
184 emit activated(videoSource);
185 user->updateWatched();
186 } else if (itemType == ChannelsModel::ItemAggregate) {
187 AggregateVideoSource *videoSource = new AggregateVideoSource(this);
188 videoSource->setName(tr("All Videos"));
189 emit activated(videoSource);
190 } else if (itemType == ChannelsModel::ItemUnwatched) {
191 AggregateVideoSource *videoSource = new AggregateVideoSource(this);
192 videoSource->setName(tr("Unwatched Videos"));
193 videoSource->setUnwatched(true);
194 emit activated(videoSource);
198 void ChannelsView::paintEvent(QPaintEvent *event) {
199 if (model()->rowCount() < 3) {
201 if (!errorMessage.isEmpty())
203 else if (showUpdated)
204 msg = tr("There are no updated subscriptions at this time.");
206 msg = tr("You have no subscriptions. "
207 "Use the star symbol to subscribe to channels.");
208 PainterUtils::centeredMessage(msg, viewport());
209 } else QListView::paintEvent(event);
210 PainterUtils::topShadow(viewport());
213 void ChannelsView::toggleShowUpdated(bool enable) {
214 showUpdated = enable;
217 settings.setValue(showUpdatedKey, showUpdated);
220 void ChannelsView::updateQuery(bool transition) {
221 errorMessage.clear();
222 if (!Database::exists()) return;
224 QString sql = "select user_id from subscriptions";
226 sql += " where notify_count>0";
230 sql += " order by updated desc";
233 sql += " order by added desc";
235 case SortByLastWatched:
236 sql += " order by watched desc";
238 case SortByMostWatched:
239 sql += " order by views desc";
242 sql += " order by name collate nocase";
248 Extra::fadeInWidget(this, this);
251 channelsModel->setQuery(sql, Database::instance().getConnection());
252 if (channelsModel->lastError().isValid()) {
253 qWarning() << channelsModel->lastError().text();
254 errorMessage = channelsModel->lastError().text();
258 void ChannelsView::setSortBy(SortBy sortBy) {
259 this->sortBy = sortBy;
262 settings.setValue(sortByKey, (int)sortBy);
265 void ChannelsView::markAllAsWatched() {
266 ChannelAggregator::instance()->markAllAsWatched();
268 markAsWatchedAction->setEnabled(false);
271 void ChannelsView::unwatchedCountChanged(int count) {
272 markAsWatchedAction->setEnabled(count > 0);
273 channelsModel->updateUnwatched();