- work on timers
authorFelix Domke <tmbinc@elitedvb.net>
Sat, 14 May 2005 15:23:23 +0000 (15:23 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Sat, 14 May 2005 15:23:23 +0000 (15:23 +0000)
 - add eInput widget
 - add python/Tools
 - add flexible listbox content

27 files changed:
RecordTimer.py
keymap.xml
lib/gdi/font.h
lib/gui/Makefile.am
lib/gui/einput.cpp [new file with mode: 0644]
lib/gui/einput.h [new file with mode: 0644]
lib/gui/elabel.h
lib/gui/elistbox.cpp
lib/gui/elistbox.h
lib/gui/elistboxcontent.cpp
lib/gui/elistboxcontent.h
lib/python/Components/TimeInput.py [new file with mode: 0644]
lib/python/Components/TimerList.py [new file with mode: 0644]
lib/python/Components/__init__.py
lib/python/Screens/Menu.py
lib/python/Screens/Screen.py
lib/python/Screens/TimerEdit.py [new file with mode: 0644]
lib/python/Screens/__init__.py
lib/python/Tools/.cvsignore [new file with mode: 0644]
lib/python/Tools/FuzzyDate.py [new file with mode: 0644]
lib/python/Tools/XMLTools.py [new file with mode: 0644]
lib/python/Tools/__init__.py [new file with mode: 0644]
lib/python/enigma_python.i
lib/service/iservice.h
mytest.py
skin.py
timer.py

index ad7fa56..0d3d53d 100644 (file)
-from timer import *
 import time
+import codecs
+
+from timer import *
+import xml.dom.minidom
+
+import NavigationInstance
+
+from Tools.XMLTools import elementsWithTag
+from ServiceReference import ServiceReference
 
 class RecordTimerEntry(TimerEntry):
-       def __init__(self, begin, end, nav, serviceref, epg):
-               TimerEntry.__init__(self, begin, end)
-               self.ServiceRef = serviceref
-               self.EpgData = epg
-               self.Timer = None
-               self.Nav = nav
-               self.RecordService = None
+       def __init__(self, begin, end, serviceref, epg):
+               TimerEntry.__init__(self, int(begin), int(end))
+               
+               assert isinstance(serviceref, ServiceReference)
+               
+               self.service_ref = serviceref
+               
+               print self.service_ref.getServiceName()
+               self.epg_data = epg
+               self.timer = None
+               self.record_service = None
                
                # build filename from epg
                
                # pff das geht noch nicht...
-               if epg == None:
-                       self.Filename = "recording.ts"
-               else:
-                       self.Filename = "record_" + str(epg.m_event_name) + ".ts"
-               
-               print "------------ record filename: %s" % (self.Filename)
+#              if epg == None:
+#                      self.Filename = "recording.ts"
+#              else:
+#                      self.Filename = "record_" + str(epg.m_event_name) + ".ts"
+#              
+#              print "------------ record filename: %s" % (self.Filename)
                
        def activate(self, event):
                if event == self.EventPrepare:
-                       self.RecordService = self.Nav.recordService(self.ServiceRef)
-                       if self.RecordService == None:
+                       self.record_service = NavigationInstance.instance.recordService(self.service_ref)
+                       if self.record_service == None:
                                print "timer record failed."
                        else:   
-                               self.RecordService.prepare()
-               elif self.RecordService == None:
+                               self.record_service.prepare()
+               elif self.record_service == None:
                        if event != self.EventAbort:
                                print "timer record start failed, can't finish recording."
                elif event == self.EventStart:
-                       self.RecordService.start()
+                       self.record_service.start()
                        print "timer started!"
                elif event == self.EventEnd or event == self.EventAbort:
-                       self.RecordService.stop()
-                       self.RecordService = None
+                       self.record_service.stop()
+                       self.record_service = None
                        print "Timer successfully ended"
 
+
+def createTimer(xml):
+       begin = int(xml.getAttribute("begin"))
+       end = int(xml.getAttribute("end"))
+       serviceref = ServiceReference(str(xml.getAttribute("serviceref")))
+       epgdata = xml.getAttribute("epgdata")
+       #filename = xml.getAttribute("filename")
+       return RecordTimerEntry(begin, end, serviceref, epgdata)
+
 class RecordTimer(Timer):
        def __init__(self):
                Timer.__init__(self)
                
+               self.Filename = "timers.xml"
+               
+#              try:
+               self.loadTimer()
+#              except:
+#                      print "unable to load timers from file!"
+       
        def loadTimer(self):
-               print "TODO: load timers from xml"
+               
+               # TODO: PATH!
+               doc = xml.dom.minidom.parse(self.Filename)
+               
+               root = doc.childNodes[0]
+               for timer in elementsWithTag(root.childNodes, "timer"):
+                       self.record(createTimer(timer))
        
        def saveTimer(self):
-               print "TODO: save timers to xml"
+               doc = xml.dom.minidom.Document()
+               root_element = doc.createElement('timers')
+               doc.appendChild(root_element)
+               root_element.appendChild(doc.createTextNode("\n"))
+               
+               for timer in self.timer_list + self.processed_timers:
+                       t = doc.createTextNode("\t")
+                       root_element.appendChild(t)
+                       t = doc.createElement('timer')
+                       t.setAttribute("begin", str(timer.begin))
+                       t.setAttribute("end", str(timer.end))
+                       t.setAttribute("serviceref", str(timer.service_ref))
+                       #t.setAttribute("epgdata", timer.)
+                       root_element.appendChild(t)
+                       t = doc.createTextNode("\n")
+                       root_element.appendChild(t)
+               
+               file = open(self.Filename, "w")
+               doc.writexml(codecs.getwriter('UTF-8')(file))
+               file.close()
        
        def record(self, entry):
                entry.Timer = self
                self.addTimerEntry(entry)
 
        def removeEntry(self, entry):
-               if entry.State == TimerEntry.StateRunning:
+               if entry.state == TimerEntry.StateRunning:
                        entry.End = time.time()
                        print "aborting timer"
-               elif entry.State != TimerEntry.StateEnded:
+               elif entry.state != TimerEntry.StateEnded:
                        entry.activate(TimerEntry.EventAbort)
-                       self.TimerList.remove(entry)
+                       self.timer_list.remove(entry)
                        print "timer did not yet start - removing"
                else:
                        print "timer did already end - doing nothing."
 
                self.calcNextActivation()
+
+
+       def shutdown(self):
+               self.saveTimer()
index 2b5f92c..7b6e5fd 100644 (file)
@@ -9,6 +9,15 @@
                <key id="1" mapto="moveUp" flags="mr" />
                <key id="2" mapto="moveDown" flags="mr" />
        </map>
+       
+       <map context="InputActions">
+               <key id="1" mapto="moveLeft" flags="mr" />
+               <key id="2" mapto="moveRight" flags="mr" />
+               <key id="3" mapto="moveHome" flags="mr" />
+               <key id="4" mapto="moveEnd" flags="mr" />
+               <key id="5" mapto="deleteChar" flags="mr" />
+       </map>
+
        <map context="InfobarActions">
                <key id="m" mapto="mainMenu" flags="mr" />
                <key id="c" mapto="switchChannel" flags="mr" />
index ff2a88c..c55b8f4 100644 (file)
@@ -130,9 +130,16 @@ public:
 
                return boundBox;
        }
+       
+       const int size() const
+       {
+               return glyphs.size();
+       }
 
        const eRect& getGlyphBBox(int num) const
        {
+               assert(num >= 0);
+               assert(num < (int)glyphs.size());
                return glyphs[num].bbox;
        }
 };
index 44f5a16..24f7067 100644 (file)
@@ -7,6 +7,7 @@ noinst_LIBRARIES = libenigma_gui.a
 libenigma_gui_a_SOURCES = \
        ebutton.cpp elabel.cpp eslider.cpp ewidget.cpp ewidgetdesktop.cpp  \
        ewindow.cpp ewindowstyle.cpp elistbox.cpp elistboxcontent.cpp \
-       epixmap.cpp ewindowstyleskinned.cpp
+       epixmap.cpp ewindowstyleskinned.cpp einput.cpp
+
 
 
diff --git a/lib/gui/einput.cpp b/lib/gui/einput.cpp
new file mode 100644 (file)
index 0000000..b2c8ad1
--- /dev/null
@@ -0,0 +1,208 @@
+#include <lib/gui/einput.h>
+#include <lib/gdi/font.h>
+#include <lib/actions/action.h>
+
+eInput::eInput(eWidget *parent): eLabel(parent)
+{
+               /* default to center alignment */
+       m_valign = alignCenter;
+       m_halign = alignCenter;
+
+       ePtr<eActionMap> ptr;
+       eActionMap::getInstance(ptr);
+       ptr->bindAction("InputActions", 0, 0, this);
+}
+
+eInput::~eInput()
+{
+       ePtr<eActionMap> ptr;
+       eActionMap::getInstance(ptr);
+       ptr->unbindAction(this, 0);
+}
+
+void eInput::setContent(eInputContent *content)
+{
+       if (m_content)
+               m_content->setInput(0);
+       m_content = content;
+       if (m_content)
+               m_content->setInput(this);
+}
+
+int eInput::event(int event, void *data, void *data2)
+{
+       switch (event)
+       {
+       case evtPaint:
+       {
+               gPainter &painter = *(gPainter*)data2;
+               ePtr<eWindowStyle> style;
+               
+               getStyle(style);
+               
+               eWidget::event(event, data, data2);
+               
+               ePtr<eTextPara> para = new eTextPara(eRect(0, 0, size().width(), size().height()));
+               
+               std::string text;
+               int cursor = -1;
+               
+               if (m_content)
+                       m_content->getDisplay(text, cursor);
+               
+               eDebug("cursor is %d", cursor);
+               para->setFont(m_font);
+               para->renderString(text, 0);
+               
+               int glyphs = para->size();
+               eRect bbox;
+               if (cursor < glyphs)
+               {
+                       bbox = para->getGlyphBBox(cursor);
+                       bbox = eRect(bbox.left()-1, 0, 2, size().height());
+               } else
+               {
+                       bbox = para->getGlyphBBox(cursor - 1);
+                       bbox = eRect(bbox.right(), 0, 2, size().height());
+               }
+               painter.fill(bbox);
+               
+               painter.renderPara(para, ePoint(0, 0));
+               
+               return 0;
+       }
+       case evtAction:
+               if (isVisible())
+               {
+                       switch((int)data2)
+                       {
+                       case moveLeft:
+                               m_content->moveCursor(eInputContent::dirLeft);
+                               break;
+                       case moveRight:
+                               m_content->moveCursor(eInputContent::dirRight);
+                               break;
+                       case moveHome:
+                               m_content->moveCursor(eInputContent::dirHome);
+                               break;
+                       case moveEnd:
+                               m_content->moveCursor(eInputContent::dirEnd);
+                               break;
+                       case deleteChar:
+                               // not yet
+                               break;
+                       }
+                       return 1;
+               }
+               return 0;
+       default:
+               break;
+       }
+       return eLabel::event(event, data, data2);
+}
+
+int eInput::getNumber()
+{
+       return atoi(m_text.c_str());
+}
+
+DEFINE_REF(eInputContentNumber);
+
+void eInputContent::setInput(eInput *widget)
+{
+       m_input = widget;
+}
+
+eInputContentNumber::eInputContentNumber(int cur, int min, int max)
+{
+       m_min = min;
+       m_max = max;
+       m_value = cur;
+       m_cursor = 0;
+       m_input = 0;
+       recalcLen();
+}
+
+void eInputContentNumber::getDisplay(std::string &res, int &cursor)
+{
+       // TODO
+       char r[128];
+       sprintf(r, "%d", m_value);
+       res = r;
+       cursor = m_cursor;
+}
+
+void eInputContentNumber::moveCursor(int dir)
+{
+       eDebug("move cursor..");
+       int old_cursor = m_cursor;
+       
+       switch (dir)
+       {
+       case dirLeft:
+               --m_cursor;
+               break;
+       case dirRight:
+               ++m_cursor;
+               break;
+       case dirHome:
+               m_cursor = 0;
+               break;
+       case dirEnd:
+               m_cursor = m_len;
+               break;
+       }
+       
+       if (m_cursor < 0)
+               m_cursor = 0;
+       if (m_cursor > m_len)
+               m_cursor = m_len;
+       
+       if (m_cursor != old_cursor)
+               if (m_input)
+                       m_input->invalidate();
+}
+
+int eInputContentNumber::haveKey(int code)
+{
+       insertDigit(m_cursor, code);
+       recalcLen();
+       return 0;
+}
+
+int eInputContentNumber::isValid()
+{
+       return m_value >= m_min && m_value <= m_max;
+}
+
+void eInputContentNumber::recalcLen()
+{
+       int v = m_value;
+       m_len = 0;
+       while (v)
+       {
+               ++m_len;
+               v /= 10;
+       }
+       
+       if (!m_len) /* zero */
+               m_len = 1;
+}
+
+void eInputContentNumber::insertDigit(int pos, int dig)
+{
+               /* get stuff left from cursor */
+       int exp = 1;
+       int i;
+       for (i = 0; i < (m_len - pos - 1); ++i)
+               exp *= 10;
+       
+               /* now it's 1...max */
+       int left = m_value / exp;
+       int right = m_value % exp;
+       left *= 10;
+       left += dig;
+       left *= exp;
+       left += right;
+       m_value = left;
+}
diff --git a/lib/gui/einput.h b/lib/gui/einput.h
new file mode 100644 (file)
index 0000000..b742a6d
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef __lib_gui_einput_h
+#define __lib_gui_einput_h
+
+#include <lib/gui/elabel.h>
+#include <lib/python/connections.h>
+
+class eInputContent;
+
+class eInput: public eLabel
+{
+public:
+       eInput(eWidget *parent);
+       virtual ~eInput();
+       PSignal0<void> changed;
+
+       int m_cursor;
+       
+       enum InputActions {
+               moveLeft, 
+               moveRight, 
+               moveHome, 
+               moveEnd,
+               deleteChar
+       };
+       
+       void setContent(eInputContent *cnt);
+       
+       int getNumber();
+protected:
+       ePtr<eInputContent> m_content;
+       int event(int event, void *data=0, void *data2=0);
+};
+
+class eInputContent: public iObject
+{
+public:
+               /* management stuff */
+       void setInput(eInput *widget);
+               /* display stuff */
+       virtual void getDisplay(std::string &res, int &cursor)=0;
+
+               /* movement / user actions */
+       enum {
+               dirLeft, dirRight,
+               dirHome, dirEnd,
+                       /* contents can define their own directions */
+               dirUser
+       };
+       virtual void moveCursor(int dir)=0;
+               /* no movement keys except stuff like '.' or so*/
+       virtual int haveKey(int code)=0;
+       
+       virtual int isValid()=0;
+protected:
+       eInput *m_input;
+};
+
+class eInputContentNumber: public eInputContent
+{
+       DECLARE_REF(eInputContentNumber);
+public:
+       eInputContentNumber(int cur, int min, int max);
+
+       void getDisplay(std::string &res, int &cursor);
+       void moveCursor(int dir);
+       int haveKey(int code);
+       int isValid();
+       
+private:
+       void recalcLen();
+       
+       void insertDigit(int pos, int dig);
+       
+       int m_value;
+       int m_cursor, m_len;
+       
+       int m_min, m_max;
+};
+
+#endif
index 7e07f43..c19eb0a 100644 (file)
@@ -25,6 +25,7 @@ public:
 protected:
        ePtr<gFont> m_font;
        int m_valign, m_halign;
+       std::string m_text;
        int event(int event, void *data=0, void *data2=0);
 private:
        enum eLabelEvent
@@ -33,7 +34,6 @@ private:
                evtChangedFont,
                evtChangedAlignment
        };
-       std::string m_text;
 };
 
 #endif
index ba2e352..4598fa0 100644 (file)
@@ -9,6 +9,8 @@ eListbox::eListbox(eWidget *parent): eWidget(parent)
        ePtr<eActionMap> ptr;
        eActionMap::getInstance(ptr);
        
+       m_itemheight = 20;
+       
        ptr->bindAction("ListboxActions", 0, 0, this);
 }
 
@@ -146,11 +148,19 @@ int eListbox::event(int event, void *data, void *data2)
 
 void eListbox::recalcSize()
 {
-       m_itemheight = 20;
        m_content->setSize(eSize(size().width(), m_itemheight));
        m_items_per_page = size().height() / m_itemheight;
 }
 
+void eListbox::setItemHeight(int h)
+{
+       if (h)
+               m_itemheight = h;
+       else
+               m_itemheight = 20;
+       recalcSize();
+}
+
 void eListbox::entryAdded(int index)
 {
                /* manage our local pointers. when the entry was added before the current position, we have to advance. */
index 9e23bde..29349cb 100644 (file)
@@ -73,6 +73,8 @@ public:
                pageDown,
                justCheck
        };
+       
+       void setItemHeight(int h);
 
 #ifndef SWIG
                /* entryAdded: an entry was added *before* the given index. it's index is the given number. */
index d51729d..54e3a24 100644 (file)
@@ -377,6 +377,11 @@ PyObject *eListboxPythonStringContent::getCurrentSelection()
        return r;
 }
 
+void eListboxPythonStringContent::invalidateEntry(int index)
+{
+       m_listbox->entryChanged(index);
+}
+
 //////////////////////////////////////
 
 void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
@@ -424,8 +429,117 @@ void eListboxPythonConfigContent::paint(gPainter &painter, eWindowStyle &style,
        painter.clippop();
 }
 
-void eListboxPythonConfigContent::invalidateEntry(int index)
+//////////////////////////////////////
+
+void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected)
 {
-       m_listbox->entryChanged(index);
+       painter.clip(eRect(offset, m_itemsize));
+       style.setStyle(painter, selected ? eWindowStyle::styleListboxSelected : eWindowStyle::styleListboxNormal);
+       painter.clear();
+
+       if (m_list && cursorValid())
+       {
+               PyObject *items = PyList_GetItem(m_list, m_cursor); // borrowed reference!
+               
+               if (!items)
+               {
+                       eDebug("eListboxPythonMultiContent: error getting item %d", m_cursor);
+                       painter.clippop();
+                       return;
+               }
+               
+               if (!PyList_Check(items))
+               {
+                       eDebug("eListboxPythonMultiContent: list entry %d is not a list", m_cursor);
+                       painter.clippop();
+                       return;
+               }
+               
+               int size = PyList_Size(items);
+               for (int i = 0; i < size; ++i)
+               {
+                       PyObject *item = PyList_GetItem(items, i); // borrowed reference!
+                       
+                       if (!item)
+                       {
+                               eDebug("eListboxPythonMultiContent: ?");
+                               painter.clippop();
+                               return;
+                       }
+                       
+                       
+                       PyObject *px, *py, *pwidth, *pheight, *pfnt, *pstring, *pflags;
+               
+                       /*
+                               we have a list of tuples:
+                               
+                               (x, y, width, height, fnt, flags, "bla" ),
+                               
+                        */
+                       
+                       if (!PyTuple_Check(item))
+                       {
+                               eDebug("eListboxPythonMultiContent did not receive a tuple.");
+                               painter.clippop();
+                               return;
+                       }
+               
+                       px = PyTuple_GetItem(item, 0);
+                       py = PyTuple_GetItem(item, 1);
+                       pwidth = PyTuple_GetItem(item, 2);
+                       pheight = PyTuple_GetItem(item, 3);
+                       pfnt = PyTuple_GetItem(item, 4);
+                       pflags = PyTuple_GetItem(item, 5);
+                       pstring = PyTuple_GetItem(item, 6);
+                       
+                       if (!(px && py && pwidth && pheight && pfnt && pstring))
+                       {
+                               eDebug("eListboxPythonMultiContent received too small tuple (must be (x, y, width, height, fnt, flags, string[, ...])");
+                               painter.clippop();
+                               return;
+                       }
+       
+                       pstring = PyObject_Str(pstring);
+                       
+                       const char *string = (PyString_Check(pstring)) ? PyString_AsString(pstring) : "<not-a-string>";
+                       
+                       int x = PyInt_AsLong(px);
+                       int y = PyInt_AsLong(py);
+                       int width = PyInt_AsLong(pwidth);
+                       int height = PyInt_AsLong(pheight);
+                       int flags = PyInt_AsLong(pflags);
+                       
+                       int fnt = PyInt_AsLong(pfnt);
+                       
+                       if (m_font.find(fnt) == m_font.end())
+                       {
+                               eDebug("eListboxPythonMultiContent: specified font %d was not found!", fnt);
+                               Py_XDECREF(pstring);
+                               painter.clippop();
+                               return;
+                       }
+                       
+                       eRect r = eRect(x, y, width, height);
+                       r.moveBy(offset);
+                       
+                       painter.setFont(m_font[fnt]);
+                       
+                       painter.renderText(r, string, flags);
+       
+                       Py_XDECREF(pstring);
+                       
+                       if (selected)
+                               style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry);
+               }
+       }
+       
+       painter.clippop();
 }
 
+void eListboxPythonMultiContent::setFont(int fnt, gFont *font)
+{
+       if (font)
+               m_font[fnt] = font;
+       else
+               m_font.erase(fnt);
+}
index 0c4cb00..6a4cdaa 100644 (file)
@@ -103,6 +103,7 @@ protected:
        
                /* the following functions always refer to the selected item */
        virtual void paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected);
+       void invalidateEntry(int index);
 
 protected:
        PyObject *m_list;
@@ -115,10 +116,19 @@ class eListboxPythonConfigContent: public eListboxPythonStringContent
 {
 public:
        void paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected);
-       void invalidateEntry(int index);
        void setSeperation(int sep) { m_seperation = sep; }
 private:
        int m_seperation;
 };
 
+class eListboxPythonMultiContent: public eListboxPythonStringContent
+{
+public:
+       void paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected);
+       
+       void setFont(int fnt, gFont *fnt);
+private:
+       std::map<int, ePtr<gFont> > m_font;
+};
+
 #endif
diff --git a/lib/python/Components/TimeInput.py b/lib/python/Components/TimeInput.py
new file mode 100644 (file)
index 0000000..c520fdf
--- /dev/null
@@ -0,0 +1,18 @@
+from HTMLComponent import *
+from GUIComponent import *
+from VariableText import *
+
+from enigma import eInput, eInputContentNumber
+
+class TimeInput(HTMLComponent, GUIComponent):
+       def __init__(self):
+               GUIComponent.__init__(self)
+               self.content = eInputContentNumber(12, 0, 15)
+       
+       def GUIcreate(self, parent, skindata):
+               self.instance = eInput(parent)
+               self.instance.setContent(self.content)
+       
+       def GUIdelete(self):
+               self.instance.setContent(None)
+               self.instance = None
diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py
new file mode 100644 (file)
index 0000000..da005b0
--- /dev/null
@@ -0,0 +1,57 @@
+from HTMLComponent import *
+from GUIComponent import *
+
+from Tools.FuzzyDate import FuzzyTime
+
+from enigma import eListboxPythonMultiContent, eListbox, gFont
+
+
+RT_HALIGN_LEFT = 0
+RT_HALIGN_RIGHT = 1
+RT_HALIGN_CENTER = 2
+RT_HALIGN_BLOCK = 4
+
+RT_VALIGN_TOP = 0
+RT_VALIGN_CENTER = 8
+RT_VALIGN_BOTTOM = 16
+
+RT_WRAP = 32
+
+
+#
+#  | <Service>     <Name of the Timer>  |
+#  | <start>                     <end>  |
+#
+def TimerEntry(timer, processed):
+       res = [ ]
+       
+       res.append((0, 0, 400, 30, 0, RT_HALIGN_LEFT, timer.service_ref.getServiceName()))
+       res.append((0, 30, 200, 20, 1, RT_HALIGN_LEFT, "%s, %s" % FuzzyTime(timer.begin)))
+       
+       if processed:
+               res.append((200, 30, 200, 20, 1, RT_HALIGN_RIGHT, FuzzyTime(timer.end)[1]))
+       else:
+               res.append((200, 30, 200, 20, 1, RT_HALIGN_RIGHT, "done"))
+       return res
+
+class TimerList(HTMLComponent, GUIComponent):
+       def __init__(self, list):
+               GUIComponent.__init__(self)
+               self.l = eListboxPythonMultiContent()
+               self.l.setList(list)
+               self.l.setFont(0, gFont("Arial", 20))
+               self.l.setFont(1, gFont("Arial", 18))
+       
+       def getCurrent(self):
+               return self.l.getCurrentSelection()
+       
+       def GUIcreate(self, parent, skindata):
+               self.instance = eListbox(parent)
+               self.instance.setContent(self.l)
+               self.instance.setItemHeight(50)
+       
+       def GUIdelete(self):
+               self.instance.setContent(None)
+               self.instance = None
+
+
index 8a064b2..d7cd406 100644 (file)
@@ -3,5 +3,5 @@ __all__ = ["ActionMap", "Button", "Clock", "ConfigList", "EventInfo",
        "GUIComponent", "GUISkin", "HTMLComponent", "HTMLSkin", "Header",
        "Label", "MenuList", "PerServiceDisplay", "ProgressBar", "ServiceList",
        "ServiceName", "ServiceScan", "VariableText", "VariableValue", "VolumeBar",
-       "components", "config"]
+       "components", "config", "TimerList", "TimeInput" ]
 
index ce73a95..c380931 100644 (file)
@@ -11,6 +11,8 @@ from Components.Label import Label
 from Components.ProgressBar import ProgressBar
 from ConfigMenu import *
 
+from TimerEdit import *
+
 from enigma import quitMainloop
 
 import xml.dom.minidom
@@ -32,7 +34,7 @@ mdom = xml.dom.minidom.parseString(
                <item text="Radio-Mode">self.setModeRadio()</item>
                <item text="File-Mode">self.setModeFile()</item>
                <item text="Scart">self.openDialog(ScartLoopThrough)</item>
-               <item text="Timer"></item>
+               <item text="Timer">self.openDialog(TimerEditList)</item>
                <menu text="Setup">
                        <menu text="Service Organising">
                                <item text="New Bouquets"></item>
index ef9b2bb..1b42141 100644 (file)
@@ -29,7 +29,6 @@ class Screen(dict, HTMLSkin, GUISkin):
                
                del self.session
                for (name, val) in self.items():
-                       print "%s -> %d" % (name, sys.getrefcount(val))
                        del self[name]
        
        def close(self, retval=None):
diff --git a/lib/python/Screens/TimerEdit.py b/lib/python/Screens/TimerEdit.py
new file mode 100644 (file)
index 0000000..41b6a12
--- /dev/null
@@ -0,0 +1,54 @@
+from Screen import Screen
+from Components.TimerList import TimerList, TimerEntry
+from Components.ActionMap import ActionMap
+from Components.TimeInput import TimeInput
+from Components.Label import Label
+from Components.Button import Button
+
+class TimerEdit(Screen):
+       def __init__(self, session, entry):
+               Screen.__init__(self, session)
+
+               self["actions"] = ActionMap(["OkCancelActions"], 
+                       {
+                               "ok": self.apply,
+                               "cancel": self.close
+                       })
+               
+               self.entry = entry
+               # begin, end, description, service
+               self["begin"] = TimeInput()
+               self["end"] = TimeInput()
+               
+               self["lbegin"] = Label("Begin")
+               self["lend"] = Label("End")
+               
+               self["description"] = Label("bla")
+# TextInput()
+               self["apply"] = Button("Apply")
+               self["service"] = Button()
+       
+       def apply(self):
+               print "applied!"
+       
+class TimerEditList(Screen):
+       def __init__(self, session):
+               Screen.__init__(self, session)
+               
+               list = [ ]
+               for timer in session.nav.RecordTimer.timer_list:
+                       list.append(TimerEntry(timer, 0))
+               
+               for timer in session.nav.RecordTimer.processed_timers:
+                       list.append(TimerEntry(timer, 1))
+               
+               self["timerlist"] = TimerList(list)
+
+               self["actions"] = ActionMap(["OkCancelActions"], 
+                       {
+                               "ok": self.openEdit,
+                               "cancel": self.close
+                       })
+
+       def openEdit(self):
+               self.session.open(TimerEdit, self["timerlist"].getCurrent())
index 90b22c2..fbd2c17 100644 (file)
@@ -1,3 +1,4 @@
 __all__ = ["ChannelSelection", "ClockDisplay", "ConfigMenu", 
-       "InfoBar", "Menu", "ScartLoopThrough", "Screen", "ServiceScan"]
+       "InfoBar", "Menu", "ScartLoopThrough", "Screen", "ServiceScan",
+       "TimerEdit"]
 
diff --git a/lib/python/Tools/.cvsignore b/lib/python/Tools/.cvsignore
new file mode 100644 (file)
index 0000000..0d20b64
--- /dev/null
@@ -0,0 +1 @@
+*.pyc
diff --git a/lib/python/Tools/FuzzyDate.py b/lib/python/Tools/FuzzyDate.py
new file mode 100644 (file)
index 0000000..c5055ba
--- /dev/null
@@ -0,0 +1,39 @@
+import time
+
+def FuzzyTime(t):
+       d = time.localtime(t)
+       nt = time.time()
+       n = time.localtime()
+       
+       if d[:3] == n[:3]:
+               # same day
+               date = "Today"
+       elif ((t - nt) < 7*86400) and (nt < t):
+               # same week
+               date = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")[d[6]]
+       elif d[0] == n[0]:
+               # same year
+               date = "%d.%d." % (d[2], d[1])
+       else:
+               date = "%d.%d.%d" % (d[2], d[1], d[0])
+       
+       timeres = "%d:%02d" % (d[3], d[4])
+       
+       return (date, timeres)
+
+if __name__ == "__main__":
+       print "now:    %s %s" % FuzzyDate(time.time())
+       print "1 day:  %s %s" % FuzzyDate(time.time() + 86400)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *2)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *3)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *4)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *5)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *6)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *7)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *8)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *9)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *10)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *11)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *12)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *13)
+       print "2 days: %s %s" % FuzzyDate(time.time() + 86400 *14)
diff --git a/lib/python/Tools/XMLTools.py b/lib/python/Tools/XMLTools.py
new file mode 100644 (file)
index 0000000..aaab467
--- /dev/null
@@ -0,0 +1,17 @@
+import xml.dom.minidom
+
+def elementsWithTag(el, tag):
+
+       """filters all elements of childNode with the specified function
+       example: nodes = elementsWithTag(childNodes, lambda x: x == "bla")"""
+
+       # fiiixme! (works but isn't nice)
+       if isinstance(tag, str):
+               s = tag
+               tag = lambda x: x == s
+               
+       for x in el:
+               if x.nodeType != xml.dom.minidom.Element.nodeType:
+                       continue
+               if tag(x.tagName):
+                       yield x
diff --git a/lib/python/Tools/__init__.py b/lib/python/Tools/__init__.py
new file mode 100644 (file)
index 0000000..4ff7ce3
--- /dev/null
@@ -0,0 +1 @@
+all = ["FuzzyDate.py", "XMLTools.py"]
index 11faff1..6062c7d 100644 (file)
@@ -48,6 +48,7 @@ is usually caused by not marking PSignals as immutable.
 
 #include <lib/gui/ewidget.h>
 #include <lib/gui/elabel.h>
+#include <lib/gui/einput.h>
 #include <lib/gui/epixmap.h>
 #include <lib/gui/ebutton.h>
 #include <lib/gui/ewindow.h>
@@ -92,6 +93,7 @@ extern PSignal1<void,int> &keyPressedSignal();
 
 // TODO: embed these...
 %immutable eButton::selected;
+%immutable eInput::changed;
 %immutable eComponentScan::statusChanged;
 %immutable pNavigation::m_event;
 
@@ -101,6 +103,7 @@ extern PSignal1<void,int> &keyPressedSignal();
 %include <lib/gdi/region.h>
 %include <lib/gui/ewidget.h>
 %include <lib/gui/elabel.h>
+%include <lib/gui/einput.h>
 %include <lib/gui/epixmap.h>
 %include <lib/gui/ebutton.h>
 %include <lib/gui/ewindow.h>
index 4379fbb..f7f6d5c 100644 (file)
@@ -143,6 +143,9 @@ class iStaticServiceInformation: public iObject
 {
 public:
        virtual RESULT getName(const eServiceReference &ref, std::string &name)=0;
+
+               // FOR SWIG
+       std::string getName(const eServiceReference &ref) { std::string temp; getName(ref, temp); return temp; }
 };
 
 TEMPLATE_TYPEDEF(ePtr<iStaticServiceInformation>, iStaticServiceInformationPtr);
index bfc015c..461fdfa 100644 (file)
--- a/mytest.py
+++ b/mytest.py
@@ -3,11 +3,13 @@ from tools import *
 
 import Screens.InfoBar
 
-import RecordTimer
-
 import sys
 import time
 
+import ServiceReference
+
+from Navigation import Navigation
+
 from skin import applyGUIskin
 
 # A screen is a function which instanciates all components of a screen into a temporary component.
@@ -126,78 +128,11 @@ class Session:
                self.execBegin()
 
        def keyEvent(self, code):
-#              print "code " + str(code)
-               if code == 32:
-                       self.currentDialog["okbutton"].instance.push()
-
-               if code == 33:
-                       self.currentDialog["channelSwitcher"].instance.push()
-               
-               if code >= 0x30 and code <= 0x39:
-                       try:
-                               self.currentDialog["menu"].instance.moveSelection(code - 0x31)
-                       except:
-                               self.currentDialog["list"].instance.moveSelection(code - 0x31)
+               print "code " + str(code)
 
        def close(self):
                self.delayTimer.start(0, 1)
 
-# TODO: remove pNavgation, eNavigation and rewrite this stuff in python.
-class Navigation:
-       def __init__(self):
-               self.pnav = pNavigation()
-               self.pnav.m_event.get().append(self.callEvent)
-               self.event = [ ]
-               self.currentlyPlayingService = None
-               
-               self.RecordTimer = RecordTimer.RecordTimer()
-
-       def callEvent(self, i):
-               for x in self.event:
-                       x(i)
-       
-       def playService(self, ref):
-               self.currentlyPlayingServiceReference = None
-               if not self.pnav.playService(ref):
-                       self.currentlyPlayingServiceReference = ref
-                       return 0
-               return 1
-       
-       def getCurrentlyPlayingServiceReference(self):
-               return self.currentlyPlayingServiceReference
-       
-       def recordService(self, ref):
-               service = iRecordableServicePtr()
-               print "recording service: %s" % (str(ref))
-               if self.pnav.recordService(ref, service):
-                       print "record returned non-zero"
-                       return None
-               else:
-                       print "ok, recordService didn't fail"
-                       return service
-       
-       def enqueueService(self, ref):
-               return self.pnav.enqueueService(ref)
-       
-       def getCurrentService(self):
-               service = iPlayableServicePtr()
-               if self.pnav.getCurrentService(service):
-                       return None
-               return service
-       
-       def getPlaylist(self):
-               playlist = ePlaylistPtr()
-               if self.pnav.getPlaylist(playlist):
-                       return None
-               return playlist
-       
-       def pause(self, p):
-               return self.pnav.pause(p)
-       
-       def recordWithTimer(self, begin, end, ref, epg):
-               entry = RecordTimer.RecordTimerEntry(begin, end, self, ref, epg)
-               self.RecordTimer.record(entry)
-               return entry
 
 def runScreenTest():
        session = Session()
@@ -211,6 +146,8 @@ def runScreenTest():
        
        runMainloop()
        
+       session.nav.shutdown()
+       
        return 0
 
 import keymapparser
diff --git a/skin.py b/skin.py
index dc01e34..72cef1a 100644 (file)
--- a/skin.py
+++ b/skin.py
@@ -2,6 +2,7 @@ from enigma import *
 import xml.dom.minidom
 from xml.dom import EMPTY_NAMESPACE
 
+from Tools.XMLTools import elementsWithTag
 
 colorNames = dict()
 
@@ -71,6 +72,9 @@ dom = xml.dom.minidom.parseString(
                <screen name="configTest" position="300,100" size="300,300" title="config menu">
                        <widget name="config" position="10,30" size="280,140" />
                </screen>
+               <screen name="TimerEditList" position="160,100" size="420,430" title="Timer Editor">
+                       <widget name="timerlist" position="10,30" size="400,300" />
+               </screen>
                <screen name="clockDisplay" position="300,100" size="300,300">
                        <widget name="okbutton" position="10,10" size="280,40" />
                        <widget name="title" position="10,120" size="280,50" />
@@ -99,23 +103,16 @@ dom = xml.dom.minidom.parseString(
                        <widget name="scan_progress" position="10,10" size="280,50" />
                        <widget name="scan_state" position="10,60" size="280,30" />
                </screen>
+               <screen name="TimerEdit" position="70,100" size="590,335" title="Timer Edit">
+                       <widget name="description" position="10,10" size="580,40" />
+                       <widget name="lbegin" position="405,102" size="103,30" />
+                       <widget name="lend" position="405,158" size="103,30" />
+                       <widget name="begin" position="508,105" size="72,35" font="Arial;30" />
+                       <widget name="end" position="508,150" size="72,35" font="Arial;30" />
+                       <widget name="apply" position="10,240" size="250,35" />
+               </screen>
        </skin>""")
 
-# filters all elements of childNode with the specified function
-# example: nodes = elementsWithTag(childNodes, lambda x: x == "bla")
-def elementsWithTag(el, tag):
-
-       # fiiixme! (works but isn't nice)
-       if tag.__class__ == "".__class__:
-               str = tag
-               tag = lambda x: x == str
-               
-       for x in el:
-               if x.nodeType != xml.dom.minidom.Element.nodeType:
-                       continue
-               if tag(x.tagName):
-                       yield x
-
 def parsePosition(str):
        x, y = str.split(',')
        return ePoint(int(x), int(y))
index 294102b..023e4e3 100644 (file)
--- a/timer.py
+++ b/timer.py
@@ -14,47 +14,47 @@ class TimerEntry:
        StateEnded   = 3
        
        def __init__(self, begin, end):
-               self.Begin = begin
-               self.Prepare = 10
-               self.End = end
-               self.State = 0
+               self.begin = begin
+               self.prepare_time = 10
+               self.end = end
+               self.state = 0
        
        def getTime(self):
-               if self.State == 0:
-                       return self.Begin - self.Prepare
-               elif self.State == 1:
-                       return self.Begin
+               if self.state == 0:
+                       return self.begin - self.prepare_time
+               elif self.state == 1:
+                       return self.begin
                else:
-                       return self.End 
+                       return self.end 
        
        def __lt__(self, o):
                return self.getTime() < o.getTime()
        
        def activate(self, event):
-               print "timer %s got activated (%d)!" % (self.Description, event)
+               print "timer %s got activated (%d)!" % (self.description, event)
 
 class Timer:
 
        MaxWaitTime = 100
 
        def __init__(self):
-               self.TimerList = [ ]
-               self.ProcessedTimers = [ ]
+               self.timer_list = [ ]
+               self.processed_timers = [ ]
                
-               self.Timer = eTimer()
-               self.Timer.timeout.get().append(self.calcNextActivation)
+               self.timer = eTimer()
+               self.timer.timeout.get().append(self.calcNextActivation)
                
                self.calcNextActivation()
        
        def addTimerEntry(self, entry):
-               bisect.insort(self.TimerList, entry)
+               bisect.insort(self.timer_list, entry)
                self.calcNextActivation()
        
        def setNextActivation(self, when):
                delay = int((when - time()) * 1000)
                print "next activation: %d (in %d seconds)" % (when, delay)
                
-               self.Timer.start(delay, 1)
+               self.timer.start(delay, 1)
                self.next = when
 
        def calcNextActivation(self):
@@ -63,28 +63,28 @@ class Timer:
                min = int(time()) + self.MaxWaitTime
                
                # calculate next activation point
-               if len(self.TimerList):
-                       w = self.TimerList[0].getTime()
+               if len(self.timer_list):
+                       w = self.timer_list[0].getTime()
                        if w < min:
                                min = w
                
                self.setNextActivation(min)
        
        def doActivate(self, w):
-               w.activate(w.State)
-               self.TimerList.remove(w)
-               w.State += 1
-               if w.State < TimerEntry.StateEnded:
-                       bisect.insort(self.TimerList, w)
+               w.activate(w.state)
+               self.timer_list.remove(w)
+               w.state += 1
+               if w.state < TimerEntry.StateEnded:
+                       bisect.insort(self.timer_list, w)
                else:
-                       bisect.insort(self.ProcessedTimers, w)
+                       bisect.insort(self.processed_timers, w)
        
        def processActivation(self):
                t = int(time()) + 1
                
                # we keep on processing the first entry until it goes into the future.
-               while len(self.TimerList) and self.TimerList[0].getTime() < t:
-                       self.doActivate(self.TimerList[0])
+               while len(self.timer_list) and self.timer_list[0].getTime() < t:
+                       self.doActivate(self.timer_list[0])
 
 #t = Timer()
 #base = time() + 5