Support fast channel change.
[vuplus_dvbapp] / lib / service / listboxservice.cpp
1 #include <lib/service/listboxservice.h>
2 #include <lib/service/service.h>
3 #include <lib/gdi/font.h>
4 #include <lib/dvb/epgcache.h>
5 #include <lib/dvb/pmt.h>
6 #include <lib/python/connections.h>
7
8 void eListboxServiceContent::addService(const eServiceReference &service, bool beforeCurrent)
9 {
10         if (beforeCurrent && m_size)
11                 m_list.insert(m_cursor, service);
12         else
13                 m_list.push_back(service);
14         if (m_size++)
15         {
16                 ++m_cursor_number;
17                 if (m_listbox)
18                         m_listbox->entryAdded(m_cursor_number-1);
19         }
20         else
21         {
22                 m_cursor = m_list.begin();
23                 m_cursor_number=0;
24                 m_listbox->entryAdded(0);
25         }
26 }
27
28 void eListboxServiceContent::removeCurrent()
29 {
30         if (m_size && m_listbox)
31         {
32                 if (m_cursor_number == --m_size)
33                 {
34                         m_list.erase(m_cursor--);
35                         if (m_size)
36                         {
37                                 --m_cursor_number;
38                                 m_listbox->entryRemoved(m_cursor_number+1);
39                         }
40                         else
41                                 m_listbox->entryRemoved(m_cursor_number);
42                 }
43                 else
44                 {
45                         m_list.erase(m_cursor++);
46                         m_listbox->entryRemoved(m_cursor_number);
47                 }
48         }
49 }
50
51 void eListboxServiceContent::FillFinished()
52 {
53         m_size = m_list.size();
54         cursorHome();
55
56         if (m_listbox)
57                 m_listbox->entryReset();
58 }
59
60 void eListboxServiceContent::setRoot(const eServiceReference &root, bool justSet)
61 {
62         m_list.clear();
63         m_root = root;
64
65         if (justSet)
66         {
67                 m_lst=0;
68                 return;
69         }
70         ASSERT(m_service_center);
71         
72         if (m_service_center->list(m_root, m_lst))
73                 eDebug("no list available!");
74         else if (m_lst->getContent(m_list))
75                 eDebug("getContent failed");
76
77         FillFinished();
78 }
79
80 void eListboxServiceContent::setCurrent(const eServiceReference &ref)
81 {
82         int index=0;
83         for (list::iterator i(m_list.begin()); i != m_list.end(); ++i, ++index)
84                 if ( *i == ref )
85                 {
86                         m_cursor = i;
87                         m_cursor_number = index;
88                         break;
89                 }
90         if (m_listbox)
91                 m_listbox->moveSelectionTo(index);
92 }
93
94 void eListboxServiceContent::getCurrent(eServiceReference &ref)
95 {
96         if (cursorValid())
97                 ref = *m_cursor;
98         else
99                 ref = eServiceReference();
100 }
101
102 void eListboxServiceContent::getPrev(eServiceReference &ref)
103 {
104         if (cursorValid())
105         {
106                 list::iterator cursor(m_cursor);
107                 if (cursor == m_list.begin())
108                 {
109                         cursor = m_list.end();
110                 }
111                 ref = *(--cursor);
112         }
113         else
114                 ref = eServiceReference();
115 }
116
117 void eListboxServiceContent::getNext(eServiceReference &ref)
118 {
119         if (cursorValid())
120         {
121                 list::iterator cursor(m_cursor);
122                 cursor++;
123                 if (cursor == m_list.end())
124                 {
125                         cursor = m_list.begin();
126                 }
127                 ref = *(cursor);
128         }
129         else
130                 ref = eServiceReference();
131 }
132
133 PyObject *eListboxServiceContent::getList()
134 {
135         ePyObject result = PyList_New(m_list.size());
136         int pos=0;
137         for (list::iterator it(m_list.begin()); it != m_list.end(); ++it)
138         {
139                 PyList_SET_ITEM(result, pos++, NEW_eServiceReference(*it));
140         }
141         return result;
142 }
143
144 int eListboxServiceContent::getNextBeginningWithChar(char c)
145 {
146 //      printf("Char: %c\n", c);
147         int index=0;
148         for (list::iterator i(m_list.begin()); i != m_list.end(); ++i, ++index)
149         {
150                 std::string text;
151                 ePtr<iStaticServiceInformation> service_info;
152                 m_service_center->info(*i, service_info);
153                 service_info->getName(*i, text);
154 //              printf("%c\n", text.c_str()[0]);
155                 int idx=0;
156                 int len=text.length();
157                 while ( idx <= len )
158                 {
159                         char cc = text[idx++];
160                         if ( cc >= 33 && cc < 127)
161                         {
162                                 if (cc == c)
163                                         return index;
164                                 break;
165                         }
166                 }
167         }
168         return 0;
169 }
170
171 int eListboxServiceContent::getPrevMarkerPos()
172 {
173         if (!m_listbox)
174                 return 0;
175         list::iterator i(m_cursor);
176         int index = m_cursor_number;
177         while (index)
178         {
179                 --i;
180                 --index;
181                 if (i->flags & eServiceReference::isMarker)
182                         break;
183         }
184         return index;
185 }
186
187 int eListboxServiceContent::getNextMarkerPos()
188 {
189         if (!m_listbox)
190                 return 0;
191         list::iterator i(m_cursor);
192         int index = m_cursor_number;
193         while (index < (m_size-1))
194         {
195                 ++i;
196                 ++index;
197                 if (i->flags & eServiceReference::isMarker)
198                         break;
199         }
200         return index;
201 }
202
203 void eListboxServiceContent::initMarked()
204 {
205         m_marked.clear();
206 }
207
208 void eListboxServiceContent::addMarked(const eServiceReference &ref)
209 {
210         m_marked.insert(ref);
211         if (m_listbox)
212                 m_listbox->entryChanged(lookupService(ref));
213 }
214
215 void eListboxServiceContent::removeMarked(const eServiceReference &ref)
216 {
217         m_marked.erase(ref);
218         if (m_listbox)
219                 m_listbox->entryChanged(lookupService(ref));
220 }
221
222 int eListboxServiceContent::isMarked(const eServiceReference &ref)
223 {
224         return m_marked.find(ref) != m_marked.end();
225 }
226
227 void eListboxServiceContent::markedQueryStart()
228 {
229         m_marked_iterator = m_marked.begin();
230 }
231
232 int eListboxServiceContent::markedQueryNext(eServiceReference &ref)
233 {
234         if (m_marked_iterator == m_marked.end())
235                 return -1;
236         ref = *m_marked_iterator++;
237         return 0;
238 }
239
240 int eListboxServiceContent::lookupService(const eServiceReference &ref)
241 {
242                 /* shortcut for cursor */
243         if (ref == *m_cursor)
244                 return m_cursor_number;
245                 /* otherwise, search in the list.. */
246         int index = 0;
247         for (list::const_iterator i(m_list.begin()); i != m_list.end(); ++i, ++index);
248         
249                 /* this is ok even when the index was not found. */
250         return index;
251 }
252
253 void eListboxServiceContent::setVisualMode(int mode)
254 {
255         for (int i=0; i < celElements; ++i)
256         {
257                 m_element_position[i] = eRect();
258                 m_element_font[i] = 0;
259         }
260
261         m_visual_mode = mode;
262
263         if (m_visual_mode == visModeSimple)
264         {
265                 m_element_position[celServiceName] = eRect(ePoint(0, 0), m_itemsize);
266                 m_element_font[celServiceName] = new gFont("Regular", 23);
267         }
268 }
269
270 void eListboxServiceContent::setElementPosition(int element, eRect where)
271 {
272         if ((element >= 0) && (element < celElements))
273                 m_element_position[element] = where;
274 }
275
276 void eListboxServiceContent::setElementFont(int element, gFont *font)
277 {
278         if ((element >= 0) && (element < celElements))
279                 m_element_font[element] = font;
280 }
281
282 void eListboxServiceContent::setPixmap(int type, ePtr<gPixmap> &pic)
283 {
284         if ((type >=0) && (type < picElements))
285                 m_pixmaps[type] = pic;
286 }
287
288 void eListboxServiceContent::sort()
289 {
290         if (!m_lst)
291                 m_service_center->list(m_root, m_lst);
292         if (m_lst)
293         {
294                 m_list.sort(iListableServiceCompare(m_lst));
295                         /* FIXME: is this really required or can we somehow keep the current entry? */
296                 cursorHome();
297                 if (m_listbox)
298                         m_listbox->entryReset();
299         }
300 }
301
302 DEFINE_REF(eListboxServiceContent);
303
304 eListboxServiceContent::eListboxServiceContent()
305         :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_numberoffset(0), m_itemheight(25)
306 {
307         memset(m_color_set, 0, sizeof(m_color_set));
308         cursorHome();
309         eServiceCenter::getInstance(m_service_center);
310 }
311
312 void eListboxServiceContent::setColor(int color, gRGB &col)
313 {
314         if ((color >= 0) && (color < colorElements))
315         {
316                 m_color_set[color] = true;
317                 m_color[color] = col;
318         }
319 }
320
321 void eListboxServiceContent::cursorHome()
322 {
323         if (m_current_marked && m_saved_cursor == m_list.end())
324         {
325                 if (m_cursor_number >= m_size)
326                 {
327                         m_cursor_number = m_size-1;
328                         --m_cursor;
329                 }
330                 while (m_cursor_number)
331                 {
332                         std::iter_swap(m_cursor--, m_cursor);
333                         --m_cursor_number;
334                         if (m_listbox && m_cursor_number)
335                                 m_listbox->entryChanged(m_cursor_number);
336                 }
337         }
338         else
339         {
340                 m_cursor = m_list.begin();
341                 m_cursor_number = 0;
342         }
343 }
344
345 void eListboxServiceContent::cursorEnd()
346 {
347         if (m_current_marked && m_saved_cursor == m_list.end())
348         {
349                 while (m_cursor != m_list.end())
350                 {
351                         list::iterator prev = m_cursor++;
352                         ++m_cursor_number;
353                         if ( prev != m_list.end() && m_cursor != m_list.end() )
354                         {
355                                 std::iter_swap(m_cursor, prev);
356                                 if ( m_listbox )
357                                         m_listbox->entryChanged(m_cursor_number);
358                         }
359                 }
360         }
361         else
362         {
363                 m_cursor = m_list.end();
364                 m_cursor_number = m_size;
365         }
366 }
367
368 int eListboxServiceContent::setCurrentMarked(bool state)
369 {
370         bool prev = m_current_marked;
371         m_current_marked = state;
372
373         if (state != prev && m_listbox)
374         {
375                 m_listbox->entryChanged(m_cursor_number);
376                 if (!state)
377                 {
378                         if (!m_lst)
379                                 m_service_center->list(m_root, m_lst);
380                         if (m_lst)
381                         {
382                                 ePtr<iMutableServiceList> list;
383                                 if (m_lst->startEdit(list))
384                                         eDebug("no editable list");
385                                 else
386                                 {
387                                         eServiceReference ref;
388                                         getCurrent(ref);
389                                         if(!ref)
390                                                 eDebug("no valid service selected");
391                                         else
392                                         {
393                                                 int pos = cursorGet();
394                                                 eDebugNoNewLine("move %s to %d ", ref.toString().c_str(), pos);
395                                                 if (list->moveService(ref, cursorGet()))
396                                                         eDebug("failed");
397                                                 else
398                                                         eDebug("ok");
399                                         }
400                                 }
401                         }
402                         else
403                                 eDebug("no list available!");
404                 }
405         }
406
407         return 0;
408 }
409
410 int eListboxServiceContent::cursorMove(int count)
411 {
412         int prev = m_cursor_number, last = m_cursor_number + count;
413         if (count > 0)
414         {
415                 while(count && m_cursor != m_list.end())
416                 {
417                         list::iterator prev_it = m_cursor++;
418                         if ( m_current_marked && m_cursor != m_list.end() && m_saved_cursor == m_list.end() )
419                         {
420                                 std::iter_swap(prev_it, m_cursor);
421                                 if ( m_listbox && prev != m_cursor_number && last != m_cursor_number )
422                                         m_listbox->entryChanged(m_cursor_number);
423                         }
424                         ++m_cursor_number;
425                         --count;
426         }
427         } else if (count < 0)
428         {
429                 while (count && m_cursor != m_list.begin())
430                 {
431                         list::iterator prev_it = m_cursor--;
432                         if ( m_current_marked && m_cursor != m_list.end() && prev_it != m_list.end() && m_saved_cursor == m_list.end() )
433                         {
434                                 std::iter_swap(prev_it, m_cursor);
435                                 if ( m_listbox && prev != m_cursor_number && last != m_cursor_number )
436                                         m_listbox->entryChanged(m_cursor_number);
437                         }
438                         --m_cursor_number;
439                         ++count;
440                 }
441         }
442         return 0;
443 }
444
445 int eListboxServiceContent::cursorValid()
446 {
447         return m_cursor != m_list.end();
448 }
449
450 int eListboxServiceContent::cursorSet(int n)
451 {
452         cursorHome();
453         cursorMove(n);
454         return 0;
455 }
456
457 int eListboxServiceContent::cursorGet()
458 {
459         return m_cursor_number;
460 }
461
462 void eListboxServiceContent::cursorSave()
463 {
464         m_saved_cursor = m_cursor;
465         m_saved_cursor_number = m_cursor_number;
466 }
467
468 void eListboxServiceContent::cursorRestore()
469 {
470         m_cursor = m_saved_cursor;
471         m_cursor_number = m_saved_cursor_number;
472         m_saved_cursor = m_list.end();
473 }
474
475 int eListboxServiceContent::size()
476 {
477         return m_size;
478 }
479         
480 void eListboxServiceContent::setSize(const eSize &size)
481 {
482         m_itemsize = size;
483         if (m_visual_mode == visModeSimple)
484                 setVisualMode(m_visual_mode);
485 }
486
487 void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
488 {
489         painter.clip(eRect(offset, m_itemsize));
490
491         int marked = 0;
492
493         if (m_current_marked && selected)
494                 marked = 2;
495         else if (cursorValid() && isMarked(*m_cursor))
496         {
497                 if (selected)
498                         marked = 2;
499                 else
500                         marked = 1;
501         }
502         else
503                 style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
504
505         eListboxStyle *local_style = 0;
506
507                 /* get local listbox style, if present */
508         if (m_listbox)
509                 local_style = m_listbox->getLocalStyle();
510
511         if (marked == 1)  // marked
512         {
513                 style.setStyle(painter, eWindowStyle::styleListboxMarked);
514                 if (m_color_set[markedForeground])
515                         painter.setForegroundColor(m_color[markedForeground]);
516                 if (m_color_set[markedBackground])
517                         painter.setBackgroundColor(m_color[markedBackground]);
518         }
519         else if (marked == 2) // marked and selected
520         {
521                 style.setStyle(painter, eWindowStyle::styleListboxMarkedAndSelected);
522                 if (m_color_set[markedForegroundSelected])
523                         painter.setForegroundColor(m_color[markedForegroundSelected]);
524                 if (m_color_set[markedBackgroundSelected])
525                         painter.setBackgroundColor(m_color[markedBackgroundSelected]);
526         }
527         else if (local_style)
528         {
529                 if (selected)
530                 {
531                         /* if we have a local background color set, use that. */
532                         if (local_style->m_background_color_selected_set)
533                                 painter.setBackgroundColor(local_style->m_background_color_selected);
534                         /* same for foreground */
535                         if (local_style->m_foreground_color_selected_set)
536                                 painter.setForegroundColor(local_style->m_foreground_color_selected);
537                 }
538                 else
539                 {
540                         /* if we have a local background color set, use that. */
541                         if (local_style->m_background_color_set)
542                                 painter.setBackgroundColor(local_style->m_background_color);
543                         /* same for foreground */
544                         if (local_style->m_foreground_color_set)
545                                 painter.setForegroundColor(local_style->m_foreground_color);
546                 }
547         }
548
549         if (!local_style || !local_style->m_transparent_background)
550                 /* if we have no transparent background */
551         {
552                 /* blit background picture, if available (otherwise, clear only) */
553                 if (local_style && local_style->m_background)
554                         painter.blit(local_style->m_background, offset, eRect(), 0);
555                 else
556                         painter.clear();
557         } else
558         {
559                 if (local_style->m_background)
560                         painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHATEST);
561                 else if (selected && !local_style->m_selection)
562                         painter.clear();
563         }
564
565         if (cursorValid())
566         {
567                         /* get service information */
568                 ePtr<iStaticServiceInformation> service_info;
569                 m_service_center->info(*m_cursor, service_info);
570                 eServiceReference ref = *m_cursor;
571                 bool isMarker = ref.flags & eServiceReference::isMarker;
572                 bool isPlayable = !(ref.flags & eServiceReference::isDirectory || isMarker);
573                 bool paintProgress = false;
574                 ePtr<eServiceEvent> evt;
575
576                 bool serviceAvail = true;
577
578                 if (!marked && isPlayable && service_info && m_is_playable_ignore.valid() && !service_info->isPlayable(*m_cursor, m_is_playable_ignore))
579                 {
580                         if (m_color_set[serviceNotAvail])
581                                 painter.setForegroundColor(m_color[serviceNotAvail]);
582                         else
583                                 painter.setForegroundColor(gRGB(0xbbbbbb));
584                         serviceAvail = false;
585                 }
586
587                 if (selected && local_style && local_style->m_selection)
588                         painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHATEST);
589
590                 int xoffset=0;  // used as offset when painting the folder/marker symbol or the serviceevent progress
591
592                 for (int e = 0; e < celElements; ++e)
593                 {
594                         if (m_element_font[e])
595                         {
596                                 int flags=gPainter::RT_VALIGN_CENTER,
597                                         yoffs = 0,
598                                         xoffs = xoffset;
599                                 eRect &area = m_element_position[e];
600                                 std::string text = "<n/a>";
601                                 xoffset=0;
602
603                                 switch (e)
604                                 {
605                                 case celServiceNumber:
606                                 {
607                                         if (m_cursor->flags & eServiceReference::isMarker)
608                                                 continue;
609                                         char bla[10];
610                                 /* how we can do this better? :) */
611                                         int markers_before=0;
612                                         {
613                                                 list::iterator tmp=m_cursor;
614                                                 while(tmp != m_list.begin())
615                                                 {
616                                                         --tmp;
617                                                         if (tmp->flags & eServiceReference::isMarker)
618                                                                 ++markers_before;
619                                                 }
620                                         }
621                                         sprintf(bla, "%d", m_numberoffset + m_cursor_number + 1 - markers_before);
622                                         text = bla;
623                                         flags|=gPainter::RT_HALIGN_RIGHT;
624                                         break;
625                                 }
626                                 case celServiceName:
627                                 {
628                                         if (service_info)
629                                                 service_info->getName(*m_cursor, text);
630                                         break;
631                                 }
632                                 case celServiceInfo:
633                                 {
634                                         if ( isPlayable && !service_info->getEvent(*m_cursor, evt) )
635                                         {
636                                                 std::string name = evt->getEventName();
637                                                 if (!name.length())
638                                                         continue;
639                                                 text = '(' + evt->getEventName() + ')';
640                                                 if (serviceAvail)
641                                                 {
642                                                         if (!selected && m_color_set[serviceDescriptionColor])
643                                                                 painter.setForegroundColor(m_color[serviceDescriptionColor]);
644                                                         else if (selected && m_color_set[serviceDescriptionColorSelected])
645                                                                 painter.setForegroundColor(m_color[serviceDescriptionColorSelected]);
646                                                 }
647                                         }
648                                         else
649                                                 continue;
650                                         break;
651                                 }
652                                 }
653
654                                 eRect tmp = area;
655                                 tmp.setWidth(tmp.width()-xoffs);
656
657                                 eTextPara *para = new eTextPara(tmp);
658                                 para->setFont(m_element_font[e]);
659                                 para->renderString(text.c_str());
660
661                                 if (e == celServiceName)
662                                 {
663                                         eRect bbox = para->getBoundBox();
664                                         int name_width = bbox.width()+8;
665                                         m_element_position[celServiceInfo].setLeft(area.left()+name_width+xoffs);
666                                         m_element_position[celServiceInfo].setTop(area.top());
667                                         m_element_position[celServiceInfo].setWidth(area.width()-(name_width+xoffs));
668                                         m_element_position[celServiceInfo].setHeight(area.height());
669                                 }
670
671                                 if (flags & gPainter::RT_HALIGN_RIGHT)
672                                         para->realign(eTextPara::dirRight);
673                                 else if (flags & gPainter::RT_HALIGN_CENTER)
674                                         para->realign(eTextPara::dirCenter);
675                                 else if (flags & gPainter::RT_HALIGN_BLOCK)
676                                         para->realign(eTextPara::dirBlock);
677
678                                 if (flags & gPainter::RT_VALIGN_CENTER)
679                                 {
680                                         eRect bbox = para->getBoundBox();
681                                         int vcentered_top = (area.height() - bbox.height()) / 2;
682                                         yoffs = vcentered_top - bbox.top();
683                                 }
684
685                                 painter.renderPara(para, offset+ePoint(xoffs, yoffs));
686                         }
687                         else if (e == celServiceTypePixmap || e == celFolderPixmap || e == celMarkerPixmap)
688                         {
689                                 int orbpos = m_cursor->getUnsignedData(4) >> 16;
690                                 ePtr<gPixmap> &pixmap =
691                                         (e == celFolderPixmap) ? m_pixmaps[picFolder] :
692                                         (e == celMarkerPixmap) ? m_pixmaps[picMarker] :
693                                         (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] :
694                                         (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] :
695                                         (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S];
696                                 if (pixmap)
697                                 {
698                                         eSize pixmap_size = pixmap->size();
699                                         int p = celServiceInfo;
700                                         if (e == celFolderPixmap)
701                                                 p = celServiceName;
702                                         else if (e == celMarkerPixmap)
703                                                 p = celServiceNumber;
704                                         eRect area = m_element_position[p];
705                                         int correction = (area.height() - pixmap_size.height()) / 2;
706
707                                         if (isPlayable)
708                                         {
709                                                 if (e != celServiceTypePixmap)
710                                                         continue;
711                                                 m_element_position[celServiceInfo] = area;
712                                                 m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + 8);
713                                                 m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - 8);
714                                         }
715                                         else if (m_cursor->flags & eServiceReference::isDirectory)
716                                         {
717                                                 if (e != celFolderPixmap)
718                                                         continue;
719                                                 xoffset = pixmap_size.width() + 8;
720                                         }
721                                         else if (m_cursor->flags & eServiceReference::isMarker)
722                                         {
723                                                 if (e != celMarkerPixmap)
724                                                         continue;
725                                         }
726                                         else
727                                                 eFatal("unknown service type in listboxservice");
728
729                                         area.moveBy(offset);
730                                         painter.clip(area);
731                                         painter.blit(pixmap, offset+ePoint(area.left(), correction), area, gPainter::BT_ALPHATEST);
732                                         painter.clippop();
733                                 }
734                         }
735                         else if (e == celServiceEventProgressbar)
736                         {
737                                 eRect area = m_element_position[celServiceEventProgressbar];
738                                 if (area.width() > 0 && (isPlayable || isMarker))
739                                 {
740                                         // we schedule it to paint it as last element.. so we dont need to reset fore/background color
741                                         paintProgress = isPlayable;
742                                         xoffset = area.width() + 10;
743                                 }
744                         }
745                 }
746                 if (selected && (!local_style || !local_style->m_selection))
747                         style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
748                 if (paintProgress && evt)
749                 {
750                         eRect area = m_element_position[celServiceEventProgressbar];
751                         if (!selected && m_color_set[serviceEventProgressbarBorderColor])
752                                 painter.setForegroundColor(m_color[serviceEventProgressbarBorderColor]);
753                         else if (selected && m_color_set[serviceEventProgressbarBorderColorSelected])
754                                 painter.setForegroundColor(m_color[serviceEventProgressbarBorderColorSelected]);
755
756                         int border = 1;
757                         int progressH = 6;
758                         int progressX = area.left() + offset.x();
759                         int progressW = area.width() - 2 * border;
760                         int progressT = offset.y() + (m_itemsize.height() - progressH - 2*border) / 2;
761
762                         // paint progressbar frame
763                         painter.fill(eRect(progressX, progressT, area.width(), border));
764                         painter.fill(eRect(progressX, progressT + border, border, progressH));
765                         painter.fill(eRect(progressX, progressT + progressH + border, area.width(), border));
766                         painter.fill(eRect(progressX + area.width() - border, progressT + border, border, progressH));
767
768                         // calculate value
769                         time_t now = time(0);
770                         int value = progressW * (now - evt->getBeginTime()) / evt->getDuration();
771
772                         eRect tmp = eRect(progressX + border, progressT + border, value, progressH);
773                         ePtr<gPixmap> &pixmap = m_pixmaps[picServiceEventProgressbar];
774                         if (pixmap)
775                         {
776                                 area.moveBy(offset);
777                                 painter.clip(area);
778                                 painter.blit(pixmap, ePoint(progressX + border, progressT + border), tmp, gPainter::BT_ALPHATEST);
779                                 painter.clippop();
780                         }
781                         else
782                         {
783                                 if (!selected && m_color_set[serviceEventProgressbarColor])
784                                         painter.setForegroundColor(m_color[serviceEventProgressbarColor]);
785                                 else if (selected && m_color_set[serviceEventProgressbarColorSelected])
786                                         painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]);
787                                 painter.fill(tmp);
788                         }
789                 }
790         }
791         painter.clippop();
792 }
793
794 void eListboxServiceContent::setIgnoreService( const eServiceReference &service )
795 {
796         m_is_playable_ignore=service;
797         if (m_listbox && m_listbox->isVisible())
798                 m_listbox->invalidate();
799 }
800
801 void eListboxServiceContent::setItemHeight(int height)
802 {
803         m_itemheight = height;
804         if (m_listbox)
805                 m_listbox->setItemHeight(height);
806 }