1
/* This file is part of Clementine.
2
Copyright 2010, David Sansome <me@davidsansome.com>
4
Clementine is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
9
Clementine is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
18
#include "radioviewcontainer.h"
19
#include "radiomodel.h"
20
#include "radioservice.h"
21
#include "ui_radioviewcontainer.h"
22
#include "core/mergedproxymodel.h"
24
#include <QMetaMethod>
28
const int RadioViewContainer::kAnimationDuration = 500;
30
RadioViewContainer::RadioViewContainer(QWidget *parent)
32
ui_(new Ui_RadioViewContainer),
34
current_service_(NULL),
39
connect(ui_->tree, SIGNAL(collapsed(QModelIndex)), SLOT(Collapsed(QModelIndex)));
40
connect(ui_->tree, SIGNAL(expanded(QModelIndex)), SLOT(Expanded(QModelIndex)));
41
connect(ui_->tree, SIGNAL(FocusOnFilterSignal(QKeyEvent*)), SLOT(FocusOnFilter(QKeyEvent*)));
44
RadioViewContainer::~RadioViewContainer() {
48
RadioView* RadioViewContainer::tree() const {
52
void RadioViewContainer::SetModel(RadioModel* model) {
55
ui_->tree->setModel(model->merged_model());
57
connect(ui_->tree->selectionModel(),
58
SIGNAL(currentChanged(QModelIndex,QModelIndex)),
59
SLOT(CurrentIndexChanged(QModelIndex)));
62
void RadioViewContainer::ServiceChanged(const QModelIndex& index) {
63
RadioService* service = index.data(RadioModel::Role_Service).value<RadioService*>();
64
if (!service || service == current_service_)
66
current_service_ = service;
68
QWidget* header = service->HeaderWidget();
69
if (header && !headers_.contains(header)) {
70
header->setParent(ui_->header_container);
71
header->setMaximumHeight(0);
72
ui_->header_container->layout()->addWidget(header);
77
d.animation_ = new QTimeLine(kAnimationDuration, this);
78
d.animation_->setFrameRange(0, header->sizeHint().height());
79
connect(d.animation_, SIGNAL(frameChanged(int)), SLOT(SetHeaderHeight(int)));
81
headers_.insert(header, d);
84
SetHeaderVisible(current_header_, false);
85
current_header_ = header;
86
SetHeaderVisible(current_header_, true);
89
void RadioViewContainer::CurrentIndexChanged(const QModelIndex& index) {
90
ServiceChanged(index);
93
void RadioViewContainer::Collapsed(const QModelIndex& index) {
94
if (model_->merged_model()->mapToSource(index).model() == model_) {
95
SetHeaderVisible(current_header_, false);
96
current_service_ = NULL;
97
current_header_ = NULL;
101
void RadioViewContainer::Expanded(const QModelIndex& index) {
102
ServiceChanged(index);
105
void RadioViewContainer::SetHeaderVisible(QWidget* header, bool visible) {
109
HeaderData& d = headers_[header];
110
if (d.visible_ == visible)
112
d.visible_ = visible;
114
d.animation_->setDirection(visible ? QTimeLine::Forward : QTimeLine::Backward);
115
d.animation_->start();
118
void RadioViewContainer::FocusOnFilter(QKeyEvent* event) {
121
if (current_header_) {
122
int slot = current_header_->metaObject()->indexOfSlot(
123
QMetaObject::normalizedSignature("FocusOnFilter(QKeyEvent*)"));
125
current_header_->metaObject()->method(slot).invoke(
126
current_header_, Q_ARG(QKeyEvent*, event));
131
void RadioViewContainer::SetHeaderHeight(int height) {
132
QTimeLine* animation = qobject_cast<QTimeLine*>(sender());
133
QWidget* header = NULL;
134
foreach (QWidget* h, headers_.keys()) {
135
if (headers_[h].animation_ == animation) {
142
header->setMaximumHeight(height);