]> git.vomp.tv Git - vompclient.git/commitdiff
Add tvscraper support and other image handling stuff to vomp
authorMarten Richter <marten.richter@freenet.de>
Sun, 13 Jul 2014 12:21:29 +0000 (14:21 +0200)
committerMarten Richter <marten.richter@freenet.de>
Sun, 13 Jul 2014 12:21:29 +0000 (14:21 +0200)
44 files changed:
boxx.cc
boxx.h
command.cc
eventdispatcher.cc
eventdispatcher.h
message.h
movieinfo.cc [new file with mode: 0644]
movieinfo.h [new file with mode: 0644]
objects.mk
osd.h
osdopenvg.cc
osdopenvg.h
osdvector.cc
osdvector.h
recinfo.cc
recinfo.h
recording.cc
recording.h
seriesinfo.cc [new file with mode: 0644]
seriesinfo.h [new file with mode: 0644]
surfacevector.cc
surfacevector.h
tvmedia.cc [new file with mode: 0644]
tvmedia.h [new file with mode: 0644]
vconnect.cc
vdr.cc
vdr.h
vdrcommand.h
vdrresponsepacket.cc
vdrresponsepacket.h
videoomx.cc
vrecording.cc
vrecording.h
wmovieview.cc [new file with mode: 0644]
wmovieview.h [new file with mode: 0644]
woptionpane.cc
wpictureview.cc [new file with mode: 0644]
wpictureview.h [new file with mode: 0644]
wseriesview.cc [new file with mode: 0644]
wseriesview.h [new file with mode: 0644]
wtabbar.cc
wtabbar.h
wtextbox.cc
wtextbox.h

diff --git a/boxx.cc b/boxx.cc
index dd12024831bca3a051230b3cc4186f596363b80a..2222086f87c5dd05c696af3e67a020e8b2ba2bc8 100644 (file)
--- a/boxx.cc
+++ b/boxx.cc
@@ -26,6 +26,7 @@
 #include "osd.h"
 
 #include "boxx.h"
+#include "surfacevector.h"
 char Boxx::numBoxxes = 0;
 
 Boxx::Boxx()
@@ -241,7 +242,7 @@ void Boxx::fillColour(const DrawStyle& colour)
   rectangle(0, 0, area.w, area.h, colour);
 }
 
-void Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour)
+int Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour,unsigned int skiplines)
 {
   char line[256];
   int lineHeight = getFontHeight() + paraVSpace;
@@ -252,6 +253,9 @@ void Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour)
   int linePos;
   int ypos;
   int printLine;
+  int leftlines=0;
+
+  int drawLinePos=-skiplines;
 
   textPos = 0;
   ypos = y;
@@ -308,15 +312,22 @@ void Boxx::drawPara(const char* text, int x, int y, const DrawStyle& colour)
 
     if (printLine || (linePos > 1)) // if some text was put in line
     {
-      drawText(line, x, ypos, colour);
-      ypos += lineHeight;
-      if (ypos > (int)(area.h - lineHeight)) break;
+       if (ypos <= (int)(area.h - lineHeight + paraVSpace)) {
+               if (drawLinePos >= 0) {
+                       drawText(line, x, ypos, colour);
+                       ypos += lineHeight;
+               }
+       } else {
+               leftlines++;
+       }
+      drawLinePos++;
     }
     else
     {
       break;
     }
   }
+  return leftlines;
 }
 
 void Boxx::rectangle(Region& region, const DrawStyle& colour)
@@ -411,6 +422,27 @@ void Boxx::drawMonoBitmap(UCHAR*base, int dx, int dy, unsigned int height,unsign
   else if (surface) surface->drawMonoBitmap(base, dx,dy, height, width, nextColour);
 }
 
+void Boxx::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float  width, float height, Corner corner)
+{
+       if (parent) parent->drawTVMedia(tvmedia,area.x + x,area.y + y,width, height, corner);
+       else if (surface) {
+               SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
+               if (surfacevector) surfacevector->drawTVMedia(tvmedia,x, y,width, height, corner);
+               else surface->fillblt(x, y, width, height, DrawStyle::RED); // Signal that something went wrong
+       }
+
+}
+
+void Boxx::drawClippingRectangle(float x, float y, float w, float h)
+{
+       if (parent) parent->drawClippingRectangle(area.x + x, area.y + y, w, h);
+       else if (surface) {
+               SurfaceVector * surfacevector=dynamic_cast<SurfaceVector*>(surface);
+               if (surfacevector) surfacevector->drawClippingRectangle(x, y, w, h);
+
+       }
+}
+
 int Boxx::getFontHeight()
 {
   if (parent) return parent->getFontHeight();
diff --git a/boxx.h b/boxx.h
index a90a070e321c3b2500e805f762bd3b8ee22e87f4..1b768664e8b5e6aac862fa86cde1435684b12ba4 100644 (file)
--- a/boxx.h
+++ b/boxx.h
@@ -32,6 +32,8 @@ using namespace std;
 
 
 #include "surface.h"
+#include "tvmedia.h"
+#include "osdvector.h"
 
 class Bitmap;
 
@@ -91,7 +93,7 @@ class Boxx
     
     // Drawing functions level 1
     void fillColour(const DrawStyle & colour);
-    void drawPara(const char* text, int x, int y, const DrawStyle& colour);
+    int drawPara(const char* text, int x, int y, const DrawStyle& colour, unsigned int skiplines=0);
 
     // Drawing functions level 0
     void rectangle(UINT x, UINT y, UINT w, UINT h, const DrawStyle& colour);
@@ -106,6 +108,8 @@ class Boxx
     void drawBitmap(UINT x, UINT y, const Bitmap& bm, const DisplayRegion & region);
    //Now deprecated
     // void drawPixelAlpha(UINT x, UINT y, const Colour& colour,bool fastdraw=false);
+    void drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float width, float height, Corner corner=TopLeft);
+    void drawClippingRectangle(float x, float y, float w, float h);
     int getFontHeight();
 
     void drawJpeg(const char *fileName,int x, int y,int *width, int *height);
index 8288d2f6d526e00c31516e1a7f241463e6fab07b..b942f2c709756db346311819cbdd28f04211d15c 100644 (file)
@@ -445,6 +445,18 @@ void Command::processMessage(Message* m)
 
         break;
       }
+      case Message::PICTURES_ARRIVED:
+      {
+         Log::getInstance()->log("Command", Log::DEBUG, "TVMedia Pictures arrived");
+         OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
+         if (osdv) {
+                 osdv->processReceivedPictures();
+               /*  if (osdv->processReceivedPictures()) {
+                         Log::getInstance()->log("Command", Log::DEBUG, "TVMedia Boxstack update triggered");
+                         boxstack->update(NULL,NULL);
+                 }*/
+         }
+      } break;
     }
   }
   else
@@ -595,6 +607,7 @@ void Command::doPowerOff()
 
 void Command::doFromTheTop(bool which)
 {
+  if (isStandby) return;
   if (which)
   {
     if (connLost)
index eba132a5831abc9e0e10116c8db7a8a3e756329f..dd1692bd2741a5f87c79bc21249f7805c98df8ef 100644 (file)
@@ -60,8 +60,9 @@ bool EventDispatcher::edFindAndCall(void* userTag)
   }
   
   edr->callinprogress = true;
-  edUnlock();  
-  bool edrType = edr->call(userTag);
+  edUnlock();
+  bool edr_delete=false;
+  bool edrType = edr->call(userTag,edr_delete);
   edLock();
   edr->callinprogress = false;
 
@@ -97,6 +98,7 @@ bool EventDispatcher::edFindAndCall(void* userTag)
     #else
     SetEvent(edr->cond);
     #endif
+    if (edr_delete) delete edr;
   }
   
   edUnlock();
index 3b0a5ee805b52b9c148bfef538fc3867cea6dbce..500ec59c4b6b6c7fc80314d50f741dea4b13f90c 100644 (file)
@@ -44,7 +44,7 @@ class EDReceiver //(implementation in eventdispatcher.cc)
     virtual ~EDReceiver();
 
   protected:
-    virtual bool call(void* userTag)=0; // Implementor must override this and do the actual call
+    virtual bool call(void* userTag, bool & deleteme)=0; // Implementor must override this and do the actual call
                            // return true to have EventDispatcher remove receiver from list after call
     bool nomorecalls;
     bool callinprogress;
index b53018a40b36b1131198ffb80d3fdc540971c856..1494129a2465bc1f83ac65602560664788e219da 100644 (file)
--- a/message.h
+++ b/message.h
@@ -77,6 +77,7 @@ class Message
     const static ULONG TELETEXTUPDATEFIRSTLINE = 33;
     const static ULONG SUBTITLE_CHANGE_CHANNEL = 34;
     const static ULONG MOUSE_ANDROID_SCROLL = 35;
+    const static ULONG PICTURES_ARRIVED = 36;
 };
 
 #endif
diff --git a/movieinfo.cc b/movieinfo.cc
new file mode 100644 (file)
index 0000000..2513c18
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "movieinfo.h"
+
+MovieInfo::MovieInfo()
+{
+       id=0;
+       title="";
+       originalTitle="";
+       tagline="";
+       overview="";
+       adult=0;
+       collectionName="";
+
+       budget=0;
+       revenue=0;
+       genres="";
+       homepage="";
+       releaseDate="";
+       runtime=0;
+       popularity=0.f;
+       voteAverage=0.f;
+
+
+
+}
+
+
diff --git a/movieinfo.h b/movieinfo.h
new file mode 100644 (file)
index 0000000..31c3358
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef MOVIEINFO_H
+#define MOVIEINFO_H
+
+#include "tvmedia.h"
+
+class MovieInfo {
+public:
+       MovieInfo();
+
+       int id;
+
+       std::string title;
+       std::string originalTitle;
+       std::string tagline;
+       std::string overview;
+       UCHAR adult;
+       std::string collectionName;
+
+       int budget;
+       int revenue;
+       std::string genres;
+       std::string homepage;
+       std::string releaseDate;
+       int runtime;
+       float popularity;
+       float voteAverage;
+
+       TVMedia poster;
+       TVMedia fanart;
+       TVMedia collectionPoster;
+       TVMedia collectionFanart;
+       Actors actors;
+};
+
+
+#endif
index 5ecff896523cdfcaa80cc3c40c1e8846f6dab90a..e27f749c4fe95c24d7180a44f373a776f4ab8c4e 100644 (file)
@@ -24,5 +24,7 @@ OBJECTS1 = command.o  tcp.o dsock.o thread.o timers.o i18n.o       \
            imagereader.o  mediaoptions.o mediaplayer.o  \
            serialize.o localmediafile.o   playermedia.o \
            demuxermedia.o tfeed.o vteletextview.o teletextdecodervbiebu.o        \
-           teletxt/txtfont.o mediafile.o
+           teletxt/txtfont.o mediafile.o movieinfo.o seriesinfo.o wmovieview.o wseriesview.o tvmedia.o \
+           wpictureview.o
+           
 
diff --git a/osd.h b/osd.h
index 5b96e685d5eb8aeb307fcb9135a9d17f67478b5b..0f87900dcbaec93a8fc894d003755e92cc82b449 100644 (file)
--- a/osd.h
+++ b/osd.h
@@ -49,6 +49,8 @@ class Osd
     virtual int getFontNames(const char *** names,const char *** names_keys){ return 0;};
     virtual void setFont(const char * fontname){};
 
+    virtual float getPixelAspect() {return 1.f;};
+
   protected:
     static Osd* instance;
     int initted;
index d11c0d9392ee34b6f640e0c9c42f68bc8373c2b1..207063a473b5376361019b4bcdafb8ba69818356 100644 (file)
@@ -304,6 +304,12 @@ int OsdOpenVG::init(void* device)
   return 1;
 }
 
+void OsdOpenVG::getScreenSize(int &width, int &height)
+{
+       width=BACKBUFFER_WIDTH;
+       height=BACKBUFFER_HEIGHT;
+}
+
 
 void OsdOpenVG::initPaths()
 {
@@ -798,6 +804,8 @@ void OsdOpenVG::drawSetTrans(SurfaceCommands & sc)
        vgLoadIdentity();
        vgScale(((float)BACKBUFFER_WIDTH)/720.f, -((float)BACKBUFFER_HEIGHT)/576.f);
        vgTranslate(0.f+sc.x,-576.f+sc.y);
+    clip_shift_x=sc.x;
+    clip_shift_y=sc.y;
 
 
 
@@ -829,15 +837,14 @@ void OsdOpenVG::executeDrawCommand(SVGCommand & command)
        case DrawImage: {
            vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
                vgGetMatrix(save_matrix);
-               vgTranslate(command.x,command.y);
-
-
+               VGfloat imagewidth=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH);
+               VGfloat imageheight=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT);
 
 
                //vgScale(command.w,command.h);
-               VGfloat imagewidth=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH);
-               VGfloat imageheight=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT);
+
                if (command.reference) { //special behaviout for bw images they act as a mask on the current paint
+                       vgTranslate(command.x,command.y);
                        vgSetPaint((VGPaint) command.reference,VG_FILL_PATH);
                        vgSetPaint((VGPaint) command.reference,VG_STROKE_PATH);
                        vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_STENCIL);
@@ -851,6 +858,33 @@ void OsdOpenVG::executeDrawCommand(SVGCommand & command)
                        //vgScale(720.f/((float)BACKBUFFER_WIDTH), 576.f/((float)BACKBUFFER_HEIGHT));
                        float scalex=command.w/imagewidth;
                        float scaley=command.h/imageheight;
+                       if (scalex==0.f && scaley==0.f) {
+                               scalex=aspect_correction;
+                               scaley=1.f;
+                       } else if (scalex==0.f) {
+                               scalex=scaley*aspect_correction;
+                       } else if (scaley==0.f) {
+                               scaley=scalex/aspect_correction;
+                       }
+                       float tx=command.x;
+                       float ty=command.y;
+
+                       if (command.corner ==  BottomRight || command.corner ==  BottomLeft || command.corner == BottomMiddle)
+                       {
+                               ty-=imageheight * scaley;
+                       }
+
+                       if (command.corner ==  BottomRight || command.corner ==  TopRight)
+                       {
+                               tx-=imagewidth * scalex;
+                       }
+
+                       if (command.corner ==  BottomMiddle || command.corner ==  TopMiddle)
+                       {
+                               tx-=imagewidth * scalex *0.5f;
+                       }
+
+                       vgTranslate(tx,ty);
                        //vgScale(command.w/imagewidth,command.h/imageheight);
                        vgScale(scalex,scaley);
                        vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);
@@ -950,6 +984,17 @@ void OsdOpenVG::executeDrawCommand(SVGCommand & command)
                vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
 
        }break;
+       case DrawClipping: {
+               VGint coords[4]={0,0,0,0};
+               coords[0]= ((command.x+clip_shift_x)*((float)BACKBUFFER_WIDTH)/720.f);
+               coords[1]= ((576.f-command.y-clip_shift_y-command.h)*((float)BACKBUFFER_HEIGHT)/576.f);
+               coords[2]= ((command.w-1.f)*((float)BACKBUFFER_WIDTH)/720.f);
+               coords[3]= ((command.h-1.f)*((float)BACKBUFFER_HEIGHT)/576.f);
+               vgSetiv(VG_SCISSOR_RECTS, 4,coords);
+               if (command.w==0.f && command.h==0.f)
+                       vgSeti(VG_SCISSORING,VG_FALSE);
+               else vgSeti(VG_SCISSORING,VG_TRUE);
+       } break;
        }
 }
 
@@ -995,8 +1040,7 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command)
        } break;
        case OVGcreateMonoBitmap: {
                VGImage handle=vgCreateImage(VG_A_1,command.param1, command.param2,
-                                       VG_IMAGE_QUALITY_NONANTIALIASED|
-                                       VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);
+                                       VG_IMAGE_QUALITY_FASTER);
                //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create mono  %d %d %x %d",command.param1,command.param2,vgGetError(),handle);
                unsigned int buffer_len=(command.param1*command.param2)>>3;
                unsigned char * buffer=(unsigned char*)malloc(buffer_len);
@@ -1025,12 +1069,11 @@ unsigned int OsdOpenVG::handleTask(OpenVGCommand& command)
 
 
                        handle=vgCreateImage(VG_sXBGR_8888,imagefile->columns(),imagefile->rows(),
-                                       VG_IMAGE_QUALITY_NONANTIALIASED|
-                                       VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);
-               //      Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details  %d %d %x mark1",imagefile->columns(),imagefile->rows(),*(unsigned int*)imageblob.data());
+                                       VG_IMAGE_QUALITY_BETTER);
+                       //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details  %d %d %x mark1",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
                        vgImageSubData(handle,imageblob.data(),imagefile->columns()*4,
                                        VG_sXBGR_8888,0,0,imagefile->columns(),imagefile->rows());
-               //      Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details  %d %d %x mark2",imagefile->columns(),imagefile->rows(),*(unsigned int*)imageblob.data());
+                       //Log::getInstance()->log("OSD", Log::DEBUG, "Draw create image details  %d %d %x mark2",imagefile->columns(),imagefile->rows(),(unsigned int*)imageblob.data());
                        delete imagefile;
                }catch( Exception &error_ )
                {
@@ -1248,6 +1291,30 @@ ImageIndex OsdOpenVG::createJpeg(const char* fileName, int *width,int *height)
        return putOpenVGCommand(comm,true);
 }
 
+ImageIndex OsdOpenVG::createPicture(unsigned char *data, unsigned int length)
+{
+       Image* magicimage=NULL;
+       bool mem=false;
+       struct OpenVGCommand comm;
+       comm.task=OVGcreateImageFile;
+
+       try{
+               // Now figure out, if it is a special case
+               //Log::getInstance()->log("OSD", Log::DEBUG, "createPicture");
+               magicimage=new Image(Blob(data,length)); // fix me this is an unnecessary memcpy
+               free(data);
+       }catch( Exception &error_ )
+       {
+               Log::getInstance()->log("OSD", Log::DEBUG, "Libmagick: %s",error_.what());
+
+               return 0;
+       }
+       comm.data=magicimage;
+       return putOpenVGCommand(comm,true);
+}
+
+
+
 ImageIndex OsdOpenVG::createMonoBitmap(void *base,int width,int height)
 {
        struct OpenVGCommand comm;
index baf6c0c5831b4a495b178efc1e861c06df88d4d8..051e173ffd6958ac85dcceae20cec6247dcaa3b9 100644 (file)
@@ -90,6 +90,8 @@ class OsdOpenVG : public OsdVector, public Thread_TYPE
 
     virtual void setFont(const char * fontname);
 
+    virtual float getPixelAspect() {return aspect_correction;};
+
 
 protected:
    /*osd vector implementation*/
@@ -97,6 +99,7 @@ protected:
     ImageIndex createJpeg(const char* fileName, int *width,int *height);
     ImageIndex createMonoBitmap(void *base,int width,int height);
     ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data);
+    ImageIndex createPicture(unsigned char *data, unsigned int length);
     void destroyStyleRef(unsigned int index);
        unsigned int createStyleRef(const DrawStyle &c);
        unsigned int createColorRef(const Colour &c);
@@ -109,6 +112,7 @@ protected:
        VGPath std_paths[Point+1];
        long long  lastrendertime;
        void InternalRendering();
+       void getScreenSize(int &width, int &height);
 
 
 
@@ -136,6 +140,9 @@ protected:
     vector<char*> fontnames_keys;
     char * cur_fontname;
 
+    int clip_shift_x;
+    int clip_shift_y;
+
     unsigned int loadTTchar(cTeletextChar c);
     map<unsigned int,int> tt_font_chars;
 
index 457cd808d0d238e2543a67832ede0cae5cc61fb8..8012ff6bf435cecd4b6f08de76787bceed79c471 100644 (file)
 
 #include "osdvector.h"
 #include "surfacevector.h"
+#include "vdr.h"
+#include "vdrresponsepacket.h"
+#include "command.h"
+#include "message.h"
 
 OsdVector::OsdVector()
 {
        setlocale(LC_CTYPE,"C.UTF-8");
+       picture_update=true;
 }
 
 OsdVector::~OsdVector()
@@ -108,6 +113,8 @@ void OsdVector::drawSurfaces()
                }
                itty1++;
        }
+       int swidth,sheight;
+       getScreenSize(swidth,sheight);
        //Now go through all surfaces and draw them
        list<SurfaceCommands*>::iterator curdraw=todraw.begin();
        while (curdraw!=todraw.end()) {
@@ -115,7 +122,21 @@ void OsdVector::drawSurfaces()
                list<SVGCommand>::iterator commands=(*(*curdraw)).commands.begin();
                list<SVGCommand>::iterator end=(*(*curdraw)).commands.end();
                while (commands!=end) {
-                       executeDrawCommand(*commands);
+                       // update any images loaded in the mean time
+                       if ((*commands).instr==DrawImageLoading) {
+                               LoadIndex loadindex=(*commands).target.loadindex;
+                               if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
+                                       (*commands).instr=DrawImage;
+                                       (*commands).target.image=tvmedias_loaded[loadindex];;
+                                       incImageRef((*commands).target.image);
+                                       removeLoadIndexRef(loadindex);
+                               }
+
+                       }
+                       // Now check if the command is on screen!
+                       if  (!(*commands).Outside(0,0,swidth,sheight)) {
+                               executeDrawCommand(*commands);
+                       }
                        commands++;
                }
                curdraw++;
@@ -124,7 +145,6 @@ void OsdVector::drawSurfaces()
        surfaces_mutex.Unlock();
 }
 
-
 void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,float height,float width,
                        list<SVGCommand>& commands)
 {
@@ -149,6 +169,25 @@ void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,flo
                new_sc.h=height;
                itty=scommands.insert(itty,new_sc);
        }
+       // update any images loaded in the mean time
+       list<SVGCommand>::iterator ilitty=commands.begin();
+
+       while (ilitty!=commands.end())
+       {
+               if ((*ilitty).instr==DrawImageLoading) {
+                       LoadIndex loadindex=(*ilitty).target.loadindex;
+                       if (tvmedias_loaded.find(loadindex)!=tvmedias_loaded.end()) {
+
+                               (*ilitty).instr=DrawImage;
+                               (*ilitty).target.image=tvmedias_loaded[loadindex];
+                               incImageRef((*ilitty).target.image);
+                               removeLoadIndexRef(loadindex);
+                       }
+               }
+               ilitty++;
+       }
+
+
        // then clear and copy
        (*itty).commands.clear();
        (*itty).commands=commands;
@@ -159,6 +198,8 @@ void OsdVector::updateOrAddSurface(const SurfaceVector *surf,float x,float y,flo
                incStyleRef((*sitty).getRef());
                ImageIndex ii=(*sitty).getImageIndex();
                if (ii) incImageRef(ii);
+               LoadIndex li=(*sitty).getLoadIndex();
+               if (li) incLoadIndexRef(li);
                sitty++;
        }
        cleanupOrphanedRefs();
@@ -192,6 +233,8 @@ void OsdVector::dereferenceSVGCommand(list<SVGCommand>& commands )
                removeStyleRef((*sitty).getRef());
                ImageIndex ii = (*sitty).getImageIndex();
                if (ii) removeImageRef(ii);
+               LoadIndex li=(*sitty).getLoadIndex();
+               if (li) removeLoadIndexRef(li);
                sitty++;
        }
 }
@@ -204,10 +247,13 @@ void OsdVector::referenceSVGCommand(list<SVGCommand>& commands )
                incStyleRef((*sitty).getRef());
                ImageIndex ii=(*sitty).getImageIndex();
                if (ii) incImageRef(ii);
+               LoadIndex li=(*sitty).getLoadIndex();
+               if (li) incLoadIndexRef(li);
                sitty++;
        }
 }
 
+
 void OsdVector::incImageRef(ImageIndex index)
 {
        if (images_ref.find(index)==images_ref.end()) {
@@ -222,6 +268,39 @@ void OsdVector::removeImageRef(const ImageIndex ref)
        images_ref[ref]--;
 }
 
+unsigned int OsdVector::getLoadIndexRef(LoadIndex index)
+{
+       if (loadindex_ref.find(index)==loadindex_ref.end()) {
+               return -1;
+       } else {
+               return loadindex_ref[index];
+       }
+}
+
+void OsdVector::incLoadIndexRef(LoadIndex index)
+{
+       if (loadindex_ref.find(index)==loadindex_ref.end()) {
+               loadindex_ref[index]=1;
+       } else {
+               loadindex_ref[index]++;
+       }
+}
+
+void OsdVector::removeLoadIndexRef(const LoadIndex ref)
+{
+       loadindex_ref[ref]--;
+       if (loadindex_ref[ref]==0) {
+               //now check, if it is already loaded
+               map<LoadIndex,ImageIndex>::iterator itty=tvmedias_loaded.find(ref);
+               if ( itty != tvmedias_loaded.end()) {
+                       removeImageRef((*itty).second); // remove lock
+               }
+               tvmedias_loaded.erase(ref);
+               tvmedias_load.erase(tvmedias_load_inv[ref]);
+               tvmedias_load_inv.erase(ref);
+       }
+}
+
 void OsdVector::cleanupOrphanedRefs()
 { // Do some garbage collection
 
@@ -249,6 +328,20 @@ void OsdVector::cleanupOrphanedRefs()
                } else ++jitty;
        }
 
+       map<TVMediaInfo,ImageIndex>::iterator titty=tvmedias.begin();
+       while (titty!=tvmedias.end()) {
+               map<ImageIndex,unsigned int>::iterator curitty=images_ref.find((*titty).second);
+               int count=(*curitty).second;
+               if (count==0) {
+
+                       Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia destroy Picture");
+                       ImageIndex ref=(*curitty).first;
+                       tvmedias.erase(titty++);
+                       images_ref.erase(curitty++);
+                       destroyImageRef(ref);
+               } else ++titty;
+       }
+
 
        map<pair<Colour*,unsigned int>,unsigned int>::iterator sitty=styles.begin();
        while (sitty!=styles.end()) {
@@ -333,6 +426,68 @@ unsigned int OsdVector::getStyleRef(unsigned int index)
        }
 }
 
+LoadIndex OsdVector::getTVMediaRef(TVMediaInfo& tvmedia, ImageIndex& image)
+{
+       ImageIndex image_handle=0;
+       LoadIndex loadindex=0;
+       if (tvmedias.find(tvmedia)==tvmedias.end())
+       {
+               loadindex=loadTVMedia(tvmedia);
+       } else {
+               image_handle=tvmedias[tvmedia];
+               if (images_ref.find(image_handle)==images_ref.end()) {
+                       //invalid handle recreate
+                       loadindex=loadTVMedia(tvmedia);
+                       image_handle=0;
+               } else {
+                       incImageRef(image_handle);
+               }
+       }
+       /*tvmedias[tvmedia]=createTVMedia(tvmedia,width,height);
+       incImageRef(image_handle);*/
+       image=image_handle;
+       return loadindex;
+}
+
+LoadIndex OsdVector::loadTVMedia(TVMediaInfo& tvmedia)
+{
+       LoadIndex index=0;
+       if (tvmedias_load.find(tvmedia)==tvmedias_load.end())
+       {
+               index=VDR::getInstance()->loadTVMedia(tvmedia);
+               tvmedias_load[tvmedia]=index;
+               tvmedias_load_inv[index]=tvmedia;
+       } else {
+               index=tvmedias_load[tvmedia];
+       }
+
+       incLoadIndexRef(index);
+
+       return index;
+}
+
+void OsdVector::setTVMedia(LoadIndex index, unsigned char * buffer, unsigned int length)
+{
+       //Beware for thread safety
+       ImageIndex image_index=0;
+
+       TVMediaInfo tvmedia=tvmedias_load_inv[index];
+         Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Picture for request id %d arrived",index);
+       if (buffer) {
+               if (getLoadIndexRef(index)<1) {
+                       // we do not want the picture anymore . Really...
+               } else {
+                       image_index=tvmedias[tvmedia]=createPicture(buffer,length);
+                       tvmedias_loaded[index]=image_index;
+                       incImageRef(image_index); // hold one index until all loadings refs are gone;
+               }
+       }
+
+
+}
+
+
+
 ImageIndex OsdVector::getJpegRef(const char* fileName, int *width,int *height)
 {
        ImageIndex image_handle=0;
@@ -376,3 +531,56 @@ ImageIndex  OsdVector::getImagePalette(int width,int height,const unsigned char
        incImageRef(image_handle);
        return image_handle;
 }
+
+void OsdVector::receivePicture(VDR_ResponsePacket *vresp)
+{
+       pict_lock_incoming.Lock();
+       pict_incoming.push(vresp);
+       pict_lock_incoming.Unlock();
+       //Log::getInstance()->log("OsdVector", Log::DEBUG, "TVMedia Pictures arrived");
+       if (picture_update) {
+               Message* m = new  Message();
+               // This is incoming from VDR, we do not want to block gui so send a message to ourself to switch to gui thread
+               m->message=Message::PICTURES_ARRIVED;
+               m->from=this;
+               m->to=Command::getInstance();
+               picture_update=false;
+               Command::getInstance()->postMessageFromOuterSpace(m); // inform command about new picture
+       }
+}
+
+bool OsdVector::processReceivedPictures()
+{
+       bool ret=false;
+       pict_lock_incoming.Lock();
+       int i=0;
+    long long time1 = getTimeMS();
+    long long cur_time =time1;
+       while (pict_incoming.size() && (time1-cur_time)<100) {
+               VDR_ResponsePacket *vresp=pict_incoming.front();
+               pict_incoming.pop();
+               pict_lock_incoming.Unlock();
+               if (vresp->getFlag() != 2) {
+                       setTVMedia(vresp->getStreamID(), vresp->getUserData(),  vresp->getUserDataLength());
+                       ret=true;
+               }
+               else  setTVMedia(vresp->getStreamID(), NULL,  0);
+               delete vresp;
+               cur_time = getTimeMS();
+               pict_lock_incoming.Lock();
+       }
+       if (pict_incoming.size()==0) picture_update=true;
+       pict_lock_incoming.Unlock();
+
+
+       if (!picture_update) {
+               Message* m = new  Message();
+               // We have remaing pictures! send a message to ourself to switch to gui thread
+               m->message=Message::PICTURES_ARRIVED;
+               m->from=this;
+               m->to=Command::getInstance();
+               picture_update=false;
+               Command::getInstance()->postMessageNoLock(m); // inform command about new picture
+       }
+       return ret;
+}
index b9474f17cdbc7fdde94569e6c320c66d224883bd..6221ae53688a11812fcb40eced0fa677c16961f2 100644 (file)
 #include "colour.h"
 #include <list>
 #include <map>
+#include <queue>
 #include <string>
+#include "tvmedia.h"
+#include "vdr.h"
 
 #include "teletextdecodervbiebu.h"
 
 enum SVGCommandInstr {
+       DrawNoop,
        DrawPath,
        DrawGlyph,
        DrawImage,
-       DrawTTchar
+       DrawTTchar,
+       DrawClipping,
+       DrawImageLoading
 };
 enum PathIndex {
        HorzLine,
@@ -42,50 +48,108 @@ enum PathIndex {
        Point
 };
 
+enum Corner{
+       TopLeft,
+       TopRight,
+       BottomLeft,
+       BottomRight,
+       TopMiddle,
+       BottomMiddle
+};
+
 typedef  unsigned int ImageIndex;
+typedef unsigned int LoadIndex;
 
 class SVGCommand
 {
 public:
-       SVGCommand(float ix, float iy,float iw,float ih,PathIndex path,unsigned int ref)
+       SVGCommand()
+    {
+               instr=DrawNoop;
+               x=y=w=h=reference=0;
+    };
+
+       static SVGCommand PaintPath(float ix, float iy,float iw,float ih,PathIndex path,unsigned int ref)
+       {
+               SVGCommand nc;
+               nc.instr=DrawPath;
+               nc.x=ix;
+               nc.y=iy;
+               nc.w=iw;
+               nc.h=ih;
+               nc.target.path_index=path;
+               nc.reference=ref;
+               return nc;
+       };
+
+       static SVGCommand PaintImageLoading(LoadIndex load_in,float ix, float iy,float iw,float ih,unsigned int ref, Corner corner=TopLeft)
+       {
+               SVGCommand nc;
+               nc.instr=DrawImageLoading;
+               nc.x=ix;
+               nc.y=iy;
+               nc.w=iw;
+               nc.h=ih;
+               nc.target.loadindex=load_in;
+               nc.reference=ref;
+               nc.corner=corner;
+               return nc;
+       };
+
+       static SVGCommand PaintImage(float ix, float iy,float iw,float ih,ImageIndex image_in,unsigned int ref, Corner corner=TopLeft)
        {
-               instr=DrawPath;
-               x=ix;
-               y=iy;
-               w=iw;
-               h=ih;
-               target.path_index=path;
-               reference=ref;
+               SVGCommand nc;
+               nc.instr=DrawImage;
+               nc.x=ix;
+               nc.y=iy;
+               nc.w=iw;
+               nc.h=ih;
+               nc.target.image=image_in;
+               nc.reference=ref;
+               nc.corner=corner;
+               return nc;
        };
-       SVGCommand(float ix, float iy,float iw,float ih,ImageIndex image_in,unsigned int ref)
+
+
+
+       static SVGCommand PaintTTchar(float ix, float iy,float iw,float ih,unsigned int ttchar_in)
        {
-               instr=DrawImage;
-               x=ix;
-               y=iy;
-               w=iw;
-               h=ih;
-               target.image=image_in;
-               reference=ref;
+               SVGCommand nc;
+               nc.instr=DrawTTchar;
+               nc.x=ix;
+               nc.y=iy;
+               nc.w=iw;
+               nc.h=ih;
+               nc.reference=0;
+               nc.target.ttchar=ttchar_in;
+               nc.corner=TopLeft;
+               return nc;
        };
-       SVGCommand(float ix, float iy,float iw,float ih,unsigned int ttchar_in)
+       static SVGCommand PaintClipping(float ix, float iy,float iw,float ih)
        {
-               instr=DrawTTchar;
-               x=ix;
-               y=iy;
-               w=iw;
-               h=ih;
-               reference=0;
-               target.ttchar=ttchar_in;
+               SVGCommand nc;
+               nc.instr=DrawClipping;
+               nc.x=ix;
+               nc.y=iy;
+               nc.w=iw;
+               nc.h=ih;
+               nc.reference=0;
+               nc.target.ttchar=0;
+               return nc;
        };
-       SVGCommand(float ix, float iy,wchar_t char_in,unsigned int ref)
+
+
+       static SVGCommand PaintGlyph(float ix, float iy,wchar_t char_in,unsigned int ref)
        {
-               instr=DrawGlyph;
-               x=ix;
-               y=iy;
-               w=0;
-               h=0;
-               reference=ref;
-               target.textchar=char_in;
+               SVGCommand nc;
+               nc.instr=DrawGlyph;
+               nc.x=ix;
+               nc.y=iy;
+               nc.w=0;
+               nc.h=0;
+               nc.reference=ref;
+               nc.target.textchar=char_in;
+               return nc;
        };
 
        bool Test(float tx,float ty,float tw, float th)
@@ -96,11 +160,21 @@ public:
        {
                return (x==tox) && (toy==y) && (w==tx) && (h==ty);
        }
+       bool Outside(float tx,float ty,float tw, float th)
+       {
+               return ((x+w)<tx) || ((y+h)<ty) || ((tx+tw) < x) || ((ty+th) < y);
+       }
+
        unsigned int getRef(){return reference;};
        ImageIndex getImageIndex() {
                if (instr!=DrawImage) return 0;
                else return target.image;
        };
+       ImageIndex getLoadIndex() {
+               if (instr!=DrawImageLoading) return 0;
+               else return target.loadindex;
+       };
+
        SVGCommandInstr instr;
        float x,y,w,h;
        unsigned int reference;
@@ -109,10 +183,14 @@ public:
                wchar_t textchar;
                ImageIndex image;
                unsigned int ttchar;
+               LoadIndex loadindex;
        } target;
+       Corner corner;
+
 };
 
 class SurfaceVector;
+class VDR_ResponsePacket;
 
 struct SurfaceCommands{
        const SurfaceVector* surf;
@@ -148,13 +226,21 @@ class OsdVector : public Osd
        virtual float getCharWidth(wchar_t c)=0;
 
        virtual ImageIndex getJpegRef(const char* fileName, int *width,int *height);
+       virtual LoadIndex getTVMediaRef(TVMediaInfo& tvmedia,ImageIndex& image);
        virtual ImageIndex getMonoBitmapRef(void *base,int width,int height);
        virtual ImageIndex getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data);
        virtual void imageUploadLine(ImageIndex index,unsigned int j,unsigned int width,void *data)=0;
        void removeImageRef(const ImageIndex ref);
+       void removeLoadIndexRef(const LoadIndex ref);
        unsigned int getColorRef(const Colour &c); //internally this is the same as getStyleRef
        unsigned int getStyleRef(const DrawStyle &c);
        virtual void removeStyleRef(unsigned int ref);
+       virtual void getScreenSize(int &width, int &height)=0;
+
+       // should be called from command thread
+       bool processReceivedPictures();
+
+       void receivePicture(VDR_ResponsePacket *vresp);
 
 
     int charSet() {return 2;}; //UTF-8
@@ -166,13 +252,36 @@ protected:
        void incImageRef(ImageIndex index);
        unsigned int getImageRef(ImageIndex index);
        virtual void destroyImageRef(ImageIndex index)=0;
+       void incLoadIndexRef(LoadIndex index);
+       unsigned int getLoadIndexRef(LoadIndex index);
+
+
        virtual ImageIndex createJpeg(const char* fileName, int *width,int *height)=0;
        virtual ImageIndex createMonoBitmap(void *base,int width,int height)=0;
        virtual ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)=0;
+       virtual ImageIndex createPicture(unsigned char *data, unsigned int length)=0;
+
+       virtual LoadIndex loadTVMedia(TVMediaInfo& tvmedia);
+
+
 
        map<ImageIndex,unsigned int> images_ref;
        map<void *,ImageIndex> monobitmaps;
        map<string,ImageIndex> jpegs;
+       map<TVMediaInfo,ImageIndex> tvmedias;
+
+
+
+       void setTVMedia(LoadIndex index, unsigned char * buffer, unsigned int length);
+       Mutex pict_lock_incoming; //locks
+       std::queue<VDR_ResponsePacket*> pict_incoming;
+       bool picture_update;
+
+
+       map<LoadIndex,unsigned int> loadindex_ref;
+       map<TVMediaInfo,LoadIndex> tvmedias_load;
+       map<LoadIndex,TVMediaInfo> tvmedias_load_inv;
+       map<LoadIndex,ImageIndex> tvmedias_loaded;
 
        void incStyleRef(unsigned int index);
        unsigned int getStyleRef(ImageIndex index);
index 92cb205f8b0445b1df47d3bd01b128658950dce8..66ff677761b22f34b45e486fb00249c062a7aa31 100644 (file)
@@ -33,6 +33,8 @@ RecInfo::RecInfo()
   types = NULL;
   languages = NULL;
   descriptions = NULL;
+
+  title = NULL;
 }
 
 RecInfo::~RecInfo()
@@ -58,6 +60,8 @@ RecInfo::~RecInfo()
     delete[] types;
   }
 
+  if (title) delete [] title;
+
   timerStart = 0;
   timerEnd = 0;
   resumePoint = 0;
index 260bd5f8e41701a90957123cf2b431967e0474d8..27844d478c336072be46743507b480fff8dc2a81 100644 (file)
--- a/recinfo.h
+++ b/recinfo.h
@@ -44,6 +44,8 @@ class RecInfo
     char** languages;
     char** descriptions;
 
+    char *title;
+
     void setNumComponents(ULONG);
     void addComponent(ULONG componentNum, UCHAR tstream, UCHAR ttype, char* tlanguage, char* tdescription);
     // addComponent accepts a pointer to a buffer that RecInfo will free, not the caller
index d173cae2af7d8145d25e8e1e182cd7d8967027ff..5bec001e62fed94dbe14f6434f1baccaba7bfb5f 100644 (file)
 #include "demuxer.h"
 #include "demuxerts.h"
 #include "command.h"
+#include "seriesinfo.h"
+#include "movieinfo.h"
 
 Recording* Recording::recInfoFor = NULL;
 RecInfo* Recording::recInfo = NULL;
+MovieInfo* Recording::movieInfo = NULL;
+SeriesInfo* Recording::seriesInfo = NULL;
 
 Recording::Recording()
 {
@@ -41,6 +45,9 @@ Recording::Recording()
   fileName = NULL;
   index = -1;
   markList = NULL;
+  movieID = 0;
+  seriesID = 0;
+  episodeID = 0;
 }
 
 Recording::~Recording()
@@ -112,7 +119,34 @@ void Recording::loadRecInfo()
   recInfo = vdr->getRecInfo(fileName);
   Log::getInstance()->log("Recording", Log::DEBUG, "Recording has loaded recInfo %p", recInfo);
   
-  if (!VDR::getInstance()->isConnected()) Command::getInstance()->connectionLost();
+  if (!vdr->isConnected()) Command::getInstance()->connectionLost();
+
+  if (movieInfo) delete movieInfo;
+  if (seriesInfo) delete seriesInfo;
+
+  movieInfo = NULL;
+  seriesInfo = NULL;
+
+  vdr->getScraperEventType(fileName, movieID, seriesID, episodeID);
+  Log::getInstance()->log("Recording", Log::DEBUG, "Got Scraper EventType %d %d %d",
+                 movieID, seriesID, episodeID);
+
+  if (!vdr->isConnected()) Command::getInstance()->connectionLost();
+
+  if (movieID != 0)
+  {
+         movieInfo = vdr->getScraperMovieInfo(movieID);
+         Log::getInstance()->log("Recording", Log::DEBUG, "Got Scraper MovieInfo ");
+  }
+  else if (seriesID != 0)
+  {
+         seriesInfo = vdr->getScraperSeriesInfo(seriesID, episodeID);
+         Log::getInstance()->log("Recording", Log::DEBUG, "Got Scraper SeriesInfo ");
+  }
+
+
+  if (!vdr->isConnected()) Command::getInstance()->connectionLost();
+
 }
 
 void Recording::dropRecInfo()
@@ -120,6 +154,11 @@ void Recording::dropRecInfo()
   if (recInfo) delete recInfo;
   recInfo = NULL;
   recInfoFor = NULL;
+  if (movieInfo) delete movieInfo;
+  if (seriesInfo) delete seriesInfo;
+
+  movieInfo = NULL;
+  seriesInfo = NULL;
 }
 
 void Recording::loadMarks()
index be7273461bfb1ef074d7e6a778e616e0c4bc87d4..745d7a0a7a99fc8954ff3ca743b5ec39b32c428d 100644 (file)
@@ -58,7 +58,13 @@ class Recording
     bool hasMarks();
     MarkList* getMarkList();
 
+   int movieID;
+   int seriesID;
+   int episodeID;
+
     static RecInfo* recInfo;
+    static MovieInfo* movieInfo;
+    static SeriesInfo* seriesInfo;
 
   private:
     Log* logger;
@@ -74,6 +80,7 @@ class Recording
     // else delete recInfo and reload for this recording
     static Recording* recInfoFor;
 
+
     MarkList* markList;
 };
 
diff --git a/seriesinfo.cc b/seriesinfo.cc
new file mode 100644 (file)
index 0000000..cd866d5
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "seriesinfo.h"
+
+
+EpisodeInfo::EpisodeInfo() {
+       name="";
+       firstAired="";
+       guestStars="";
+       overview="";
+
+       rating=0.;
+       season=0;
+       episodeid=0;
+       number=0;
+}
+
+EpisodeInfo::~EpisodeInfo() {
+
+}
+
+SeriesInfo::SeriesInfo()
+{
+       id=0;
+
+
+
+}
+
+
+
diff --git a/seriesinfo.h b/seriesinfo.h
new file mode 100644 (file)
index 0000000..adea749
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef SERIESINFO_H
+#define SERIESINFO_H
+
+#include "tvmedia.h"
+#include <string>
+
+class EpisodeInfo {
+public:
+       EpisodeInfo();
+       ~EpisodeInfo();
+
+       int episodeid;
+       int number;
+       int season;
+       std::string name;
+       std::string firstAired;
+       std::string guestStars;
+       std::string overview;
+       float rating ;
+       TVMedia image;
+
+
+};
+
+class SeriesInfo {
+public:
+       SeriesInfo();
+
+       int id;
+
+
+       std::string name;
+       std::string overview;
+       std::string firstAired;
+       std::string network;
+       std::string genre;
+       double rating;
+       std::string status;
+       EpisodeInfo episode; // Image 0
+
+
+
+
+       Actors actors; // Image 1
+       TVMedias posters; // Image 2
+       TVMedias banners; // Image 3
+       TVMedias fanart; // Image 4
+       TVMedia seasonposter; // Image 5
+};
+#endif
index fa9659f6f028a5f583e9646e84c4829adbb064c2..dff343299ba721c9b3a10130b42682922ade1cde 100644 (file)
@@ -37,7 +37,11 @@ SurfaceVector::~SurfaceVector()
        {
                osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
                ImageIndex ii=(*itty).getImageIndex();
-               if (ii) osd->removeImageRef(ii);
+               if (ii) {
+                       osd->removeImageRef(ii);
+               }
+               LoadIndex li=(*itty).getLoadIndex();
+               if (li) osd->removeLoadIndexRef(li);
                itty++;
        }
 }
@@ -98,7 +102,7 @@ int SurfaceVector::drawText(const char* text, int x, int y, int width, const Dra
        while (num_bytes!=((size_t) -1) && num_bytes!=((size_t) -2) && length>0)
        {
                unsigned int ref=osd->getStyleRef(c);
-               commands.push_back(SVGCommand(x+shift,y,*tempo,ref));
+               commands.push_back(SVGCommand::PaintGlyph(x+shift,y,*tempo,ref));
                shift+=osd->getCharWidth(*tempo);
                length -= num_bytes;
                run += num_bytes;
@@ -158,7 +162,30 @@ void SurfaceVector::drawJpeg(const char *fileName,int x, int y,int *width, int *
 {
        command_mutex.Lock();
        ImageIndex image=osd->getJpegRef(fileName,width,height);
-       commands.push_back(SVGCommand(x,y,*width,*height,image,0));
+       commands.push_back(SVGCommand::PaintImage(x,y,*width,*height,image,0));
+       command_mutex.Unlock();
+}
+
+void SurfaceVector::drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float  width, float height, Corner corner)
+{
+       command_mutex.Lock();
+       ImageIndex image=0;
+       LoadIndex load_index=osd->getTVMediaRef(tvmedia,image);
+       if (image) {
+               //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image %d %d", load_index,image);
+               commands.push_back(SVGCommand::PaintImage(x,y,width,height,image,0,corner));
+       } else {
+
+               commands.push_back(SVGCommand::PaintImageLoading(load_index,x,y,width,height,0,corner));
+               //Log::getInstance()->log("SurfaceVector", Log::DEBUG, "TVMedia Add instru image loading %d %d", load_index,image);
+       }
+       command_mutex.Unlock();
+}
+
+void SurfaceVector::drawClippingRectangle(float x, float y, float w, float h)
+{
+       command_mutex.Lock();
+       commands.push_back(SVGCommand::PaintClipping((float)x,(float)y,(float)w,(float)h));
        command_mutex.Unlock();
 }
 
@@ -178,7 +205,7 @@ int SurfaceVector::fillblt(int x, int y, int width, int height, const DrawStyle&
        command_mutex.Lock();
        removeCommands(x,y,width,height); // remove commands below the box
        unsigned int ref=osd->getStyleRef(c);
-       commands.push_back(SVGCommand(x,y,width,height,Rectangle,ref));
+       commands.push_back(SVGCommand::PaintPath(x,y,width,height,Rectangle,ref));
        command_mutex.Unlock();
        return 1;
 
@@ -187,14 +214,14 @@ void SurfaceVector::drawHorzLine(int x1, int x2, int y, const DrawStyle& c)
 {
        command_mutex.Lock();
        unsigned int ref=osd->getStyleRef(c);
-       commands.push_back(SVGCommand(x1,y,x2-x1,1,HorzLine,ref));
+       commands.push_back(SVGCommand::PaintPath(x1,y,x2-x1,1,HorzLine,ref));
        command_mutex.Unlock();
 }
 
 void SurfaceVector::drawVertLine(int x, int y1, int y2, const DrawStyle& c){
        command_mutex.Lock();
        unsigned int ref=osd->getStyleRef(c);
-       commands.push_back(SVGCommand(x,y1,1,y2-y1,VertLine,ref));
+       commands.push_back(SVGCommand::PaintPath(x,y1,1,y2-y1,VertLine,ref));
        command_mutex.Unlock();
 }
 
@@ -224,7 +251,7 @@ void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegio
        ty*=scaley;
        tw*=scalex;
        th*=scaley;
-       SVGCommand temp=SVGCommand(tx,ty,tw,th,image,0);
+       SVGCommand temp=SVGCommand::PaintImage(tx,ty,tw,th,image,0);
        commands.push_back(temp);
        command_mutex.Unlock();
 }
@@ -232,7 +259,7 @@ void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegio
 void SurfaceVector::drawPoint(int x, int y, DrawStyle& c, bool fastdraw){
        if (!fastdraw) command_mutex.Lock();
        unsigned int ref=osd->getStyleRef(c);
-       commands.push_back(SVGCommand(x,y,1,1,Point,ref));
+       commands.push_back(SVGCommand::PaintPath(x,y,1,1,Point,ref));
        if (!fastdraw)  command_mutex.Unlock();
 }
 void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, DrawStyle& nextColour)
@@ -240,7 +267,7 @@ void SurfaceVector::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int hei
        command_mutex.Lock();
        ImageIndex image=osd->getMonoBitmapRef(base,width,height);
        unsigned int ref=osd->getStyleRef(nextColour);
-       commands.push_back(SVGCommand(dx,dy,height,width,image,ref));
+       commands.push_back(SVGCommand::PaintImage(dx,dy,height,width,image,ref));
        command_mutex.Unlock();
 }
 
@@ -251,10 +278,12 @@ int SurfaceVector::removeCommands(float x,float y,float width,float height)
        list<SVGCommand>::iterator itty=commands.begin();
        while (itty!=commands.end())
        {
-               if ((*itty).Test(x,y,width,height) ) {
+               if ((*itty).Test(x,y,width,height)  && (*itty).instr != DrawClipping) {
                        osd->removeStyleRef((*itty).getRef()); // We remove the Style reference, so that osd can free stuff
                        ImageIndex ii=(*itty).getImageIndex();
                        if (ii) osd->removeImageRef(ii);
+                       LoadIndex li=(*itty).getLoadIndex();
+                       if (li) osd->removeLoadIndexRef(li);
                        itty=commands.erase(itty);
                } else {
                        itty++;
@@ -296,6 +325,6 @@ void SurfaceVector::drawTTChar(int ox, int oy,int x, int y, cTeletextChar c)
                        itty++;
                }
        }
-       commands.push_back(SVGCommand(ox,oy,x,y,c.getInternal()));
+       commands.push_back(SVGCommand::PaintTTchar(ox,oy,x,y,c.getInternal()));
        command_mutex.Unlock();
 }
index 519abcd18a231e9f528cf8501118213f22560b40..fb31b17b9ccd63d871665bc6989927a775507769 100644 (file)
@@ -43,6 +43,11 @@ class SurfaceVector : public Surface
     int drawTextCentre(const char* text, int x, int y, const DrawStyle& c);
 
     void drawJpeg(const char *fileName,int x, int y,int *width, int *height);
+    // set width and height to zero, if the original size is wanted, if one index is non zero,
+    // the images is scaled with correct aspect ratio, if both are non zero both are scaled
+    void drawTVMedia(TVMediaInfo & tvmedia,float x, float y, float  width, float height, Corner corner=TopLeft);
+    // set w and h to 0, for unsetting clipping, use correct x and y parameter so that cleanup of commands works
+    void drawClippingRectangle(float x, float y, float w, float h);
 
     int create(UINT width, UINT height);
     void display();
diff --git a/tvmedia.cc b/tvmedia.cc
new file mode 100644 (file)
index 0000000..8460b56
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "tvmedia.h"
+#include "movieinfo.h"
+#include "seriesinfo.h"
+
+
+TVMediaInfo::TVMediaInfo()
+{
+       type=2; // movie or series
+       primary_id=0; //movie or series_id
+       secondary_id=0;  //0 or episode id
+       type_pict=-1; // 0 full info, 1 poster, 2 poster banner, 3 poster thumb
+       container=-1; // indices the dataelements with picture in movieinfo or seriesinfo
+       container_member=-1; // index into the container
+}
+
+
+
+TVMediaInfo::TVMediaInfo(const TVMediaInfo& info)
+{
+       type=info.type; // movie or series
+       primary_id=info.primary_id; //movie or series_id
+       secondary_id=info.secondary_id;  //0 or episode id
+       type_pict=info.type_pict; // 0 full info, 1 poster, 2 poster banner, 3 poster thumb
+       container=info.container; // indices the dataelements with picture in movieinfo or seriesinfo
+       container_member=info.container_member; // index into the container
+
+}
+
+void TVMediaInfo::setMovieInfo(const MovieInfo * mi)
+{
+       type=1; // movie or series
+       primary_id=mi->id; //movie or series_id
+       secondary_id=0;  //0 or episode id
+}
+
+void TVMediaInfo::setSeriesInfo(const SeriesInfo *  si)
+{
+       type=0; // movie or series
+       primary_id=si->id; //movie or series_id
+       secondary_id=si->episode.episodeid;  //0 or episode id
+}
+
+bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs)
+{
+       if (rhs.type==lhs.type) {
+               if (rhs.primary_id==lhs.primary_id) {
+                       if (rhs.secondary_id==lhs.secondary_id) {
+                               if (rhs.type_pict==lhs.type_pict) {
+                                       if (rhs.container==lhs.container) {
+                                               return rhs.container_member<lhs.container_member;
+                                       } else {
+                                               return rhs.container<lhs.container;
+                                       }
+
+
+                               } else {
+                                       return rhs.type_pict<lhs.type_pict;
+                               }
+
+                       } else {
+                               return rhs.secondary_id<lhs.secondary_id;
+                       }
+
+               } else {
+                       return rhs.primary_id<lhs.primary_id;
+               }
+
+       } else {
+               return rhs.type < lhs.type;
+       }
+}
diff --git a/tvmedia.h b/tvmedia.h
new file mode 100644 (file)
index 0000000..714f30e
--- /dev/null
+++ b/tvmedia.h
@@ -0,0 +1,76 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef TVMEDIA_H
+#define TVMEDIA_H
+
+#include "defines.h"
+#include <vector>
+#include <string>
+
+class MovieInfo;
+class SeriesInfo;
+
+class TVMediaInfo
+{
+friend class VDR;
+public:
+       TVMediaInfo();
+       TVMediaInfo(const TVMediaInfo& info);
+
+       friend bool operator<(const TVMediaInfo& rhs, const TVMediaInfo& lhs);
+
+       void setSeasonThumb() { type_pict=2; container=0; container_member=0;};
+       void setPosterThumb() { type_pict=1; container=0; container_member=0;};
+       void setElement(int cont,int memb) { type_pict=0; container=cont; container_member=memb;};
+       void setMovieInfo(const MovieInfo * mi);
+       void setSeriesInfo(const SeriesInfo * si);
+
+private:
+       int type; // movie or series
+       int primary_id; //movie or series_id
+       int secondary_id;  //0 or episode id
+       int type_pict; // 0 full info, 1 poster thumb, 2 season thumb
+       int container; // indices the dataelements with picture in movieinfo or seriesinfo
+       int container_member; // index into the container
+};
+
+struct TVMedia
+{
+       unsigned int width;
+       unsigned int height;
+
+       // no filename, file handling is only on the server
+       TVMediaInfo info;
+
+};
+
+typedef std::vector<TVMedia> TVMedias;
+
+struct Actor
+{
+       std::string name;
+       std::string role;
+       TVMedia thumb;
+};
+
+typedef std::vector<Actor> Actors;
+
+#endif
index e9236655c8fe1ed5211e3ae70f7270f69246a290..7755073b0efe3c4ea3a0f918d43bf2df62504c01 100644 (file)
@@ -162,15 +162,15 @@ void VConnect::threadMethod()
     if (success)
     {
       logger->log("VConnect", Log::DEBUG, "Connected ok, doing login");
-      unsigned int version_server,version_client;
-      success = vdr->doLogin(&version_server,&version_client);
+      unsigned int version_server_min,version_server_max,version_client;
+      success = vdr->doLogin(&version_server_min,&version_server_max,&version_client);
 
       if (!success)
       {
         vdr->disconnect();
-        if (version_server!=version_client) {
+        if (version_server_min >version_client || version_client > version_server_max) {
                char buffer[1024];
-               sprintf(buffer,"Protocoll mismatch s: %x c: %x",version_server,version_client);
+               sprintf(buffer,"Protocol mismatch s min: %x s max: %x c: %x",version_server_min,version_server_max,version_client);
                setOneLiner(buffer);
         } else {
                setOneLiner(tr("Login failed"));
diff --git a/vdr.cc b/vdr.cc
index bb2d4d3fbf002af0be75076df77f36496370785b..e8d70435596f86f816c25db4767d7bc6b4d33a11 100644 (file)
--- a/vdr.cc
+++ b/vdr.cc
 #include "vdrcommand.h"
 #include "video.h"
 #include "osd.h"
+#include "movieinfo.h"
+#include "seriesinfo.h"
 
-#define VOMP_PROTOCOLL_VERSION 0x00000301
+
+#define VOMP_PROTOCOLL_VERSION 0x00000302
 
 VDR* VDR::instance = NULL;
 //prepare a request
@@ -348,7 +351,7 @@ void VDR::threadMethod()
     // Data was read
             
     channelID = ntohl(channelID);
-   
+
     if (channelID == CHANNEL_REQUEST_RESPONSE)
     {
       if (!tcp->readData((UCHAR*)&requestID, sizeof(ULONG))) break;
@@ -375,7 +378,7 @@ void VDR::threadMethod()
         delete vresp;
       }
     }
-    else if (channelID == CHANNEL_STREAM)
+    else if (channelID == CHANNEL_STREAM || channelID == CHANNEL_TVMEDIA)
     {
       if (!tcp->readData((UCHAR*)&streamID, sizeof(ULONG))) break;
       streamID = ntohl(streamID);
@@ -394,8 +397,8 @@ void VDR::threadMethod()
       }
 
       vresp = new VDR_ResponsePacket();    
-      vresp->setStream(streamID, flag, userData, userDataLength);
-//      logger->log("VDR", Log::DEBUG, "Rxd a stream packet, streamID=%lu, flag=%lu, len=%lu", streamID, flag, userDataLength);
+      vresp->setStream(streamID, flag, userData, userDataLength, channelID);
+      //logger->log("VDR", Log::DEBUG, "Rxd a stream packet, streamID=%lu, flag=%lu, len=%lu", streamID, flag, userDataLength);
 
       if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
       {
@@ -466,10 +469,10 @@ void VDR::connectionDied()
       }
       edLock();
     }
-    else if (vdrpr->receiverChannel == CHANNEL_STREAM)
+    else if (vdrpr->receiverChannel == CHANNEL_STREAM || vdrpr->receiverChannel == CHANNEL_TVMEDIA)
     {
       vresp = new VDR_ResponsePacket();
-      vresp->setStream(vdrpr->streamID, 2 /* connection-lost flag */ , NULL, 0);
+      vresp->setStream(vdrpr->streamID, 2 /* connection-lost flag */ , NULL, 0, vdrpr->receiverChannel);
       logger->log("VDR", Log::DEBUG, "Timeouts: created blank response packet for streamid %lu", vdrpr->streamID);
       edUnlock();
       if (!edFindAndCall(vresp)) // makes ED lock, find receiver for vresp (using ed_cb_find() ) and then call (using ed_cb_call() )
@@ -503,6 +506,7 @@ bool VDR::ed_cb_find(EDReceiver* edr, void* userTag)
   // Is vresp for vdrpr ?
   
   ULONG packetChannel = vresp->getChannelID();
+  //logger->log("VDR", Log::DEBUG, "TVMedia debug %d %d %x", vdrpr->receiverChannel,packetChannel,vdrpr);
   if (vdrpr->receiverChannel != packetChannel) return false;
 
   if (packetChannel == CHANNEL_REQUEST_RESPONSE)
@@ -512,6 +516,9 @@ bool VDR::ed_cb_find(EDReceiver* edr, void* userTag)
   else if (packetChannel == CHANNEL_STREAM)
   {
     if (vdrpr->streamID == vresp->getStreamID()) return true;
+  } else  if (packetChannel == CHANNEL_TVMEDIA)
+  { //We want them all
+    return true;
   }
  
   return false;
@@ -584,7 +591,7 @@ bool VDR::sendKA(ULONG timeStamp)
 
 // Here VDR takes a break for the VDR_PacketReceiver helper class
 
-bool VDR_PacketReceiver::call(void* userTag)
+bool VDR_PacketReceiver::call(void* userTag, bool & deleteme)
 {
   if (receiverChannel == VDR::CHANNEL_REQUEST_RESPONSE)
   {
@@ -592,6 +599,7 @@ bool VDR_PacketReceiver::call(void* userTag)
     // VDR::RequestResponse will be blocking waiting for this to happen.
     // That function has a pointer to this object and can read save_vresp.
     save_vresp = (VDR_ResponsePacket*)userTag;
+    deleteme=false;
     return true; // Signals ED to remove edr from receivers and wake up edr thread
   }
   
@@ -601,15 +609,28 @@ bool VDR_PacketReceiver::call(void* userTag)
     VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
     streamReceiver->streamReceive(vresp->getFlag(), vresp->getUserData(), vresp->getUserDataLength());
     delete vresp;
+    deleteme=false;
     return false;
   }
+  if (receiverChannel == VDR::CHANNEL_TVMEDIA)
+  {
+         // It's TVMedia
+         VDR_ResponsePacket* vresp = (VDR_ResponsePacket*)userTag;
+         Log::getInstance()->log("VDR", Log::DEBUG, "TVMedia Pictures arrived VDR");
+         OsdVector *osd=dynamic_cast<OsdVector*>(Osd::getInstance());
+         if (osd) osd->receivePicture(vresp);
+         else delete vresp; //nonsense
+         deleteme=false;
+         return true;
+  }
+
 
   abort(); // unknown receiverChannel, should not happen
 }
 
 /////////////////////////////////////////////////////////////////////////////
 
-int VDR::doLogin(unsigned int* v_server,unsigned int* v_client)
+int VDR::doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client)
 {
   VDR_RequestPacket vrp;
   if (!vrp.init(VDR_LOGIN, true, 6)) return 0;
@@ -626,14 +647,17 @@ int VDR::doLogin(unsigned int* v_server,unsigned int* v_client)
   long vdrTimeOffset = vresp->extractLONG();
   logger->log("VDR", Log::DEBUG, "offset = %i", vdrTimeOffset);
 
-  unsigned int version=vresp->extractULONG();
+  unsigned int version_min=vresp->extractULONG();
 
-  *v_server=version;
+  *v_server_min=version_min;
+  unsigned int version_max=vresp->extractULONG();
+  *v_server_max=version_max;
   *v_client=VOMP_PROTOCOLL_VERSION;
 
   delete vresp;
 
-  if (version!=VOMP_PROTOCOLL_VERSION) {
+  if ((version_min > VOMP_PROTOCOLL_VERSION)
+                 || (version_max < VOMP_PROTOCOLL_VERSION) ) {
 
          return 0;
 
@@ -1190,6 +1214,7 @@ RecInfo* VDR::getRecInfo(char* fileName)
     }
   }
   recInfo->fps=vresp->extractdouble();
+  recInfo->title=vresp->extractString();
   
 
   recInfo->print();
@@ -1566,3 +1591,209 @@ void VDR::shutdownVDR()
 
   logger->log("VDR", Log::DEBUG, "VDR shutdown");
 }
+
+void VDR::getScraperEventType(char * fileName, int & movieID,
+               int & seriesID, int & episodeID )
+{
+       movieID = 0;
+       seriesID = 0;
+       episodeID = 0;
+       VDR_RequestPacket vrp;
+       if (!vrp.init(VDR_GETRECSCRAPEREVENTTYPE, true, strlen(fileName) + 1)) return;
+       if (!vrp.addString(fileName)) return ;
+       Log::getInstance()->log("Recording", Log::DEBUG, "Before Response ");
+       VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+       Log::getInstance()->log("Recording", Log::DEBUG, "After Response ");
+       if (vresp->noResponse()) { delete vresp; return ; }
+       int type = vresp->extractUCHAR();
+       if (type == 0) //serie
+       {
+               seriesID = vresp->extractLONG();
+               episodeID = vresp->extractLONG();
+       } else if (type == 1) //movie
+       {
+               movieID = vresp->extractLONG();
+       }
+       delete vresp;
+
+}
+
+MovieInfo *VDR::getScraperMovieInfo(int movieID)
+{
+       VDR_RequestPacket vrp;
+       if (!vrp.init(VDR_GETSCRAPERMOVIEINFO, false, 0)) return NULL;
+       if (!vrp.addULONG(movieID)) return NULL;
+       VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+       if (vresp->noResponse()) { delete vresp; return NULL; }
+       MovieInfo * movieinf= new MovieInfo();
+
+       movieinf->id=movieID;
+       movieinf->title = vresp->extractStdString();
+       movieinf->originalTitle = vresp->extractStdString();
+       movieinf->tagline = vresp->extractStdString();
+       movieinf->overview = vresp->extractStdString();
+       movieinf->adult = vresp->extractUCHAR();
+       movieinf->collectionName = vresp->extractStdString();
+
+       movieinf->budget = vresp->extractLONG();
+       movieinf->revenue = vresp->extractLONG();
+       movieinf->genres = vresp->extractStdString();
+       movieinf->homepage = vresp->extractStdString();
+       movieinf->releaseDate = vresp->extractStdString();
+       movieinf->runtime = vresp->extractLONG();
+       movieinf->popularity = vresp->extractdouble();
+       movieinf->voteAverage = vresp->extractdouble();
+       movieinf->poster.width = vresp->extractULONG();
+       movieinf->poster.height = vresp->extractULONG();
+       movieinf->poster.info.setMovieInfo(movieinf);
+       movieinf->poster.info.setElement(0,0);
+       movieinf->fanart.width = vresp->extractULONG();
+       movieinf->fanart.height = vresp->extractULONG();
+       movieinf->fanart.info.setMovieInfo(movieinf);
+       movieinf->fanart.info.setElement(1,0);
+       movieinf->collectionPoster.width = vresp->extractULONG();
+       movieinf->collectionPoster.height = vresp->extractULONG();
+       movieinf->collectionPoster.info.setMovieInfo(movieinf);
+       movieinf->collectionPoster.info.setElement(2,0);
+       movieinf->collectionFanart.width = vresp->extractULONG();
+       movieinf->collectionFanart.height = vresp->extractULONG();
+       movieinf->collectionFanart.info.setMovieInfo(movieinf);
+       movieinf->collectionFanart.info.setElement(3,0);
+       ULONG num_actors =  vresp->extractULONG();
+       movieinf->actors.clear();
+       movieinf->actors.reserve(num_actors);
+       for (ULONG acty=0; acty < num_actors; acty++) {
+               Actor new_act;
+               new_act.name =  vresp->extractStdString();
+               new_act.role =  vresp->extractStdString();
+               new_act.thumb.width = vresp->extractULONG();
+               new_act.thumb.height = vresp->extractULONG();
+               new_act.thumb.info.setMovieInfo(movieinf);
+               new_act.thumb.info.setElement(4,acty);
+               movieinf->actors.push_back(new_act);
+       }
+
+
+       delete vresp;
+       return movieinf;
+
+}
+
+SeriesInfo *VDR::getScraperSeriesInfo(int seriesID, int episodeID)
+{
+       VDR_RequestPacket vrp;
+       if (!vrp.init(VDR_GETSCRAPERSERIESINFO, false, 0)) return NULL;
+       if (!vrp.addULONG(seriesID)) return NULL;
+       if (!vrp.addULONG(episodeID)) return NULL;
+
+       VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+       if (vresp->noResponse()) { delete vresp; return 0; }
+       SeriesInfo * seriesinf= new SeriesInfo();
+
+       seriesinf->id=seriesID;
+
+
+       seriesinf->name = vresp->extractStdString();
+       seriesinf->overview = vresp->extractStdString();
+       seriesinf->firstAired = vresp->extractStdString();
+       seriesinf->network = vresp->extractStdString();
+       seriesinf->genre = vresp->extractStdString();
+       seriesinf->rating =  vresp->extractdouble();
+       seriesinf->status = vresp->extractStdString();
+
+
+       seriesinf->episode.episodeid=episodeID;
+       seriesinf->episode.number = vresp->extractLONG();
+       seriesinf->episode.season = vresp->extractLONG();
+       seriesinf->episode.name =  vresp->extractStdString();
+       seriesinf->episode.firstAired =  vresp->extractStdString();
+       seriesinf->episode.guestStars =  vresp->extractStdString();
+       seriesinf->episode.overview =  vresp->extractStdString();
+       seriesinf->episode.rating = vresp->extractdouble();
+       seriesinf->episode.image.width =  vresp->extractULONG();
+       seriesinf->episode.image.height =  vresp->extractULONG();
+       seriesinf->episode.image.info.setSeriesInfo(seriesinf);
+       seriesinf->episode.image.info.setElement(0,0);
+
+
+       ULONG num_actors =  vresp->extractULONG();
+       seriesinf->actors.clear();
+       seriesinf->actors.reserve(num_actors);
+       for (ULONG acty=0; acty < num_actors; acty++) {
+               Actor new_act;
+               new_act.name =  vresp->extractStdString();
+               new_act.role =  vresp->extractStdString();
+               new_act.thumb.width = vresp->extractULONG();
+               new_act.thumb.height = vresp->extractULONG();
+               new_act.thumb.info.setSeriesInfo(seriesinf);
+               new_act.thumb.info.setElement(1,acty);
+               seriesinf->actors.push_back(new_act);
+       }
+       ULONG num_posters =  vresp->extractULONG();
+       for (ULONG medias = 0; medias < num_posters; medias++ ) {
+               TVMedia media;
+               media.info.setSeriesInfo(seriesinf);
+               media.info.setElement(2,medias);
+               media.width =  vresp->extractULONG();
+               media.height = vresp->extractULONG();
+               seriesinf->posters.push_back(media);
+       }
+
+       ULONG num_banners =  vresp->extractULONG();
+       for (ULONG medias = 0; medias < num_banners; medias++ ) {
+               TVMedia media;
+               media.info.setSeriesInfo(seriesinf);
+               media.info.setElement(3,medias);
+               media.width =  vresp->extractULONG();
+               media.height = vresp->extractULONG();
+               seriesinf->banners.push_back(media);
+       }
+       ULONG num_fanarts =  vresp->extractULONG();
+       for (ULONG medias = 0; medias < num_fanarts; medias++ ) {
+               TVMedia media;
+               media.info.setSeriesInfo(seriesinf);
+               media.info.setElement(4,medias);
+               media.width =  vresp->extractULONG();
+               media.height = vresp->extractULONG();
+               seriesinf->fanart.push_back(media);
+       }
+       seriesinf->seasonposter.width = vresp->extractULONG();
+       seriesinf->seasonposter.height = vresp->extractULONG();
+       seriesinf->seasonposter.info.setSeriesInfo(seriesinf);
+       seriesinf->seasonposter.info.setElement(5,0);
+
+       delete vresp;
+       return seriesinf;
+
+}
+
+ULONG VDR::loadTVMedia(TVMediaInfo& tvmedia)
+{
+
+       VDR_RequestPacket vrp;
+
+       if (!vrp.init(VDR_LOADTVMEDIA, false, 0)) return -1;
+       if (!vrp.addULONG(tvmedia.type)) return -1;
+       if (!vrp.addULONG(tvmedia.primary_id)) return -1;
+       if (!vrp.addULONG(tvmedia.secondary_id)) return -1;
+       if (!vrp.addULONG(tvmedia.type_pict)) return -1;
+       if (!vrp.addULONG(tvmedia.container)) return -1;
+       if (!vrp.addULONG(tvmedia.container_member)) return -1;
+       Log::getInstance()->log("VDR", Log::DEBUG, "TVMedia with ID %d %d; %d %d %d %d;%d",
+                       tvmedia.primary_id,tvmedia.secondary_id,tvmedia.type,tvmedia.type_pict,
+                       tvmedia.container,tvmedia.container_member,vrp.getSerial());
+
+
+       VDR_PacketReceiver* vdrpr = new VDR_PacketReceiver();
+       vdrpr->receiverChannel = VDR::CHANNEL_TVMEDIA;
+       vdrpr->streamID = vrp.getSerial();
+       vdrpr->streamReceiver = NULL;
+       edRegister(vdrpr);
+
+
+       VDR_ResponsePacket* vresp = RequestResponse(&vrp);
+       //if (vresp->noResponse()) { delete vresp; return -1; }
+       delete vresp;
+
+       return vrp.getSerial();
+}
diff --git a/vdr.h b/vdr.h
index c406115e7b4b8c983182c6fe4a9a84b9a039edb5..f322051e876431de70965e9efa3f969be28c0f4f 100644 (file)
--- a/vdr.h
+++ b/vdr.h
@@ -40,6 +40,7 @@
 #include "eventdispatcher.h"
 #include "i18n.h"
 #include "log.h"
+#include "osdvector.h"
 
 class TCP;
 class Log;
@@ -49,6 +50,9 @@ class Channel;
 class VDR_RequestPacket;
 class VDR_ResponsePacket;
 class SerializeBuffer;
+class MovieInfo;
+class SeriesInfo;
+
 
 using namespace std;
 
@@ -92,7 +96,7 @@ class StreamReceiver
 class VDR_PacketReceiver : public EDReceiver // implementation in vdr.cc
 {
   public:
-    virtual bool call(void* userTag);
+    virtual bool call(void* userTag, bool & deleteme);
 
   friend class VDR;
   protected:
@@ -119,6 +123,7 @@ class VDR : public Thread_TYPE, public EventDispatcher, public MediaProvider, pu
     const static ULONG CHANNEL_STREAM = 2;
     const static ULONG CHANNEL_KEEPALIVE = 3;
     const static ULONG CHANNEL_NETLOG = 4;
+    const static ULONG CHANNEL_TVMEDIA = 5;
   
     VDR();
     ~VDR();
@@ -158,7 +163,7 @@ class VDR : public Thread_TYPE, public EventDispatcher, public MediaProvider, pu
     //  configSave
     //  setEventTimer
 
-    int           doLogin(unsigned int* v_server,unsigned int* v_client);
+    int           doLogin(unsigned int* v_server_min, unsigned int* v_server_max, unsigned int* v_client);
     bool          getRecordingsList(RecMan* recman);
     RecInfo*      getRecInfo(char* fileName);
     int           deleteRecording(char* fileName);
@@ -199,6 +204,12 @@ class VDR : public Thread_TYPE, public EventDispatcher, public MediaProvider, pu
     virtual int getMediaInfo(ULONG channel, struct MediaInfo * result);
     virtual int closeMediaChannel(ULONG channel);
 
+    //TV Scraper support
+    void getScraperEventType(char * fileName, int & movieID, int & seriesID, int & episodeID);
+    MovieInfo *getScraperMovieInfo(int movieID);
+    SeriesInfo *getScraperSeriesInfo(int seriesID, int episodeID);
+    ULONG loadTVMedia(TVMediaInfo& tvmedia);
+
 
     I18n::lang_code_list getLanguageList();
     int           getLanguageContent(const string code, I18n::trans_table&);
index 33b9352b0a2563ee7169672538573d35f692f454..d0a8af86160f123be3562cc57b24d23ddda1148a 100644 (file)
@@ -69,6 +69,10 @@ const static ULONG VDR_OPENMEDIA           = 31;
 const static ULONG VDR_GETMEDIABLOCK       = 32;
 const static ULONG VDR_GETMEDIAINFO        = 35;
 const static ULONG VDR_CLOSECHANNEL        = 36;
+const static ULONG VDR_GETRECSCRAPEREVENTTYPE = 38;
+const static ULONG VDR_GETSCRAPERMOVIEINFO = 39;
+const static ULONG VDR_GETSCRAPERSERIESINFO = 40;
+const static ULONG VDR_LOADTVMEDIA = 41;
 const static ULONG VDR_SHUTDOWN            = 666;
 
 class VDR_Command : public SerializableList {
index 37b2be5d90fc2a34dbc9fffece629104e5147319..41ff5223ff78e4642a56b676bd4d37da7a1add4d 100644 (file)
@@ -53,9 +53,9 @@ void VDR_ResponsePacket::setResponse(ULONG trequestID, UCHAR* tuserData, ULONG t
   userDataLength = tuserDataLength;
 }
 
-void VDR_ResponsePacket::setStream(ULONG tstreamID, ULONG tflag, UCHAR* tuserData, ULONG tuserDataLength)
+void VDR_ResponsePacket::setStream(ULONG tstreamID, ULONG tflag, UCHAR* tuserData, ULONG tuserDataLength, ULONG tchannelID)
 {
-  channelID = VDR::CHANNEL_STREAM;
+  channelID = tchannelID;
   streamID = tstreamID;
   flag = tflag;
   userData = tuserData;
@@ -78,6 +78,17 @@ int VDR_ResponsePacket::serverError()
   else return 0;
 }
 
+std::string  VDR_ResponsePacket::extractStdString()
+{
+  if (serverError()) return NULL;
+
+  int length = strlen((char*)&userData[packetPos]);
+  if ((packetPos + length) > userDataLength) return std::string("");
+  const char * dest_str=(char*)&userData[packetPos];
+  packetPos += length + 1;
+  return dest_str;
+}
+
 char* VDR_ResponsePacket::extractString()
 {
   if (serverError()) return NULL;
index 0d60be0e3bc71387b407fe1428dc7f4a1fef6a0f..25abedfbd0cfba47243fb8fa0875b7adf08c327a 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <string>
 
 #include "defines.h"
 
@@ -39,7 +40,7 @@ class VDR_ResponsePacket
     ~VDR_ResponsePacket();
     
     void setResponse(ULONG requestID, UCHAR* packet, ULONG packetLength);
-    void setStream(ULONG streamID, ULONG flag, UCHAR* packet, ULONG packetLength);
+    void setStream(ULONG streamID, ULONG flag, UCHAR* packet, ULONG packetLength, ULONG tchannelID);
      
     bool noResponse() { return (userData == NULL); };
     int  serverError();
@@ -51,6 +52,7 @@ class VDR_ResponsePacket
     ULONG getFlag() { return flag; }
     
     char*  extractString();
+    std::string  extractStdString();
     UCHAR  extractUCHAR();
     ULONG  extractULONG();
     ULLONG extractULLONG();
index fd8a1335f43df9d1b8a2dcc56311ce365f18ce5b..33ce840c3c1027749cd4713560814606612aaee9 100644 (file)
@@ -1208,7 +1208,7 @@ int VideoOMX::AllocateCodecsOMX()
        }
 
 
-       Log::getInstance()->log("Video", Log::DEBUG, "mark2 ");
+
        if (!ChangeComponentState(omx_vid_sched,OMX_StateIdle)) {
                Log::getInstance()->log("Video", Log::DEBUG, "vid_sched idle ChangeComponentState");
                clock_mutex.Unlock();
@@ -1218,7 +1218,7 @@ int VideoOMX::AllocateCodecsOMX()
 
 
 
-       Log::getInstance()->log("Video", Log::DEBUG, "mark1 ");
+
        if ( !CommandFinished(omx_vid_sched,OMX_CommandPortEnable,omx_shed_clock_port)) {
                clock_mutex.Unlock();
                DeAllocateCodecsOMX();
@@ -1228,7 +1228,7 @@ int VideoOMX::AllocateCodecsOMX()
 
 
 
-       Log::getInstance()->log("Video", Log::DEBUG, "mark1 special ");
+
        if ( !CommandFinished(omx_clock,OMX_CommandPortEnable,omx_clock_output_port)) {
                clock_mutex.Unlock();
                DeAllocateCodecsOMX();
@@ -1237,9 +1237,6 @@ int VideoOMX::AllocateCodecsOMX()
 
 
 
-       Log::getInstance()->log("Video", Log::DEBUG, "mark1b ");
-
-
 /*     error=OMX_SendCommand(omx_vid_dec,OMX_CommandStateSet,OMX_StateIdle,0);
        if (error!=OMX_ErrorNone){
                Log::getInstance()->log("Video", Log::DEBUG, "vid_dec Send Command to OMX State Idle %x", error);
index 6ebb45ce2559074b037f1899b841298399022dc0..f9e2eca5bb8c64f1981e53fb0831e29f029de7d9 100644 (file)
 #include "recording.h"
 #include "message.h"
 #include "log.h"
+#include "wmovieview.h"
+#include "wseriesview.h"
+#include "wpictureview.h"
 
 VRecording::VRecording(RecMan* trecman, Recording* trec)
 {
   rec = trec;
   recman = trecman;
+  buttons = true;
   
   Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
   rec->loadRecInfo();
   Log::getInstance()->log("VRecording", Log::DEBUG, "%s", rec->getProgName());
 
-  setSize(570, 420);
-  createBuffer();
+
   if (Video::getInstance()->getFormat() == Video::PAL)
   {
-    setPosition(80, 70);
+    setSize(640, 500);
+       createBuffer();
   }
   else
   {
-    setPosition(70, 35);
+       setSize(560, 400);
+       createBuffer();
   }
+  setPosition(40, 40);
 
   setTitleBarOn(1);
   setBorderOn(1);
-  setTitleText(rec->getProgName());
+  if (rec->recInfo && strlen(rec->recInfo->title))
+         setTitleText(rec->recInfo->title);
+  else
+         setTitleText(rec->getProgName());
   setTitleBarColour(DrawStyle::TITLEBARBACKGROUND);
 
-  summary.setPosition(10, 30 + 5);
-  summary.setSize(area.w - 20, area.h - 30 - 15 - 50);
-  summary.setParaMode(true);
+  tabbar.setPosition(10+130+10, 30 + 5);
+  tabbar.setSize(area.w - 20-10-130, area.h - 30 - 10);
+  add(&tabbar);
+
+
+
 
-  if (rec->recInfo &&strlen(rec->recInfo->summary))
-    summary.setText(rec->recInfo->summary);
+  WTextbox * summary=new WTextbox();
+  summary->setParaMode(true);
+
+  if (rec->recInfo && strlen(rec->recInfo->summary))
+    summary->setText(rec->recInfo->summary);
   else
-    summary.setText(tr("Summary unavailable"));
+    summary->setText(tr("Summary unavailable"));
+
+  OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
+
+  tabbar.addTab(tr("EPG"), summary);
+  if (rec->movieInfo) {
+         WMovieView *movieview = new WMovieView(rec->movieInfo);
+         movieview->setParaMode(true);
+         tabbar.addTab(tr("TheTVDB Info"), movieview);
+         if (osdv) {
+                 if (rec->movieInfo->actors.size() > 0 && osdv)
+                 {
+                         WActorGallery *gallery= new WActorGallery(rec->movieInfo->actors);
+                         tabbar.addTab(tr("Cast"),gallery);
+                 }
+                 WArtworkGallery *artgallery= new WArtworkGallery(*rec->movieInfo);
+                 tabbar.addTab(tr("Gallery"),artgallery);
+         }
+  } else if (rec->seriesInfo) {
+         WSeriesView *seriesview = new WSeriesView(rec->seriesInfo);
+         seriesview->setParaMode(true);
+         tabbar.addTab(tr("TheTVDB Info"), seriesview);
+         if (osdv) {
+                 if (rec->seriesInfo->actors.size() > 0 && osdv)
+                 {
+                         WActorGallery *gallery= new WActorGallery(rec->seriesInfo->actors);
+                         tabbar.addTab(tr("Cast"),gallery);
+                 }
+                 WArtworkGallery *artgallery= new WArtworkGallery(*rec->seriesInfo);
+                 tabbar.addTab(tr("Gallery"),artgallery);
+         }
+
+  }
+
 
-  add(&summary);
   
   int sfh = getFontHeight();
   buttonRegion.x = 10;
-  buttonRegion.y = area.h - 40;
-  buttonRegion.w = 550;
-  buttonRegion.h = sfh;
+  buttonRegion.y = 10+30;
+  buttonRegion.w = 130;
+  buttonRegion.h = sfh*2*last;
 
   button[PLAY].setText(tr("Play"));
   button[RESUME].setText(tr("Resume"));
   button[MOVE].setText(tr("Move"));
   button[A_DELETE].setText(tr("Delete"));
   
-  for (int i=PLAY, hor=10; i<last; i++, hor+= 140)
+  for (int i=PLAY, ver=10+30; i<last; i++, ver+= sfh*2)
   {
-    button[i].setPosition(hor, area.h - 40);
+    button[i].setPosition(10, ver);
     button[i].setSize(130, sfh);
     add(&button[i]);
   }
   
   selected = RESUME;
   button[selected].setActive(1);
+  tabbar.activateFocus(false);
 }
 
 VRecording::~VRecording()
@@ -107,95 +155,153 @@ void VRecording::setParent(VRecordingList* tvRecList)
 void VRecording::draw()
 {
   TBBoxx::draw();
+  OsdVector *osdv=dynamic_cast<OsdVector*>(Osd::getInstance());
+  if (osdv) {
+         TVMedia poster;
+         if (rec->movieInfo) {
+                 poster=rec->movieInfo->poster;
+         }
+         if (rec->seriesInfo) {
+                 if (rec->seriesInfo->seasonposter.height) {
+                         poster=rec->seriesInfo->seasonposter;
+                 }
+                 else
+                 if (rec->seriesInfo->posters.size()) {
+                         poster=rec->seriesInfo->posters[0];
+                 }
+         }
+         if (poster.height) {
+                // float aspect=((float)poster.height)/((float)poster.width)/Osd::getInstance()->getPixelAspect();
+                 drawTVMedia(poster.info,buttonRegion.x,
+                                        buttonRegion.y+buttonRegion.h,
+                                               buttonRegion.w,/*buttonRegion.w*aspect*/0.f);
+         }
+  }
+
 }
 
 int VRecording::handleCommand(int command)
 {
-  switch(command)
-  {
-    case Remote::LEFT:
-    case Remote::DF_LEFT:
-    case Remote::DF_UP:
-    case Remote::UP:
-    {
-      moveCursor(LEFT);
-      return 2;
-    }
-    case Remote::RIGHT:
-    case Remote::DF_RIGHT:
-    case Remote::DF_DOWN:
-    case Remote::DOWN:
-    {
-      moveCursor(RIGHT);
-      return 2;
-    }
-    case Remote::OK:
-    {
+       if (command==Remote::BACK) {
+               return 4;
+       }
+       if (buttons) {
+               switch(command)
+               {
+               case Remote::DF_UP:
+               case Remote::UP:
+               {
+                       moveCursor(LEFT);
+                       return 2;
+               }
 
-      if (selected == PLAY)
-      {
-        Message* m = new Message(); // Must be done after this view deleted
-        m->from = this;
-        m->to = vRecList;
-        m->message = Message::PLAY_SELECTED_RECORDING;
-        Command::getInstance()->postMessageNoLock(m);
-        return 4;
-      }
+               case Remote::DF_DOWN:
+               case Remote::DOWN:
+               {
+                       moveCursor(RIGHT);
+                       return 2;
+               }
+               case Remote::LEFT:
+               case Remote::DF_LEFT:
+               case Remote::RIGHT:
+               case Remote::DF_RIGHT:
+               {
+                       buttons = false;
+                       button[selected].setActive(0);
+                       tabbar.activateFocus(true);
+                       button[selected].draw();
+                       tabbar.draw();
+                       BoxStack::getInstance()->update(this);
+                       return 2;
+               }
+               case Remote::OK:
+               {
 
-      if (selected == RESUME)
-      {
-        Message* m = new Message(); // Must be done after this view deleted
-        m->from = this;
-        m->to = vRecList;
-        m->message = Message::RESUME_SELECTED_RECORDING;
-        Command::getInstance()->postMessageNoLock(m);
-        return 4;
-      }
+                       if (selected == PLAY)
+                       {
+                               Message* m = new Message(); // Must be done after this view deleted
+                               m->from = this;
+                               m->to = vRecList;
+                               m->message = Message::PLAY_SELECTED_RECORDING;
+                               Command::getInstance()->postMessageNoLock(m);
+                               return 4;
+                       }
 
-      if (selected == MOVE)
-      {
-        VRecMove* vrm = new VRecMove(recman);
-        vrm->setParent(this);
-        vrm->draw();
-        BoxStack::getInstance()->add(vrm);
-        BoxStack::getInstance()->update(vrm);
-        return 2;
-      }
+                       if (selected == RESUME)
+                       {
+                               Message* m = new Message(); // Must be done after this view deleted
+                               m->from = this;
+                               m->to = vRecList;
+                               m->message = Message::RESUME_SELECTED_RECORDING;
+                               Command::getInstance()->postMessageNoLock(m);
+                               return 4;
+                       }
 
-      if (selected == A_DELETE)
-      {
-        VQuestion* v = new VQuestion(this);
-        v->setSize(260, 180);
-        v->createBuffer();
-        v->setTitleBarColour(DrawStyle::DANGER);
-        v->setTitleBarOn(1);
-        v->setBorderOn(1);
-        v->setTitleText(tr("Delete recording"));
-        v->setMainText(tr("Are you sure you want to delete this recording?"));
-        v->setDefault(VQuestion::NO);
-        if (Video::getInstance()->getFormat() == Video::PAL)
-        {
-          v->setPosition(230, 160);
-        }
-        else
-        {
-          v->setPosition(220, 140);
-        }
-
-        v->draw();
-        BoxStack::getInstance()->add(v);
-        BoxStack::getInstance()->update(v);
-        return 2;
-      }
-    }
+                       if (selected == MOVE)
+                       {
+                               VRecMove* vrm = new VRecMove(recman);
+                               vrm->setParent(this);
+                               vrm->draw();
+                               BoxStack::getInstance()->add(vrm);
+                               BoxStack::getInstance()->update(vrm);
+                               return 2;
+                       }
 
-    case Remote::BACK:
-    {
-      return 4;
-    }
-  }
-  // stop command getting to any more views
-  return 1;
+                       if (selected == A_DELETE)
+                       {
+                               VQuestion* v = new VQuestion(this);
+                               v->setSize(260, 180);
+                               v->createBuffer();
+                               v->setTitleBarColour(DrawStyle::DANGER);
+                               v->setTitleBarOn(1);
+                               v->setBorderOn(1);
+                               v->setTitleText(tr("Delete recording"));
+                               v->setMainText(tr("Are you sure you want to delete this recording?"));
+                               v->setDefault(VQuestion::NO);
+                               if (Video::getInstance()->getFormat() == Video::PAL)
+                               {
+                                       v->setPosition(230, 160);
+                               }
+                               else
+                               {
+                                       v->setPosition(220, 140);
+                               }
+
+                               v->draw();
+                               BoxStack::getInstance()->add(v);
+                               BoxStack::getInstance()->update(v);
+                               return 2;
+                       }
+               }
+               }
+       } else {
+               // Pass to tabbar
+               int retval = tabbar.handleCommand(command);
+               if (retval == 1)
+               {
+                       BoxStack::getInstance()->update(this);
+                       return 2;
+               }
+               else if (retval == 2)
+               {
+                       // command was taken and actively ignored
+                       if (command==Remote::LEFT || command==Remote::DF_LEFT
+                                       || command==Remote::RIGHT || command==Remote::DF_RIGHT)
+                       {
+                               buttons=true;
+                               button[selected].setActive(1);
+                               tabbar.activateFocus(false);
+                               button[selected].draw();
+                               tabbar.draw();
+                               BoxStack::getInstance()->update(this);
+                       }
+                       return 2;
+               }
+       }
+
+
+       // stop command getting to any more views
+       return 1;
 }
 
 void VRecording::moveCursor(Direction direction)
index 10394c218eb4424d12643e4b1eaffd7ef8a42912..ca5eac17f6380b3ee299b36a7f9ab7c4d8657997 100644 (file)
@@ -27,6 +27,7 @@
 #include "tbboxx.h"
 #include "wbutton.h"
 #include "wtextbox.h"
+#include "wtabbar.h"
 
 class VRecordingList;
 class RecMan;
@@ -49,8 +50,7 @@ class VRecording : public TBBoxx
     RecMan* recman;
     VRecordingList* vRecList;
     Recording* rec;
-    
-    WTextbox summary;
+    WTabBar tabbar;
 
     enum Action { PLAY=0, RESUME, MOVE, A_DELETE, last };
     WButton button[last];
@@ -61,6 +61,7 @@ class VRecording : public TBBoxx
     
     int selected;
     Region buttonRegion;
+    bool buttons;
    
     enum Direction { LEFT, RIGHT };
     void moveCursor(Direction direction);
diff --git a/wmovieview.cc b/wmovieview.cc
new file mode 100644 (file)
index 0000000..9e5ed6e
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "wmovieview.h"
+#include "i18n.h"
+#include <sstream>
+
+
+WMovieView::WMovieView(MovieInfo* movie):
+WTextbox(NULL)
+{
+       // portions from nopacity plugin by Louis Braun
+       if (movie)
+       {
+               std::stringstream info;
+           info << tr("TheMovieDB Information") << ":\n\n";
+           if (!movie->originalTitle.empty()){
+               info << tr("Original Title") << ": " << movie->originalTitle << "\n\n";
+           }
+           if (!movie->tagline.empty()){
+               info << tr("Tagline") << ": " << movie->tagline << "\n\n";
+           }
+           if (!movie->overview.empty()){
+               info << tr("Overview") << ": " << movie->overview << "\n\n";
+           }
+           const char* strAdult = (movie->adult)?(tr("yes")):(tr("no"));
+           info << tr("Adult") << ": " << strAdult << "\n\n";
+           if (!movie->collectionName.empty()){
+               info << tr("Collection") << ": " << movie->collectionName << "\n\n";
+           }
+           if (movie->budget > 0 ){
+               info << tr("Budget") << ": " << movie->budget << "$\n\n";
+           }
+           if (movie->revenue > 0 ){
+               info << tr("Revenue") << ": " << movie->revenue << "$\n\n";
+           }
+           if (!movie->genres.empty() ){
+               info << tr("Genre") << ": " << movie->genres << "\n\n";
+           }
+           if (!movie->homepage.empty()){
+               info << tr("Homepage") << ": " << movie->homepage << "\n\n";
+           }
+           if (!movie->releaseDate.empty()){
+               info << tr("Release Date") << ": " << movie->releaseDate << "\n\n";
+           }
+           if (movie->runtime > 0 ){
+               info << tr("Runtime") << ": " << movie->runtime << " " << tr("minutes") << "\n\n";
+           }
+           if (movie->popularity > 0 ){
+               info << tr("TheMovieDB Popularity") << ": " << movie->popularity << "\n\n";
+           }
+           if (movie->voteAverage > 0 ){
+               info << tr("TheMovieDB Vote Average") << ": " << movie->voteAverage << "\n\n";
+           }
+           setText(info.str().c_str());
+       } else {
+               setText("This is a bug!");
+       }
+
+}
+
+void WMovieView::draw()
+{
+       WTextbox::draw();
+
+
+}
diff --git a/wmovieview.h b/wmovieview.h
new file mode 100644 (file)
index 0000000..ef04c75
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef WMOVIEVIEW_H
+#define WMOVIEVIEW_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defines.h"
+#include "wtextbox.h"
+#include "movieinfo.h"
+
+class Colour;
+
+class WMovieView : public WTextbox
+{
+  public:
+    WMovieView(MovieInfo* movinfo);
+    void draw();
+
+
+  private:
+
+};
+
+#endif
index 690ab793caba4ac7ebfb28066079f97c0486a5ce..fb5b456e0cd18bf8b339a92ac2a9536893c9a2f3 100644 (file)
@@ -68,7 +68,7 @@ void WOptionPane::addOptionLine(Option* option)
 
   WTextbox* tb = new WTextbox();
   tb->setPosition(4, 4 + (numOptions * 30));
-  tb->setSize(300, fontHeight);
+  tb->setSize(300, fontHeight + 6);
   tb->setText(tr(option->displayText));
   tb->setTextPos(0, 0);
   add(tb);
diff --git a/wpictureview.cc b/wpictureview.cc
new file mode 100644 (file)
index 0000000..5418a2d
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+    Copyright 2005 Brian Walton (WTextBox)
+    Copyright 2014 Marten Richter (WPictureView)
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "wpictureview.h"
+
+#include "colour.h"
+#include "remote.h"
+#include "osd.h"
+#include "movieinfo.h"
+#include "seriesinfo.h"
+#include <math.h>
+
+WPictureView::WPictureView():
+foreColour(DrawStyle::LIGHTTEXT)
+{
+  cur_scroll_line=0;
+  rem_scroll_line=0;
+  const_height=0;
+}
+
+WPictureView::~WPictureView()
+{
+}
+
+
+
+void WPictureView::setForegroundColour(const DrawStyle& fcolour)
+{
+  foreColour = fcolour;
+}
+
+void WPictureView::draw()
+{
+  Boxx::draw();
+  int fontHeight = getFontHeight();
+  float ypos = cur_scroll_line * (fontHeight*8.f);
+  ypos = -ypos;
+  float height = 0;
+
+  drawClippingRectangle(1,1,area.w-1,area.h-1);
+
+  list<Picture>::iterator itty=pictures.begin();
+  while (itty!=pictures.end())
+  {
+         // We now calculate the pictures in one row
+         list<Picture*> cur_pict;
+         float cur_width=0;
+         float max_height=const_height;
+
+
+         while (itty != pictures.end())
+         {
+                 if ((((*itty).w + cur_width+ 10.f) > area.w || const_height) && cur_pict.size() > 0) break;
+                 cur_width += 10 + (*itty).w;
+                 if (!const_height) max_height = max(max_height,(*itty).h);
+                 cur_pict.push_back(&(*itty));
+                 itty++;
+         }
+         // ok now we have a list of pictures, let's draw them
+         list<Picture*>::iterator citty=cur_pict.begin();
+         float xpos= (area.w - cur_width)*0.5f;
+         if (xpos < 0) xpos=0;
+         while (citty!=cur_pict.end())
+         {
+                 if (!const_height) {
+                         drawTVMedia((*citty)->media,
+                                         xpos, ypos + max_height /*- (*citty)->h*/,
+                                         (*citty)->w,
+                                         /*(*citty)->h*/0.f,BottomLeft);
+                 } else {
+                         if (!(*citty)->banner) {
+                                 drawTVMedia((*citty)->media,
+                                                 xpos+area.w*0.5f, ypos,
+                                                 0.f,
+                                                 const_height,TopMiddle);
+                         } else {
+                                 drawTVMedia((*citty)->media,
+                                               xpos+area.w*0.5f, ypos,
+                                               area.w-2.f,
+                                               0.f,TopMiddle);
+                         }
+                 }
+                 xpos += (*citty)->w + 10.f;
+                 citty++;
+         }
+         ypos += max_height;
+         height += max_height;
+         bool caption1=false;
+         bool caption2=false;
+
+         citty=cur_pict.begin();
+         xpos= (area.w - cur_width)*0.5f;
+          if (xpos < 0) xpos=0;
+         while (citty!=cur_pict.end())
+         {
+                 if (!(*citty)->caption.empty())
+                 {
+                         drawTextCentre((*citty)->caption.c_str(), xpos + (*citty)->w*0.5f, ypos, foreColour);
+                         caption1 = true;
+                 }
+                 if (!(*citty)->caption2.empty())
+                 {
+                         drawTextCentre((*citty)->caption2.c_str(), xpos + (*citty)->w*0.5f, ypos + fontHeight*1.f, foreColour);
+                         caption2 = true;
+                 }
+                 xpos += (*citty)->w + 10.f;
+                 citty++;
+         }
+         if (caption1) {
+                 ypos +=fontHeight*1.f;
+                 height += fontHeight*1.f;
+         }
+         if (caption2) {
+                 ypos +=fontHeight*1.f;
+                 height += fontHeight*1.f;
+         }
+         ypos +=fontHeight*1.f;
+         height += fontHeight*1.f;
+
+  }
+  rem_scroll_line = ceil((height - area.h  -cur_scroll_line * fontHeight*8.f)/fontHeight/8.f);
+ // Log::getInstance()->log("WActorGallery", Log::DEBUG, "TVMedia rml %d",rem_scroll_line);
+  drawClippingRectangle(0,0,0,0);
+
+}
+
+void WPictureView::addPicture(TVMediaInfo& pict,  float pwidth, float pheight , bool banner, std::string caption, std::string caption2)
+{
+       pictures.push_back(Picture(pict,pwidth,pheight, banner, caption,caption2));
+}
+
+int WPictureView::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::DF_UP:
+    case Remote::UP:
+    {
+      if (cur_scroll_line > 0)
+      {
+         cur_scroll_line--;
+         rem_scroll_line++;
+         return 1;
+      }
+      else
+      {
+         return 4; // Signal return control to parent
+      }
+    }
+    case Remote::DF_DOWN:
+    case Remote::DOWN:
+    {
+       if (rem_scroll_line > 0)
+       {
+               cur_scroll_line++;
+               rem_scroll_line--;
+               return 1;
+       } else {
+               return 4;
+       }
+    }
+    case Remote::LEFT:
+    case Remote::RIGHT:
+    case Remote::DF_LEFT:
+    case Remote::DF_RIGHT:
+    {
+       return 5;
+    }
+
+  }
+
+  return 0;
+}
+
+WActorGallery::WActorGallery(Actors& actors)
+{
+       Actors::iterator itty=actors.begin();
+       float pixelaspect=Osd::getInstance()->getPixelAspect();
+       while (itty!= actors.end())
+       {
+               float aspect=((float)(*itty).thumb.height)/((float)(*itty).thumb.width)/pixelaspect;
+               float width= 100;
+               float height= aspect*width;
+
+               //Log::getInstance()->log("WActorGallery", Log::DEBUG, "TVMedia %d %d %g", (*itty).thumb.width,(*itty).thumb.height,aspect);
+               addPicture((*itty).thumb.info, width, height, false,(*itty).name,"\""+(*itty).role+"\"");
+               itty++;
+       }
+}
+
+WArtworkGallery::WArtworkGallery(MovieInfo& movie)
+{
+       float pixelaspect=Osd::getInstance()->getPixelAspect();
+       addTVMedia(movie.fanart);
+       addTVMedia(movie.collectionFanart);
+       addTVMedia(movie.collectionPoster);
+       addTVMedia(movie.poster);
+       const_height=400;
+}
+
+WArtworkGallery::WArtworkGallery(SeriesInfo& series)
+{
+       addTVMedia(series.seasonposter);
+       addTVMedia(series.episode.image);
+
+       addTVMedias(series.banners, true);
+       addTVMedias(series.fanart);
+       addTVMedias(series.posters);
+       const_height=400;
+}
+
+void WArtworkGallery::addTVMedias(TVMedias& medias, bool banner)
+{
+       if (medias.size()) {
+               TVMedias::iterator titty=medias.begin();
+               while (titty!=medias.end())
+               {
+                       addTVMedia(*titty, banner);
+                       titty++;
+               }
+
+       }
+}
+
+void WArtworkGallery::addTVMedia(TVMedia& media, bool banner)
+{
+       if (media.width)
+               addPicture(media.info, media.width, media.height, banner);
+}
diff --git a/wpictureview.h b/wpictureview.h
new file mode 100644 (file)
index 0000000..272299a
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+    Copyright 2005 Brian Walton (WTextBox)
+    Copyright 2014 Marten Richter (WPictureView)
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef WPICTUREVIEW_H
+#define WPICTUREVIEW_H
+
+#include <stdio.h>
+#include <string>
+#include <list>
+
+#include "defines.h"
+#include "boxx.h"
+
+class Colour;
+
+class WPictureView : public Boxx
+{
+  public:
+       WPictureView();
+    virtual ~WPictureView();
+    void addPicture(TVMediaInfo& pict,  float width, float height,bool banner=false, std::string caption ="", std::string caption2 ="");
+    void draw();
+    void setForegroundColour(const DrawStyle& fcolour);
+
+
+    // if added as a pane
+    int handleCommand(int command);
+
+  protected:
+    class Picture {
+    public:
+       Picture(TVMediaInfo tmedia,float width, float height, bool tbanner, std::string tcaption,  std::string tcaption2){
+               media=tmedia; caption=tcaption;caption2=tcaption2;w=width; h=height; banner=tbanner;
+       }
+
+       TVMediaInfo media;
+       std::string caption;
+       std::string caption2;
+       float w;
+       float h;
+       bool banner;
+    };
+    list<Picture> pictures;
+
+    DrawStyle foreColour;
+    unsigned int cur_scroll_line;
+    unsigned int rem_scroll_line;
+    unsigned int const_height; // if set only one per line
+};
+
+class WActorGallery : public WPictureView
+{
+public:
+       WActorGallery(Actors& actors);
+
+};
+
+class WArtworkGallery : public WPictureView
+{
+public:
+       WArtworkGallery(MovieInfo& movie);
+       WArtworkGallery(SeriesInfo& series);
+protected:
+       void addTVMedias(TVMedias& medias, bool banner=false);
+       void addTVMedia(TVMedia& media, bool banner=false);
+
+};
+
+#endif
diff --git a/wseriesview.cc b/wseriesview.cc
new file mode 100644 (file)
index 0000000..4a28d3e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#include "wseriesview.h"
+#include "i18n.h"
+#include <sstream>
+
+
+WSeriesView::WSeriesView(SeriesInfo* series):
+WTextbox(NULL)
+{
+       // portions from nopacity plugin by Louis Braun
+       if (series)
+       {
+               std::stringstream info;
+           info << tr("TheTVDB Information") << ":\n\n";
+
+           if (!series->episode.name.empty()) {
+               info << tr("Episode") << ": " << series->episode.name << " (" << tr("Season") << " " << series->episode.season << ", " << tr("Episode") << " " << series->episode.number << ")\n\n";
+           }
+           if (!series->episode.overview.empty()) {
+               info << tr("Episode Overview") << ": " << series->episode.overview << "\n\n";
+           }
+           if (!series->episode.firstAired.empty()) {
+               info << tr("First aired") << ": " << series->episode.firstAired << "\n\n";
+           }
+           if (!series->episode.guestStars.empty()) {
+               info << tr("Guest Stars") << ": " << series->episode.guestStars << "\n\n";
+           }
+           if (series->episode.rating > 0) {
+               info << tr("TheMovieDB Rating") << ": " << series->episode.rating << "\n\n";
+           }
+           if (!series->overview.empty()) {
+               info << tr("Series Overview") << ": " << series->overview << "\n\n";
+           }
+           if (!series->firstAired.empty()) {
+               info << tr("First aired") << ": " << series->firstAired << "\n\n";
+           }
+           if (!series->genre.empty()) {
+               info << tr("Genre") << ": " << series->genre << "\n\n";
+           }
+           if (!series->network.empty()) {
+               info << tr("Network") << ": " << series->network << "\n\n";
+           }
+           if (series->rating > 0) {
+               info << tr("TheMovieDB Rating") << ": " << series->rating << "\n\n";
+           }
+           if (!series->status.empty()) {
+               info << tr("Status") << ": " << series->status << "\n\n";
+           }
+           setText(info.str().c_str());
+       } else {
+               setText("This is a bug!");
+       }
+
+}
diff --git a/wseriesview.h b/wseriesview.h
new file mode 100644 (file)
index 0000000..0b9f715
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+    Copyright 2014 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+#ifndef WSERIESVIEW_H
+#define WSERIESIEW_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "defines.h"
+#include "wtextbox.h"
+#include "seriesinfo.h"
+
+class Colour;
+
+class WSeriesView : public WTextbox
+{
+  public:
+    WSeriesView(SeriesInfo* seriesinfo);
+
+
+  private:
+
+};
+
+#endif
index a33bae775d11d736cd9cc622777dc27647f6ef98..044a90af88b8aaa1975914d5382c99008f0f3936 100644 (file)
@@ -108,6 +108,7 @@ int WTabBar::handleCommand(int command)
       // 0 - not handled
       // 1 - handled - stop command here
       // 4 - handled - pane is returning control to here
+         // 5 - activate button bar and let button process the call, this for simple up and down scroll views
       // FIXME standardise these
       
     int paneRetCode = tabs[visiblePane].pane->handleCommand(command);
@@ -128,6 +129,14 @@ int WTabBar::handleCommand(int command)
       if (visiblePane != tabs.size() - 1) symbolRight.nextColour = DrawStyle::SELECTHIGHLIGHT;
       draw();
       return 1;
+    } else if (paneRetCode == 5)
+    {
+       buttonBarActive = true;
+       tabs[visiblePane].button->setActive(true);
+       if (visiblePane != 0) symbolLeft.nextColour = DrawStyle::SELECTHIGHLIGHT;
+       if (visiblePane != tabs.size() - 1) symbolRight.nextColour = DrawStyle::SELECTHIGHLIGHT;
+       draw();
+       // no return!
     }
   }
 
@@ -149,6 +158,8 @@ int WTabBar::handleCommand(int command)
         draw();
         return 1;
       }
+      case Remote::UP:
+      case Remote::DF_UP:
       case Remote::DOWN:
       case Remote::DF_DOWN:
       {
@@ -305,3 +316,17 @@ bool WTabBar::mouseLBDOWN(int x, int y) {
     return false;
 }
 
+void WTabBar::activateFocus(bool active)
+{
+       if (active)
+       {
+               tabs[visiblePane].button->setActive(true);
+               buttonBarActive = true;
+
+       } else {
+               tabs[visiblePane].button->setActive(false);
+               buttonBarActive = false;
+
+       }
+}
+
index db70ccd2cba6704ec82376526002ba92f56c4c37..bfd8d70239905b87bfaf91554a4c0c3243ca6303 100644 (file)
--- a/wtabbar.h
+++ b/wtabbar.h
@@ -45,6 +45,7 @@ class WTabBar : public Boxx
     int handleCommand(int command);
     bool mouseMove(int x, int y) ;
     bool mouseLBDOWN(int x, int y);
+    void activateFocus(bool active);
 
   private:
     bool left();
index 048bec041a5a6c532907b72240f7c12df3c25cec..7cb6045fd6d813540e1815d1bec767d0b90406fd 100644 (file)
@@ -21,6 +21,7 @@
 #include "wtextbox.h"
 
 #include "colour.h"
+#include "remote.h"
 
 WTextbox::WTextbox(const char* ttext):
 foreColour(DrawStyle::LIGHTTEXT)
@@ -37,6 +38,9 @@ foreColour(DrawStyle::LIGHTTEXT)
   paraMode = true;
   
   if (ttext) setText(ttext);
+
+  cur_scroll_line=0;
+  rem_scroll_line=0;
 }
 
 WTextbox::~WTextbox()
@@ -67,7 +71,7 @@ void WTextbox::draw()
   Boxx::draw();
   if (text)
   {
-    if (paraMode) drawPara(text, textX, textY, foreColour);
+    if (paraMode) rem_scroll_line=drawPara(text, textX, textY, foreColour,cur_scroll_line);
     else          drawText(text, textX, textY, foreColour);
   }
 }
@@ -77,3 +81,46 @@ void WTextbox::setTextPos(int x, int y)
   textX = x;
   textY = y;
 }
+
+int WTextbox::handleCommand(int command)
+{
+  switch(command)
+  {
+    case Remote::DF_UP:
+    case Remote::UP:
+    {
+      if (cur_scroll_line > 0)
+      {
+         cur_scroll_line--;
+         rem_scroll_line++;
+         return 1;
+      }
+      else
+      {
+         return 4; // Signal return control to parent
+      }
+    }
+    case Remote::DF_DOWN:
+    case Remote::DOWN:
+    {
+       if (rem_scroll_line > 0)
+       {
+               cur_scroll_line++;
+               rem_scroll_line--;
+               return 1;
+       } else {
+               return 4;
+       }
+    }
+    case Remote::LEFT:
+    case Remote::RIGHT:
+    case Remote::DF_LEFT:
+    case Remote::DF_RIGHT:
+    {
+       return 5;
+    }
+
+  }
+
+  return 0;
+}
index cc80935df74144cb6b42874f8fdcd2b05da08587..5003157f3dd645d7db2929f0bf6a730e9bf6a7dd 100644 (file)
@@ -40,6 +40,9 @@ class WTextbox : public Boxx
     void setTextPos(int x, int y); // optional
     void setParaMode(bool mode);
 
+    // if added as a pane
+    int handleCommand(int command);
+
   private:
 
     char* text;
@@ -47,6 +50,8 @@ class WTextbox : public Boxx
     int textX;
     int textY;
     bool paraMode;
+    unsigned int cur_scroll_line;
+    unsigned int rem_scroll_line;
 };
 
 #endif