Merge pull request #4196 from arnova/sub_fallback
[vuplus_xbmc] / xbmc / guilib / GUIRSSControl.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program 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 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program 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.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "GUIRSSControl.h"
22 #include "GUIWindowManager.h"
23 #include "settings/Settings.h"
24 #include "threads/CriticalSection.h"
25 #include "threads/SingleLock.h"
26 #include "utils/RssManager.h"
27 #include "utils/RssReader.h"
28 #include "utils/StringUtils.h"
29
30 using namespace std;
31
32 CGUIRSSControl::CGUIRSSControl(int parentID, int controlID, float posX, float posY, float width, float height, const CLabelInfo& labelInfo, const CGUIInfoColor &channelColor, const CGUIInfoColor &headlineColor, CStdString& strRSSTags)
33 : CGUIControl(parentID, controlID, posX, posY, width, height),
34   m_label(labelInfo),
35   m_channelColor(channelColor),
36   m_headlineColor(headlineColor),
37   m_scrollInfo(0,0,labelInfo.scrollSpeed,""),
38   m_dirty(true)
39 {
40   m_strRSSTags = strRSSTags;
41
42   m_pReader = NULL;
43   m_rtl = false;
44   m_stopped = false;
45   m_urlset = 1;
46   ControlType = GUICONTROL_RSS;
47 }
48
49 CGUIRSSControl::CGUIRSSControl(const CGUIRSSControl &from)
50   : CGUIControl(from),
51   m_feed(),
52   m_label(from.m_label),
53   m_channelColor(from.m_channelColor),
54   m_headlineColor(from.m_headlineColor),
55   m_vecUrls(),
56   m_vecIntervals(),
57   m_scrollInfo(from.m_scrollInfo),
58   m_dirty(true)
59 {
60   m_strRSSTags = from.m_strRSSTags;
61   m_pReader = NULL;
62   m_rtl = from.m_rtl;
63   m_stopped = from.m_stopped;
64   m_urlset = 1;
65   ControlType = GUICONTROL_RSS;
66 }
67
68 CGUIRSSControl::~CGUIRSSControl(void)
69 {
70   CSingleLock lock(m_criticalSection);
71   if (m_pReader)
72     m_pReader->SetObserver(NULL);
73   m_pReader = NULL;
74 }
75
76 void CGUIRSSControl::OnFocus()
77 {
78   m_stopped = true;
79 }
80
81 void CGUIRSSControl::OnUnFocus()
82 {
83   m_stopped = false;
84 }
85
86 void CGUIRSSControl::SetUrlSet(const int urlset)
87 {
88   m_urlset = urlset;
89 }
90
91 bool CGUIRSSControl::UpdateColors()
92 {
93   bool changed = CGUIControl::UpdateColors();
94   changed |= m_label.UpdateColors();
95   changed |= m_headlineColor.Update();
96   changed |= m_channelColor.Update();
97   return changed;
98 }
99
100 void CGUIRSSControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
101 {
102   bool dirty = false;
103   if (CSettings::Get().GetBool("lookandfeel.enablerssfeeds") && CRssManager::Get().IsActive())
104   {
105     CSingleLock lock(m_criticalSection);
106     // Create RSS background/worker thread if needed
107     if (m_pReader == NULL)
108     {
109
110       RssUrls::const_iterator iter = CRssManager::Get().GetUrls().find(m_urlset);
111       if (iter != CRssManager::Get().GetUrls().end())
112       {
113         m_rtl = iter->second.rtl;
114         m_vecUrls = iter->second.url;
115         m_vecIntervals = iter->second.interval;
116         m_scrollInfo.SetSpeed(m_label.scrollSpeed * (m_rtl ? -1 : 1));
117       }
118
119       dirty = true;
120
121       if (CRssManager::Get().GetReader(GetID(), GetParentID(), this, m_pReader))
122         m_scrollInfo.characterPos = m_pReader->m_SavedScrollPos;
123       else
124       {
125         if (m_strRSSTags != "")
126         {
127           CStdStringArray vecSplitTags;
128
129           StringUtils::SplitString(m_strRSSTags, ",", vecSplitTags);
130
131           for (unsigned int i = 0;i < vecSplitTags.size();i++)
132             m_pReader->AddTag(vecSplitTags[i]);
133         }
134         // use half the width of the control as spacing between feeds, and double this between feed sets
135         float spaceWidth = (m_label.font) ? m_label.font->GetCharWidth(L' ') : 15;
136         m_pReader->Create(this, m_vecUrls, m_vecIntervals, (int)(0.5f*GetWidth() / spaceWidth) + 1, m_rtl);
137       }
138     }
139
140     if(m_dirty)
141       dirty = true;
142     m_dirty = false;
143
144     if (m_label.font)
145     {
146       if ( m_stopped )
147         m_scrollInfo.SetSpeed(0);
148       else
149         m_scrollInfo.SetSpeed(m_label.scrollSpeed * (m_rtl ? -1 : 1));
150
151       if(m_label.font->UpdateScrollInfo(m_feed, m_scrollInfo))
152         dirty = true;
153     }
154   }
155
156   if(dirty)
157     MarkDirtyRegion();
158
159   CGUIControl::Process(currentTime, dirtyregions);
160 }
161
162 void CGUIRSSControl::Render()
163 {
164   // only render the control if they are enabled
165   if (CSettings::Get().GetBool("lookandfeel.enablerssfeeds") && CRssManager::Get().IsActive())
166   {
167
168     if (m_label.font)
169     {
170       vecColors colors;
171       colors.push_back(m_label.textColor);
172       colors.push_back(m_headlineColor);
173       colors.push_back(m_channelColor);
174       m_label.font->DrawScrollingText(m_posX, m_posY, colors, m_label.shadowColor, m_feed, 0, m_width, m_scrollInfo);
175     }
176
177     if (m_pReader)
178     {
179       m_pReader->CheckForUpdates();
180       m_pReader->m_SavedScrollPos = m_scrollInfo.characterPos;
181     }
182   }
183   CGUIControl::Render();
184 }
185
186 CRect CGUIRSSControl::CalcRenderRegion() const
187 {
188   if (m_label.font)
189     return CRect(m_posX, m_posY, m_posX + m_width, m_posY + m_label.font->GetTextHeight(1));
190   return CGUIControl::CalcRenderRegion();
191 }
192
193 void CGUIRSSControl::OnFeedUpdate(const vecText &feed)
194 {
195   CSingleLock lock(m_criticalSection);
196   m_feed = feed;
197   m_dirty = true;
198 }
199
200 void CGUIRSSControl::OnFeedRelease()
201 {
202   m_pReader = NULL;
203 }
204
205