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 "moviecontroller.h"
20 #include "data/movie.h"
21 #include "data/cinemaschedule.h"
22 #include "control/actioncontroller.h"
23 #include "control/itemmodelsortclient.h"
24 #include "ui/moviewindow.h"
25 #include "ui/movieschedulemodel.h"
26 #include "ui/contextdialog.h"
27 #include "ui/uiutils.h"
28 #include "searchclients/movieschedulesearchclient.h"
29 #include "utils/assertedlocker.h"
30 #include "utils/asynccall.h"
32 #include <QSortFilterProxyModel>
35 static const char *MSG_NO_MOVIE_SCHEDULE_FOUND = QT_TRANSLATE_NOOP("MovieController", "No schedule found for %1.");
36 static const char *MSG_MOVIE_SCHEDULE_ERROR = QT_TRANSLATE_NOOP("MovieController", "Error on fetching movie schedule.");
38 MovieController::MovieController(MovieWindow *movie_window, CinemaSchedule *cinema_schedule,
39 ActionController *action_controller, ItemModelSortController *sort_controller,
40 QThread *search_worker)
42 _movie_window(movie_window),
43 _cinema_schedule(cinema_schedule),
44 _action_controller(action_controller),
45 _sort_controller(sort_controller),
46 _search_worker(search_worker),
47 _current_search_task_id(MovieScheduleSearchClient::INVALID_SEARCH_TASK_ID),
48 _movie_schedule_model(0),
49 _movie_schedule_proxy_model(new QSortFilterProxyModel(this))
51 connect(_movie_window, SIGNAL(ScheduleEntrySelected(ScheduleEntryKey)), this, SLOT(ScheduleEntrySelected(ScheduleEntryKey)));
54 void MovieController::ShowMovie(MovieKey movie_key)
57 AssertedReadLocker locker(_cinema_schedule->GetLock());
58 _movie_key = movie_key;
59 const Movie *movie = ((const CinemaSchedule *) _cinema_schedule)->FindMovie(movie_key);
62 _movie_window->SetMovieName(movie->GetName());
63 _movie_window->SetMovieScheduleModel(_movie_schedule_proxy_model);
64 _movie_window->show();
65 MovieScheduleSearchClient *client = new MovieScheduleSearchClient(_cinema_schedule);
66 _current_search_task_id = client->GetSearchTaskId();
67 connect(client, SIGNAL(SearchStarted(int)), this, SLOT(SearchStarted(int)));
68 connect(client, SIGNAL(Reply(int, bool)), this, SLOT(Reply(int, bool)));
69 connect(client, SIGNAL(SearchFinished(int, bool)), this, SLOT(SearchFinished(int, bool)));
70 connect(client, SIGNAL(Error(int)), this, SLOT(Error(int)));
71 client->moveToThread(_search_worker);
72 CallAsync(client, &MovieScheduleSearchClient::SearchSchedule, movie->GetKey(), movie->GetTheatersUrl());
73 // search client deletes itself
77 void MovieController::Cancel()
79 _movie_window->hide();
83 void MovieController::CancelSearch()
86 AssertedWriteLocker locker(_cinema_schedule->GetLock());
87 _current_search_task_id = MovieScheduleSearchClient::INVALID_SEARCH_TASK_ID;
88 MovieScheduleSearchClient::CancelAllRunningSearchs();
91 void MovieController::ScheduleEntrySelected(ScheduleEntryKey schedule_entry_key)
93 ContextDialog *dialog = new ContextDialog(_cinema_schedule, _movie_window);
94 connect(dialog, SIGNAL(AddToCalendar(ScheduleEntryKey)), _action_controller, SLOT(AddToCalendar(ScheduleEntryKey)));
95 connect(dialog, SIGNAL(CallTheaterByPhone(CinemaKey)), _action_controller, SLOT(CallTheaterByPhone(CinemaKey)));
96 connect(dialog, SIGNAL(FindRouteToTheater(CinemaKey)), _action_controller, SLOT(FindRouteToTheater(CinemaKey)));
97 connect(dialog, SIGNAL(SearchMovieInWeb(MovieKey)), _action_controller, SLOT(SearchMovieInWeb(MovieKey)));
98 connect(dialog, SIGNAL(SearchTheaterInWeb(CinemaKey)), _action_controller, SLOT(SearchTheaterInWeb(CinemaKey)));
99 dialog->Show(schedule_entry_key);
100 // dialog deletes itself
103 void MovieController::SearchStarted(int search_task_id)
105 if (search_task_id != _current_search_task_id) {
108 _movie_window->SetBusy(true);
111 void MovieController::Reply(int search_task_id, bool intermediate)
113 if (search_task_id != _current_search_task_id) {
116 Sort(intermediate, SLOT(SortFinished(QAbstractItemModel*,int,bool)));
119 void MovieController::Error(int search_task_id)
121 if (search_task_id != _current_search_task_id) {
124 Sort(false, SLOT(SortErrorFinished(QAbstractItemModel*,int,bool)));
127 void MovieController::SearchFinished(int search_task_id, bool success)
130 if (search_task_id != _current_search_task_id) {
133 _movie_window->SetBusy(false);
136 void MovieController::Sort(bool intermediate, const char *slot)
138 MovieScheduleModel *movie_schedule_model = new MovieScheduleModel(_cinema_schedule, _movie_key, this);
139 movie_schedule_model->Update();
140 QSortFilterProxyModel *sort_model = new QSortFilterProxyModel(this);
141 sort_model->setSortCaseSensitivity(Qt::CaseInsensitive);
142 sort_model->setSortRole(MovieScheduleModel::SortRole);
143 sort_model->setDynamicSortFilter(false);
144 sort_model->setSourceModel(movie_schedule_model);
145 ItemModelSortClient *sort_client = new ItemModelSortClient(_sort_controller, this);
146 connect(sort_client, SIGNAL(SortFinished(QAbstractItemModel*,int,bool)), this, slot);
147 sort_client->Sort(sort_model, _current_search_task_id, intermediate);
148 // proxy deletes itself
151 void MovieController::SortFinished(QAbstractItemModel *model, int search_task_id, bool intermediate)
153 if (search_task_id != _current_search_task_id) {
158 if (_movie_schedule_model->rowCount() == 0) {
159 _movie_window->SetError(tr(MSG_NO_MOVIE_SCHEDULE_FOUND).arg(_movie_key.GetName()));
164 void MovieController::SortErrorFinished(QAbstractItemModel *model, int search_task_id, bool intermediate)
166 Q_UNUSED(intermediate);
167 if (search_task_id != _current_search_task_id) {
171 if (_movie_schedule_model->rowCount() == 0) {
172 _movie_window->SetError(tr(MSG_MOVIE_SCHEDULE_ERROR));
174 UiUtils::ShowError(tr(MSG_MOVIE_SCHEDULE_ERROR));
178 void MovieController::SetModel(QAbstractItemModel *model)
180 delete _movie_schedule_proxy_model->sourceModel();
181 _movie_schedule_proxy_model->setSourceModel(model);
182 delete _movie_schedule_model;
184 _movie_schedule_model = (MovieScheduleModel *) ((QSortFilterProxyModel *) model)->sourceModel();
186 _movie_schedule_model = 0;