4 * Copyright (C) 2012-2013 Team XBMC
7 * This Program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This Program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with XBMC; see the file COPYING. If not, see
19 * <http://www.gnu.org/licenses/>.
24 #include "PVRChannel.h"
25 #include "settings/lib/ISettingCallback.h"
26 #include "utils/JobManager.h"
28 #include <boost/shared_ptr.hpp>
32 struct EpgSearchFilter;
37 #define XBMC_INTERNAL_GROUP_RADIO 1
38 #define XBMC_INTERNAL_GROUP_TV 2
40 #define PVR_GROUP_TYPE_DEFAULT 0
41 #define PVR_GROUP_TYPE_INTERNAL 1
42 #define PVR_GROUP_TYPE_USER_DEFINED 2
44 class CPVRChannelGroups;
45 class CPVRChannelGroupInternal;
46 class CPVRChannelGroupsContainer;
50 CPVRChannelPtr channel;
51 unsigned int iChannelNumber;
52 } PVRChannelGroupMember;
60 class CPVRChannelGroup;
61 typedef boost::shared_ptr<PVR::CPVRChannelGroup> CPVRChannelGroupPtr;
63 /** A group of channels */
64 class CPVRChannelGroup : public Observable,
66 public ISettingCallback
69 friend class CPVRChannelGroups;
70 friend class CPVRChannelGroupInternal;
71 friend class CPVRChannelGroupsContainer;
72 friend class CPVRDatabase;
75 CPVRChannelGroup(void);
78 * @brief Create a new channel group instance.
79 * @param bRadio True if this group holds radio channels.
80 * @param iGroupId The database ID of this group.
81 * @param strGroupName The name of this group.
83 CPVRChannelGroup(bool bRadio, unsigned int iGroupId, const CStdString &strGroupName);
86 * @brief Create a new channel group instance from a channel group provided by an add-on.
87 * @param group The channel group provided by the add-on.
89 CPVRChannelGroup(const PVR_CHANNEL_GROUP &group);
92 * @brief Copy constructor
93 * @param group Source group
95 CPVRChannelGroup(const CPVRChannelGroup &group);
97 virtual ~CPVRChannelGroup(void);
99 bool operator ==(const CPVRChannelGroup &right) const;
100 bool operator !=(const CPVRChannelGroup &right) const;
103 * @return The amount of group members
105 int Size(void) const;
108 * @brief Refresh the channel list from the clients.
110 virtual bool Update(void);
113 * @brief Change the channelnumber of a group. Used by CGUIDialogPVRChannelManager. Call SortByChannelNumber() and Renumber() after all changes are done.
114 * @param channel The channel to change the channel number for.
115 * @param iChannelNumber The new channel number.
117 bool SetChannelNumber(const CPVRChannel &channel, unsigned int iChannelNumber);
120 * @brief Move a channel from position iOldIndex to iNewIndex.
121 * @param iOldChannelNumber The channel number of the channel to move.
122 * @param iNewChannelNumber The new channel number.
123 * @param bSaveInDb If true, save this change in the database.
124 * @return True if the channel was moved successfully, false otherwise.
126 virtual bool MoveChannel(unsigned int iOldChannelNumber, unsigned int iNewChannelNumber, bool bSaveInDb = true);
129 * @brief Search missing channel icons for all known channels.
130 * @param bUpdateDb If true, update the changed values in the database.
132 void SearchAndSetChannelIcons(bool bUpdateDb = false);
135 * @brief Remove a channel from this container.
136 * @param channel The channel to remove.
137 * @return True if the channel was found and removed, false otherwise.
139 virtual bool RemoveFromGroup(const CPVRChannel &channel);
142 * @brief Add a channel to this container.
143 * @param channel The channel to add.
144 * @param iChannelNumber The channel number of the channel number to add. Use -1 to add it at the end.
145 * @return True if the channel was added, false otherwise.
147 virtual bool AddToGroup(CPVRChannel &channel, int iChannelNumber = 0);
150 * @brief Change the name of this group.
151 * @param strGroupName The new group name.
152 * @param bSaveInDb Save in the database or not.
153 * @return True if the something changed, false otherwise.
155 bool SetGroupName(const CStdString &strGroupName, bool bSaveInDb = false);
158 * @brief Persist changed or new data.
159 * @return True if the channel was persisted, false otherwise.
164 * @brief Check whether a channel is in this container.
165 * @param channel The channel to find.
166 * @return True if the channel was found, false otherwise.
168 virtual bool IsGroupMember(const CPVRChannel &channel) const;
171 * @brief Check whether a channel is in this container.
172 * @param iChannelId The db id of the channel to find.
173 * @return True if the channel was found, false otherwise.
175 virtual bool IsGroupMember(int iChannelId) const;
178 * @brief Check if this group is the internal group containing all channels.
179 * @return True if it's the internal group, false otherwise.
181 virtual bool IsInternalGroup(void) const { return false; }
184 * @brief True if this group holds radio channels, false if it holds TV channels.
185 * @return True if this group holds radio channels, false if it holds TV channels.
187 bool IsRadio(void) const { return m_bRadio; }
190 * @brief True if sorting should be prevented when adding/updating channels to the group.
191 * @return True if sorting should be prevented when adding/updating channels to the group.
193 bool PreventSortAndRenumber(void) const;
196 * @brief The database ID of this group.
197 * @return The database ID of this group.
199 int GroupID(void) const;
202 * @brief Set the database ID of this group.
203 * @param iGroupId The new database ID.
205 void SetGroupID(int iGroupId);
208 * @brief Set the type of this group.
209 * @param the new type for this group.
211 void SetGroupType(int iGroupType);
214 * @brief Return the type of this group.
216 int GroupType(void) const;
219 * @brief Set if sorting and renumbering should happen after adding/updating channels to group.
220 * @param bPreventSortAndRenumber The new sorting and renumbering prevention value for this group.
222 void SetPreventSortAndRenumber(bool bPreventSortAndRenumber = true);
225 * @brief The name of this group.
226 * @return The name of this group.
228 CStdString GroupName(void) const;
230 /*! @name Sort methods
235 * @brief Sort the group and fix up channel numbers.
236 * @return True when numbering changed, false otherwise
238 bool SortAndRenumber(void);
242 virtual void OnSettingChanged(const CSetting *setting);
245 * @brief Get a channel given it's EPG ID.
246 * @param iEpgID The channel EPG ID.
247 * @return The channel or NULL if it wasn't found.
249 CPVRChannelPtr GetByChannelEpgID(int iEpgID) const;
252 * @brief The channel that was played last that has a valid client or NULL if there was none.
253 * @param iCurrentChannel The channelid of the current channel that is playing, or -1 if none
254 * @return The requested channel.
256 CFileItemPtr GetLastPlayedChannel(unsigned int iCurrentChannel = -1) const;
259 * @brief Get a channel given it's channel number.
260 * @param iChannelNumber The channel number.
261 * @return The channel or NULL if it wasn't found.
263 CFileItemPtr GetByChannelNumber(unsigned int iChannelNumber) const;
266 * @brief Get the channel number in this group of the given channel.
267 * @param channel The channel to get the channel number for.
268 * @return The channel number in this group or 0 if the channel isn't a member of this group.
270 unsigned int GetChannelNumber(const CPVRChannel &channel) const;
273 * @brief Get the next channel in this group.
274 * @param channel The current channel.
275 * @return The channel or NULL if it wasn't found.
277 CFileItemPtr GetByChannelUp(const CFileItem &channel) const { return GetByChannelUpDown(channel, true); }
280 * @brief Get the previous channel in this group.
281 * @param channel The current channel.
282 * @return The channel or NULL if it wasn't found.
284 CFileItemPtr GetByChannelDown(const CFileItem &channel) const { return GetByChannelUpDown(channel, false); }
287 * @brief Get a channel given it's index in this container.
288 * @param index The index in this container.
289 * @return The channel or NULL if it wasn't found.
291 CFileItemPtr GetByIndex(unsigned int index) const;
294 * @brief Get the current index in this group of a channel.
295 * @param channel The channel to get the index for.
296 * @return The index or -1 if it wasn't found.
298 int GetIndex(const CPVRChannel &channel) const;
301 * @brief Get the list of channels in a group.
302 * @param results The file list to store the results in.
303 * @param bGroupMembers If true, get the channels that are in this group. Get the channels that are not in this group otherwise.
304 * @return The amount of channels that were added to the list.
306 virtual int GetMembers(CFileItemList &results, bool bGroupMembers = true) const;
309 * @return The next channel group.
311 CPVRChannelGroupPtr GetNextGroup(void) const;
314 * @return The previous channel group.
316 CPVRChannelGroupPtr GetPreviousGroup(void) const;
319 * @brief The amount of hidden channels in this container.
320 * @return The amount of hidden channels in this container.
322 virtual int GetNumHiddenChannels(void) const { return 0; }
325 * @return True if there is at least one channel in this group with changes that haven't been persisted, false otherwise.
327 bool HasChangedChannels(void) const;
330 * @return True if there is at least one new channel in this group that hasn't been persisted, false otherwise.
332 bool HasNewChannels(void) const;
335 * @return True if anything changed in this group that hasn't been persisted, false otherwise.
337 bool HasChanges(void) const;
340 * @brief Reset the channel number cache if this is the selected group in the UI.
342 void ResetChannelNumberCache(void);
344 void OnJobComplete(unsigned int jobID, bool success, CJob* job) {}
347 * @brief Get all EPG tables and apply a filter.
348 * @param results The fileitem list to store the results in.
349 * @param filter The filter to apply.
350 * @return The amount of entries that were added.
352 int GetEPGSearch(CFileItemList &results, const EPG::EpgSearchFilter &filter);
355 * @brief Get all EPG tables.
356 * @param results The fileitem list to store the results in.
357 * @return The amount of entries that were added.
359 int GetEPGAll(CFileItemList &results);
362 * @brief Get all entries that are active now.
363 * @param results The fileitem list to store the results in.
364 * @return The amount of entries that were added.
366 int GetEPGNow(CFileItemList &results);
369 * @brief Get all entries that will be active next.
370 * @param results The fileitem list to store the results in.
371 * @return The amount of entries that were added.
373 int GetEPGNext(CFileItemList &results);
376 * @brief Get the start time of the first entry.
377 * @return The start time.
379 CDateTime GetFirstEPGDate(void) const;
382 * @brief Get the end time of the last entry.
383 * @return The end time.
385 CDateTime GetLastEPGDate(void) const;
387 bool UpdateChannel(const CFileItem &channel, bool bHidden, bool bVirtual, bool bEPGEnabled, bool bParentalLocked, int iEPGSource, int iChannelNumber, const CStdString &strChannelName, const CStdString &strIconPath, const CStdString &strStreamURL);
389 bool ToggleChannelLocked(const CFileItem &channel);
391 virtual bool AddNewChannel(const CPVRChannel &channel, unsigned int iChannelNumber = 0) { return false; }
394 * @brief Get a channel given the channel number on the client.
395 * @param iUniqueChannelId The unique channel id on the client.
396 * @param iClientID The ID of the client.
397 * @return The channel or NULL if it wasn't found.
399 CPVRChannelPtr GetByClient(int iUniqueChannelId, int iClientID) const;
402 * @brief Get a channel given it's unique ID.
403 * @param iUniqueID The unique ID.
404 * @return The channel or NULL if it wasn't found.
406 CPVRChannelPtr GetByUniqueID(int iUniqueID) const;
408 void SetSelectedGroup(bool bSetTo);
409 bool IsSelectedGroup(void) const;
413 * @brief Set a new channel icon path if the path exists
414 * @param channel The channel to change
415 * @param strIconPath The new path
416 * @return True if the path exists, false otherwise
418 bool SetChannelIconPath(CPVRChannelPtr channel, const std::string& strIconPath);
421 * @brief Load the channels stored in the database.
422 * @param bCompress If true, compress the database after storing the channels.
423 * @return The amount of channels that were added.
425 virtual int LoadFromDb(bool bCompress = false);
428 * @brief Update the current channel list with the given list.
430 * Update the current channel list with the given list.
431 * Only the new channels will be present in the passed list after this call.
433 * @param channels The channels to use to update this list.
434 * @return True if everything went well, false otherwise.
436 virtual bool UpdateGroupEntries(const CPVRChannelGroup &channels);
438 virtual bool AddAndUpdateChannels(const CPVRChannelGroup &channels, bool bUseBackendChannelNumbers);
440 bool RemoveDeletedChannels(const CPVRChannelGroup &channels);
443 * @brief Create an EPG table for each channel.
444 * @brief bForce Create the tables, even if they already have been created before.
445 * @return True if all tables were created successfully, false otherwise.
447 virtual bool CreateChannelEpgs(bool bForce = false);
450 * @brief Remove invalid channels from this container.
452 void RemoveInvalidChannels(void);
455 * @brief Load the channels from the database.
456 * @return True when loaded successfully, false otherwise.
458 virtual bool Load(void);
461 * @brief Clear this channel list.
463 virtual void Unload(void);
466 * @brief Load the channels from the clients.
467 * @return True when loaded successfully, false otherwise.
469 virtual bool LoadFromClients(void);
472 * @brief Remove invalid channels and updates the channel numbers.
473 * @return True if something changed, false otherwise.
475 virtual bool Renumber(void);
478 * @brief Sort the current channel list by client channel number.
480 void SortByClientChannelNumber(void);
483 * @brief Sort the current channel list by channel number.
485 void SortByChannelNumber(void);
488 * @brief Get the previous or next channel in this group.
489 * @param channel The current channel.
490 * @param bChannelUp True to get the next channel, false to get the previous one.
491 * @return The requested channel or NULL if there is none.
493 CFileItemPtr GetByChannelUpDown(const CFileItem &channel, bool bChannelUp) const;
495 void ResetChannelNumbers(void);
498 * @brief Get a channel given it's channel ID.
499 * @param iChannelID The channel ID.
500 * @return The channel or NULL if it wasn't found.
502 CPVRChannelPtr GetByChannelID(int iChannelID) const;
504 bool m_bRadio; /*!< true if this container holds radio channels, false if it holds TV channels */
505 int m_iGroupType; /*!< The type of this group */
506 int m_iGroupId; /*!< The ID of this group in the database */
507 CStdString m_strGroupName; /*!< The name of this group */
508 bool m_bLoaded; /*!< True if this container is loaded, false otherwise */
509 bool m_bChanged; /*!< true if anything changed in this group that hasn't been persisted, false otherwise */
510 bool m_bUsingBackendChannelOrder; /*!< true to use the channel order from backends, false otherwise */
511 bool m_bUsingBackendChannelNumbers; /*!< true to use the channel numbers from 1 backend, false otherwise */
512 bool m_bSelectedGroup; /*!< true when this is the selected group, false otherwise */
513 bool m_bPreventSortAndRenumber; /*!< true when sorting and renumbering should not be done after adding/updating channels to the group */
514 std::vector<PVRChannelGroupMember> m_members;
515 CCriticalSection m_critSection;
518 CDateTime GetEPGDate(EpgDateType epgDateType) const;
522 class CPVRPersistGroupJob : public CJob
525 CPVRPersistGroupJob(CPVRChannelGroupPtr group) { m_group = group; }
526 virtual ~CPVRPersistGroupJob() {}
527 const char *GetType() const { return "pvr-channelgroup-persist"; }
529 virtual bool DoWork();
532 CPVRChannelGroupPtr m_group;