1 // Copyright 2010 Jochen Becher
3 // This file is part of MovieSchedule.
5 // MovieSchedule is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // MovieSchedule is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with MovieSchedule. If not, see <http://www.gnu.org/licenses/>.
18 #include "theatercontroller.h"
20 #include "data/cinema.h"
21 #include "data/cinemaschedule.h"
22 #include "control/actioncontroller.h"
23 #include "control/itemmodelsortclient.h"
24 #include "ui/theaterwindow.h"
25 #include "ui/theaterschedulemodel.h"
26 #include "ui/contextdialog.h"
27 #include "ui/uiutils.h"
28 #include "searchclients/theaterschedulesearchclient.h"
29 #include "utils/assertedlocker.h"
30 #include "utils/asynccall.h"
32 #include <QSortFilterProxyModel>
35 static const char *MSG_NO_THEATER_SCHEDULE_FOUND = QT_TRANSLATE_NOOP("TheaterController", "No schedule found for %1.");
36 static const char *MSG_THEATER_SCHEDULE_ERROR = QT_TRANSLATE_NOOP("TheaterController", "Error on fetching theater schedule.");
38 TheaterController::TheaterController(TheaterWindow *theater_window, CinemaSchedule *cinema_schedule, ActionController *action_controller,
39 ItemModelSortController *sort_controller, QThread *search_worker)
41 _theater_window(theater_window),
42 _cinema_schedule(cinema_schedule),
43 _action_controller(action_controller),
44 _sort_controller(sort_controller),
45 _search_worker(search_worker),
46 _current_search_task_id(TheaterScheduleSearchClient::INVALID_SEARCH_TASK_ID),
47 _theater_schedule_model(0),
48 _theater_schedule_proxy_model(new QSortFilterProxyModel(this))
50 connect(_theater_window, SIGNAL(ScheduleEntrySelected(ScheduleEntryKey)), this, SLOT(ScheduleEntrySelected(ScheduleEntryKey)));
53 void TheaterController::ShowTheater(CinemaKey cinema_key)
56 AssertedReadLocker locker(_cinema_schedule->GetLock());
57 _cinema_key = cinema_key;
58 const Cinema *cinema = ((const CinemaSchedule *) _cinema_schedule)->FindCinema(cinema_key);
61 _theater_window->SetTheaterName(cinema->GetName());
62 _theater_window->SetTheaterScheduleModel(_theater_schedule_proxy_model);
63 _theater_window->show();
64 TheaterScheduleSearchClient *client = new TheaterScheduleSearchClient(_cinema_schedule);
65 _current_search_task_id = client->GetSearchTaskId();
66 connect(client, SIGNAL(SearchStarted(int)), this, SLOT(SearchStarted(int)));
67 connect(client, SIGNAL(Reply(int,bool)), this, SLOT(Reply(int,bool)));
68 connect(client, SIGNAL(SearchFinished(int,bool)), this, SLOT(SearchFinished(int,bool)));
69 connect(client, SIGNAL(Error(int)), this, SLOT(Error(int)));
70 client->moveToThread(_search_worker);
71 CallAsync(client, &TheaterScheduleSearchClient::SearchSchedule, cinema->GetKey(), cinema->GetMoviesUrl());
72 // client deletes itself
76 void TheaterController::Cancel()
78 _theater_window->hide();
82 void TheaterController::CancelSearch()
85 AssertedWriteLocker locker(_cinema_schedule->GetLock());
86 _current_search_task_id = TheaterScheduleSearchClient::INVALID_SEARCH_TASK_ID;
87 TheaterScheduleSearchClient::CancelAllRunningSearchs();
90 void TheaterController::ScheduleEntrySelected(ScheduleEntryKey schedule_entry_key)
92 ContextDialog *dialog = new ContextDialog(_cinema_schedule, _theater_window);
93 connect(dialog, SIGNAL(AddToCalendar(ScheduleEntryKey)), _action_controller, SLOT(AddToCalendar(ScheduleEntryKey)));
94 connect(dialog, SIGNAL(CallTheaterByPhone(CinemaKey)), _action_controller, SLOT(CallTheaterByPhone(CinemaKey)));
95 connect(dialog, SIGNAL(FindRouteToTheater(CinemaKey)), _action_controller, SLOT(FindRouteToTheater(CinemaKey)));
96 connect(dialog, SIGNAL(SearchMovieInWeb(MovieKey)), _action_controller, SLOT(SearchMovieInWeb(MovieKey)));
97 connect(dialog, SIGNAL(SearchTheaterInWeb(CinemaKey)), _action_controller, SLOT(SearchTheaterInWeb(CinemaKey)));
98 dialog->Show(schedule_entry_key);
99 // dialog deletes itself
102 void TheaterController::SearchStarted(int search_task_id)
104 if (search_task_id != _current_search_task_id) {
107 _theater_window->SetBusy(true);
110 void TheaterController::Reply(int search_task_id, bool intermediate)
112 if (search_task_id != _current_search_task_id) {
115 Sort(intermediate, SLOT(SortFinished(QAbstractItemModel*,int,bool)));
118 void TheaterController::Error(int search_task_id)
120 if (search_task_id != _current_search_task_id) {
123 Sort(false, SLOT(SortErrorFinished(QAbstractItemModel*,int,bool)));
126 void TheaterController::SearchFinished(int search_task_id, bool success)
129 if (search_task_id != _current_search_task_id) {
132 _theater_window->SetBusy(false);
135 void TheaterController::Sort(bool intermediate, const char *slot)
137 TheaterScheduleModel *theater_schedule_model = new TheaterScheduleModel(_cinema_schedule, _cinema_key, this);
138 theater_schedule_model->Update();
139 QSortFilterProxyModel *sort_model = new QSortFilterProxyModel(this);
140 sort_model->setSortCaseSensitivity(Qt::CaseInsensitive);
141 sort_model->setSortRole(TheaterScheduleModel::SortRole);
142 sort_model->setDynamicSortFilter(false);
143 sort_model->setSourceModel(theater_schedule_model);
144 ItemModelSortClient *sort_client = new ItemModelSortClient(_sort_controller, this);
145 connect(sort_client, SIGNAL(SortFinished(QAbstractItemModel*,int,bool)), this, slot);
146 sort_client->Sort(sort_model, _current_search_task_id, intermediate);
147 // proxy deletes itself
150 void TheaterController::SortFinished(QAbstractItemModel *model, int search_task_id, bool intermediate)
152 if (search_task_id != _current_search_task_id) {
157 if (_theater_schedule_model->rowCount() == 0) {
158 _theater_window->SetError(tr(MSG_NO_THEATER_SCHEDULE_FOUND).arg(_cinema_key.GetName()));
163 void TheaterController::SortErrorFinished(QAbstractItemModel *model, int search_task_id, bool intermediate)
165 Q_UNUSED(intermediate);
166 if (search_task_id != _current_search_task_id) {
170 if (_theater_schedule_model->rowCount() == 0) {
171 _theater_window->SetError(tr(MSG_THEATER_SCHEDULE_ERROR));
173 UiUtils::ShowError(tr(MSG_THEATER_SCHEDULE_ERROR));
177 void TheaterController::SetModel(QAbstractItemModel *model)
179 delete _theater_schedule_proxy_model->sourceModel();
180 _theater_schedule_proxy_model->setSourceModel(model);
181 delete _theater_schedule_model;
183 _theater_schedule_model = (TheaterScheduleModel *) ((QSortFilterProxyModel *) model)->sourceModel();
185 _theater_schedule_model = 0;