Merge pull request #4314 from MartijnKaijser/beta1
[vuplus_xbmc] / xbmc / pvr / channels / PVRChannelGroup.h
1 #pragma once
2
3 /*
4  *      Copyright (C) 2012-2013 Team XBMC
5  *      http://xbmc.org
6  *
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)
10  *  any later version.
11  *
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.
16  *
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/>.
20  *
21  */
22
23 #include "FileItem.h"
24 #include "PVRChannel.h"
25 #include "settings/lib/ISettingCallback.h"
26 #include "utils/JobManager.h"
27
28 #include <boost/shared_ptr.hpp>
29
30 namespace EPG
31 {
32   struct EpgSearchFilter;
33 }
34
35 namespace PVR
36 {
37 #define XBMC_INTERNAL_GROUP_RADIO 1
38 #define XBMC_INTERNAL_GROUP_TV    2
39
40 #define PVR_GROUP_TYPE_DEFAULT      0
41 #define PVR_GROUP_TYPE_INTERNAL     1
42 #define PVR_GROUP_TYPE_USER_DEFINED 2
43
44   class CPVRChannelGroups;
45   class CPVRChannelGroupInternal;
46   class CPVRChannelGroupsContainer;
47
48   typedef struct
49   {
50     CPVRChannelPtr channel;
51     unsigned int   iChannelNumber;
52   } PVRChannelGroupMember;
53   
54   enum EpgDateType
55   {
56     EPG_FIRST_DATE = 0,
57     EPG_LAST_DATE = 1
58   };
59   
60   class CPVRChannelGroup;
61   typedef boost::shared_ptr<PVR::CPVRChannelGroup> CPVRChannelGroupPtr;
62
63   /** A group of channels */
64   class CPVRChannelGroup : public Observable,
65                            public IJobCallback,
66                            public ISettingCallback
67
68   {
69     friend class CPVRChannelGroups;
70     friend class CPVRChannelGroupInternal;
71     friend class CPVRChannelGroupsContainer;
72     friend class CPVRDatabase;
73
74   public:
75     CPVRChannelGroup(void);
76
77     /*!
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.
82      */
83     CPVRChannelGroup(bool bRadio, unsigned int iGroupId, const CStdString &strGroupName);
84
85     /*!
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.
88      */
89     CPVRChannelGroup(const PVR_CHANNEL_GROUP &group);
90
91     /*!
92      * @brief Copy constructor
93      * @param group Source group
94      */
95     CPVRChannelGroup(const CPVRChannelGroup &group);
96
97     virtual ~CPVRChannelGroup(void);
98
99     bool operator ==(const CPVRChannelGroup &right) const;
100     bool operator !=(const CPVRChannelGroup &right) const;
101
102     /*!
103      * @return The amount of group members
104      */
105     int Size(void) const;
106
107     /*!
108      * @brief Refresh the channel list from the clients.
109      */
110     virtual bool Update(void);
111
112     /*!
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.
116      */
117     bool SetChannelNumber(const CPVRChannel &channel, unsigned int iChannelNumber);
118
119     /*!
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.
125      */
126     virtual bool MoveChannel(unsigned int iOldChannelNumber, unsigned int iNewChannelNumber, bool bSaveInDb = true);
127
128     /*!
129      * @brief Search missing channel icons for all known channels.
130      * @param bUpdateDb If true, update the changed values in the database.
131      */
132     void SearchAndSetChannelIcons(bool bUpdateDb = false);
133
134     /*!
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.
138      */
139     virtual bool RemoveFromGroup(const CPVRChannel &channel);
140
141     /*!
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.
146      */
147     virtual bool AddToGroup(CPVRChannel &channel, int iChannelNumber = 0);
148
149     /*!
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.
154      */
155     bool SetGroupName(const CStdString &strGroupName, bool bSaveInDb = false);
156
157     /*!
158      * @brief Persist changed or new data.
159      * @return True if the channel was persisted, false otherwise.
160      */
161     bool Persist(void);
162
163     /*!
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.
167      */
168     virtual bool IsGroupMember(const CPVRChannel &channel) const;
169
170     /*!
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.
174      */
175     virtual bool IsGroupMember(int iChannelId) const;
176
177     /*!
178      * @brief Check if this group is the internal group containing all channels.
179      * @return True if it's the internal group, false otherwise.
180      */
181     virtual bool IsInternalGroup(void) const { return false; }
182
183     /*!
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.
186      */
187     bool IsRadio(void) const { return m_bRadio; }
188
189     /*!
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.
192      */
193     bool PreventSortAndRenumber(void) const;
194
195     /*!
196      * @brief The database ID of this group.
197      * @return The database ID of this group.
198      */
199     int GroupID(void) const;
200
201     /*!
202      * @brief Set the database ID of this group.
203      * @param iGroupId The new database ID.
204      */
205     void SetGroupID(int iGroupId);
206
207     /*!
208      * @brief Set the type of this group.
209      * @param the new type for this group.
210      */
211     void SetGroupType(int iGroupType);
212
213     /*!
214      * @brief Return the type of this group.
215      */
216     int GroupType(void) const;
217
218     /*!
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.
221      */
222     void SetPreventSortAndRenumber(bool bPreventSortAndRenumber = true);
223
224     /*!
225      * @brief The name of this group.
226      * @return The name of this group.
227      */
228     CStdString GroupName(void) const;
229
230     /*! @name Sort methods
231      */
232     //@{
233
234     /*!
235      * @brief Sort the group and fix up channel numbers.
236      * @return True when numbering changed, false otherwise
237      */
238     bool SortAndRenumber(void);
239
240     //@}
241
242     virtual void OnSettingChanged(const CSetting *setting);
243
244     /*!
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.
248      */
249     CPVRChannelPtr GetByChannelEpgID(int iEpgID) const;
250
251     /*!
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.
255      */
256     CFileItemPtr GetLastPlayedChannel(unsigned int iCurrentChannel = -1) const;
257
258     /*!
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.
262      */
263     CFileItemPtr GetByChannelNumber(unsigned int iChannelNumber) const;
264
265     /*!
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.
269      */
270     unsigned int GetChannelNumber(const CPVRChannel &channel) const;
271
272     /*!
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.
276      */
277     CFileItemPtr GetByChannelUp(const CFileItem &channel) const { return GetByChannelUpDown(channel, true); }
278
279     /*!
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.
283      */
284     CFileItemPtr GetByChannelDown(const CFileItem &channel) const { return GetByChannelUpDown(channel, false); }
285
286     /*!
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.
290      */
291     CFileItemPtr GetByIndex(unsigned int index) const;
292
293     /*!
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.
297      */
298     int GetIndex(const CPVRChannel &channel) const;
299
300     /*!
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.
305      */
306     virtual int GetMembers(CFileItemList &results, bool bGroupMembers = true) const;
307
308     /*!
309      * @return The next channel group.
310      */
311     CPVRChannelGroupPtr GetNextGroup(void) const;
312
313     /*!
314      * @return The previous channel group.
315      */
316     CPVRChannelGroupPtr GetPreviousGroup(void) const;
317
318     /*!
319      * @brief The amount of hidden channels in this container.
320      * @return The amount of hidden channels in this container.
321      */
322     virtual int GetNumHiddenChannels(void) const { return 0; }
323
324     /*!
325      * @return True if there is at least one channel in this group with changes that haven't been persisted, false otherwise.
326      */
327     bool HasChangedChannels(void) const;
328
329     /*!
330      * @return True if there is at least one new channel in this group that hasn't been persisted, false otherwise.
331      */
332     bool HasNewChannels(void) const;
333
334     /*!
335      * @return True if anything changed in this group that hasn't been persisted, false otherwise.
336      */
337     bool HasChanges(void) const;
338
339     /*!
340      * @brief Reset the channel number cache if this is the selected group in the UI.
341      */
342     void ResetChannelNumberCache(void);
343
344     void OnJobComplete(unsigned int jobID, bool success, CJob* job) {}
345
346     /*!
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.
351      */
352     int GetEPGSearch(CFileItemList &results, const EPG::EpgSearchFilter &filter);
353
354     /*!
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.
358      */
359     int GetEPGAll(CFileItemList &results);
360
361     /*!
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.
365      */
366     int GetEPGNow(CFileItemList &results);
367
368     /*!
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.
372      */
373     int GetEPGNext(CFileItemList &results);
374     
375     /*!
376      * @brief Get the start time of the first entry.
377      * @return The start time.
378      */
379     CDateTime GetFirstEPGDate(void) const;
380     
381     /*!
382      * @brief Get the end time of the last entry.
383      * @return The end time.
384      */
385     CDateTime GetLastEPGDate(void) const;
386
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);
388
389     bool ToggleChannelLocked(const CFileItem &channel);
390
391     virtual bool AddNewChannel(const CPVRChannel &channel, unsigned int iChannelNumber = 0) { return false; }
392
393     /*!
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.
398      */
399     CPVRChannelPtr GetByClient(int iUniqueChannelId, int iClientID) const;
400
401     /*!
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.
405      */
406     CPVRChannelPtr GetByUniqueID(int iUniqueID) const;
407
408     void SetSelectedGroup(bool bSetTo);
409     bool IsSelectedGroup(void) const;
410
411   protected:
412     /*!
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
417      */
418     bool SetChannelIconPath(CPVRChannelPtr channel, const std::string& strIconPath);
419
420     /*!
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.
424      */
425     virtual int LoadFromDb(bool bCompress = false);
426
427     /*!
428      * @brief Update the current channel list with the given list.
429      *
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.
432      *
433      * @param channels The channels to use to update this list.
434      * @return True if everything went well, false otherwise.
435      */
436     virtual bool UpdateGroupEntries(const CPVRChannelGroup &channels);
437
438     virtual bool AddAndUpdateChannels(const CPVRChannelGroup &channels, bool bUseBackendChannelNumbers);
439
440     bool RemoveDeletedChannels(const CPVRChannelGroup &channels);
441
442     /*!
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.
446      */
447     virtual bool CreateChannelEpgs(bool bForce = false);
448
449     /*!
450      * @brief Remove invalid channels from this container.
451      */
452     void RemoveInvalidChannels(void);
453
454     /*!
455      * @brief Load the channels from the database.
456      * @return True when loaded successfully, false otherwise.
457      */
458     virtual bool Load(void);
459
460     /*!
461      * @brief Clear this channel list.
462      */
463     virtual void Unload(void);
464
465     /*!
466      * @brief Load the channels from the clients.
467      * @return True when loaded successfully, false otherwise.
468      */
469     virtual bool LoadFromClients(void);
470
471     /*!
472      * @brief Remove invalid channels and updates the channel numbers.
473      * @return True if something changed, false otherwise.
474      */
475     virtual bool Renumber(void);
476
477     /*!
478      * @brief Sort the current channel list by client channel number.
479      */
480     void SortByClientChannelNumber(void);
481
482     /*!
483      * @brief Sort the current channel list by channel number.
484      */
485     void SortByChannelNumber(void);
486
487     /*!
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.
492      */
493     CFileItemPtr GetByChannelUpDown(const CFileItem &channel, bool bChannelUp) const;
494
495     void ResetChannelNumbers(void);
496
497     /*!
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.
501      */
502     CPVRChannelPtr GetByChannelID(int iChannelID) const;
503
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;
516     
517   private:
518     CDateTime GetEPGDate(EpgDateType epgDateType) const;
519     
520   };
521
522   class CPVRPersistGroupJob : public CJob
523   {
524   public:
525     CPVRPersistGroupJob(CPVRChannelGroupPtr group) { m_group = group; }
526     virtual ~CPVRPersistGroupJob() {}
527     const char *GetType() const { return "pvr-channelgroup-persist"; }
528
529     virtual bool DoWork();
530
531   private:
532     CPVRChannelGroupPtr m_group;
533   };
534 }