Bug Summary

File:menu_searchtemplate.c
Location:line 98, column 1
Description:Potential memory leak

Annotated Source Code

1/* -*- c++ -*-
2Copyright (C) 2004-2013 Christian Wieninger
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18
19The author can be reached at cwieninger@gmx.de
20
21The project's page is at http://winni.vdr-developer.org/epgsearch
22*/
23
24#include <vector>
25#include <string>
26#include <iomanip>
27#include <sstream>
28
29#include "menu_searchtemplate.h"
30#include "epgsearchtools.h"
31#include "epgsearchcfg.h"
32#include "recdone.h"
33#include "menu_templateedit.h"
34#include "menu_searchactions.h"
35
36using namespace std;
37
38// --- cMenuSearchTemplateItem ----------------------------------------------------------
39class cMenuSearchTemplateItem : public cOsdItem {
40 private:
41public:
42 cSearchExt* searchExt;
43 cMenuSearchTemplateItem(cSearchExt* SearchExt);
44 int Compare(const cListObject &ListObject) const;
45 void Set(void);
46 };
47
48cMenuSearchTemplateItem::cMenuSearchTemplateItem(cSearchExt* SearchExt)
49{
50 searchExt = SearchExt;
51 Set();
1
Calling 'cMenuSearchTemplateItem::Set'
52}
53
54void cMenuSearchTemplateItem::Set(void)
55{
56 ostringstream line;
57
58 if (searchExt->ID == EPGSearchConfig.DefSearchTemplateID)
2
Taking false branch
59 line << "*";
60 else if (searchExt->useAsSearchTimer)
3
Taking false branch
61 {
62 if (searchExt->IsActiveAt(time(NULL__null)))
63 line << ">";
64 else
65 line << "!";
66 }
67
68 line << "\t";
69 if (searchExt->search && strlen(searchExt->search) > 0)
4
Taking false branch
70 line << setiosflags(ios::left) << string(searchExt->search);
71 else
72 line << setiosflags(ios::left) << "*";
73
74 line << "\t";
75 if (searchExt->useChannel == 1)
5
Taking false branch
76 {
77 if (searchExt->channelMin != searchExt->channelMax)
78 line << setiosflags(ios::left) << searchExt->channelMin->Number() << " - " << searchExt->channelMax->Number();
79 else
80 line << setiosflags(ios::left) << setw(11) << (searchExt->useChannel?CHANNELNAME(searchExt->channelMin)(searchExt->channelMin ? searchExt->channelMin->ShortName
(true) : "")
:"");
81 }
82 else if (searchExt->useChannel == 2)
6
Taking false branch
83 line << setiosflags(ios::left) << setw(11) << searchExt->channelGroup;
84
85 line << "\t";
86 if (searchExt->useTime)
7
Taking false branch
87 {
88 ostringstream timeline;
89 timeline << setfill('0') << setw(2) << searchExt->startTime / 100 << ":" << setw(2) << searchExt->startTime % 100;
90 timeline << "\t";
91 timeline << setfill('0') << setw(2) << searchExt->stopTime / 100 << ":" << setw(2) << searchExt->stopTime % 100;
92 line << timeline.str();
93 }
94 else
95 line << "--:--\t--:--";
96
97 SetText(strdup(line.str().c_str()), false);
8
Memory is allocated
98}
9
Potential memory leak
99
100int cMenuSearchTemplateItem::Compare(const cListObject &ListObject) const
101{
102 cMenuSearchTemplateItem *p = (cMenuSearchTemplateItem *)&ListObject;
103 return strcasecmp(searchExt->search, p->searchExt->search);
104}
105
106// --- cMenuEPGSearchTemplate ----------------------------------------------------------
107cMenuEPGSearchTemplate::cMenuEPGSearchTemplate(cSearchExt* Search, cBlacklist* Blacklist, bool New)
108:cOsdMenu(tr("Search templates")I18nTranslate("Search templates", "vdr-" "epgsearch"), 2, 20, 11, 6, 5)
109{
110#if VDRVERSNUM20005 >= 10728
111 SetMenuCategory(mcPlugin);
112#endif
113 search = Search;
114 blacklist = Blacklist;
115 newSearch = New;
116 cMutexLock SearchTemplatesLock(&SearchTemplates);
117 cSearchExt *SearchExt = SearchTemplates.First();
118 while (SearchExt) {
119 Add(new cMenuSearchTemplateItem(SearchExt));
120 SearchExt = SearchTemplates.Next(SearchExt);
121 }
122 SetHelp(trVDR("Button$Edit")I18nTranslate("Button$Edit"), trVDR("Button$New")I18nTranslate("Button$New"), trVDR("Button$Delete")I18nTranslate("Button$Delete"), tr("Button$Default")I18nTranslate("Button$Default", "vdr-" "epgsearch"));
123 Sort();
124 Display();
125
126}
127
128cSearchExt *cMenuEPGSearchTemplate::CurrentSearchTemplate(void)
129{
130 cMenuSearchTemplateItem *item = (cMenuSearchTemplateItem *)Get(Current());
131 return item ? item->searchExt : NULL__null;
132}
133
134eOSState cMenuEPGSearchTemplate::New(void)
135{
136 if (HasSubMenu())
137 return osContinue;
138 return AddSubMenu(new cMenuEditTemplate(new cSearchExt, true));
139}
140
141eOSState cMenuEPGSearchTemplate::Delete(void)
142{
143 cSearchExt *curSearchExt = CurrentSearchTemplate();
144 if (curSearchExt) {
145 if (Interface->Confirm(tr("Edit$Delete template?")I18nTranslate("Edit$Delete template?", "vdr-" "epgsearch"))) {
146 cMutexLock SearchTemplatesLock(&SearchTemplates);
147 SearchTemplates.Del(curSearchExt);
148 SearchTemplates.Save();
149 cOsdMenu::Del(Current());
150 Display();
151 }
152 }
153 return osContinue;
154}
155
156eOSState cMenuEPGSearchTemplate::DefaultTemplate(void)
157{
158 if (HasSubMenu())
159 return osContinue;
160 cSearchExt *curSearchExt = CurrentSearchTemplate();
161
162 int current = Current();
163 cMenuSearchTemplateItem *oldDefaultTemplateItem = NULL__null;
164 for(int i=0; i<Count(); i++)
165 {
166 cMenuSearchTemplateItem *item = (cMenuSearchTemplateItem *)Get(i);
167 if (item && item->searchExt && item->searchExt->ID == EPGSearchConfig.DefSearchTemplateID)
168 oldDefaultTemplateItem = item;
169 }
170
171 if (curSearchExt)
172 {
173 if (EPGSearchConfig.DefSearchTemplateID == curSearchExt->ID)
174 EPGSearchConfig.DefSearchTemplateID = -1;
175 else
176 EPGSearchConfig.DefSearchTemplateID = curSearchExt->ID;
177 cPluginManager::GetPlugin("epgsearch")->SetupStore("DefSearchTemplateID", EPGSearchConfig.DefSearchTemplateID);
178
179 SetCurrent(oldDefaultTemplateItem);
180 RefreshCurrent();
181 DisplayCurrent(true);
182
183 SetCurrent(Get(current));
184 RefreshCurrent();
185 DisplayCurrent(true);
186
187 Display();
188 }
189 return osContinue;
190}
191
192eOSState cMenuEPGSearchTemplate::ProcessKey(eKeys Key)
193{
194 int SearchNumber = HasSubMenu() ? Count() : -1;
195 eOSState state = cOsdMenu::ProcessKey(Key);
196 if (state == osUnknown) {
197 if (HasSubMenu())
198 return osContinue;
199 switch (Key) {
200 case kOk:
201 {
202 if (search)
203 {
204 if (!newSearch && !Interface->Confirm(tr("Overwrite existing entries?")I18nTranslate("Overwrite existing entries?", "vdr-" "epgsearch"
)
))
205 return osBack;
206 // duplicate template
207 cSearchExt* t =CurrentSearchTemplate();
208 if (!t) return osContinue;
209 // copy all except the name and id
210 search->CopyFromTemplate(t);
211 }
212 if (blacklist)
213 {
214 if (!newSearch && !Interface->Confirm(tr("Overwrite existing entries?")I18nTranslate("Overwrite existing entries?", "vdr-" "epgsearch"
)
))
215 return osBack;
216 // duplicate template
217 cSearchExt* t =CurrentSearchTemplate();
218 if (!t) return osContinue;
219 // copy all except the name and id
220 blacklist->CopyFromTemplate(t);
221 }
222 return osBack;
223 }
224 case kRed:
225 if (CurrentSearchTemplate())
226 state = AddSubMenu(new cMenuEditTemplate(CurrentSearchTemplate()));
227 else
228 state = osContinue;
229 break;
230 case kGreen: state = New(); break;
231 case kYellow: state = Delete(); break;
232 case kBlue: state = DefaultTemplate(); break;
233 default: break;
234 }
235 }
236 if (SearchNumber >= 0 && !HasSubMenu())
237 {
238 cSearchExt* search = SearchTemplates.Get(SearchNumber);
239 if (search) // a newly created template was confirmed with Ok
240 Add(new cMenuSearchTemplateItem(search));
241 else
242 search = CurrentSearchTemplate();
243 // always update all entries, since channel group names may have changed and affect other searches
244 Sort();
245 for(int i=0; i<Count(); i++)
246 {
247 cMenuSearchTemplateItem *item = (cMenuSearchTemplateItem *)Get(i);
248 if (item)
249 {
250 item->Set();
251 if (item->searchExt == search)
252 SetCurrent(item);
253 }
254 }
255 Display();
256 }
257
258 return state;
259}