OBJECTS = main.o command.o log.o remote.o led.o mtd.o video.o audio.o tcp.o directory.o thread.o event.o \
player.o demuxer.o stream.o vfeed.o afeed.o afeedr.o osd.o surface.o viewman.o vdr.o dsock.o box.o \
- recording.o channel.o message.o playervideo.o messagequeue.o rectimer.o vtimeredit.o \
+ recording.o channel.o message.o playervideo.o messagequeue.o rectimer.o vtimeredit.o voptionsmenu.o \
view.o vinfo.o vwallpaper.o vvolume.o vrecordinglist.o vlivebanner.o vmute.o vtimerlist.o \
vrecordingmenu.o vquestion.o vchannellist.o vwelcome.o vvideolive.o vvideorec.o \
vchannelselect.o vserverselect.o colour.o vconnect.o voptions.o vepg.o region.o \
typedef unsigned long ULONG;
typedef unsigned long long ULLONG;
+#define OPTIONTYPE_TEXT 1
+#define OPTIONTYPE_INT 2
+
//#define SCREENWIDTH 720
//#define SCREENHEIGHT 576
//#define SCREENHEIGHT 480
const static ULONG TIMER = 15;
const static ULONG EPG = 16;
const static ULONG EPG_CLOSE = 17;
+ const static ULONG CHANGED_OPTIONS = 18;
};
#endif
#include <pthread.h>
#include <signal.h>
-#include <stdio.h> // temp
-
class Thread
{
protected:
freePacket();
pthread_mutex_unlock(&mutex);
+ // Sort the directory order
+ sort(recDir->dirList.begin(), recDir->dirList.end(), DirectorySorter());
+
+ // Sort all the sub lists
+
+ Directory* sortDir;
+ DirectoryList::iterator i;
+ for (i = recDir->dirList.begin(); i != recDir->dirList.end(); i++)
+ {
+ sortDir = *i;
+ sort(sortDir->recList.begin(), sortDir->recList.end(), RecordingSorter());
+ }
+
+ // Sort the root level list
sort(recDir->recList.begin(), recDir->recList.end(), RecordingSorter());
return recDir;
}
};
+struct DirectorySorter
+{
+ bool operator() (const Directory* a, const Directory* b)
+ {
+ int c = strcmp(b->name, a->name);
+ if (c > 0) return true;
+ return false;
+ }
+};
+
class VDR
{
}\r
case Remote::RECORD:\r
{\r
+ Log::getInstance()->log("VEPG", Log::DEBUG, "ID %lu TIME %lu DURATION %lu TITLE %s\n", thisEvent.id, thisEvent.time, thisEvent.duration, thisEvent.title);
+
//TODO FIXME\r
return 2;\r
}\r
return surface->create(area.w, area.h);
}
-void View::setTitleText(char* takeText)
+void View::setTitleText(const char* takeText)
{
int length = strlen(takeText);
titleText = new char[length + 1];
void setBorderOn(UCHAR on);
void setTitleBarOn(UCHAR on);
- void setTitleText(char* title);
+ void setTitleText(const char* title);
void setBackgroundColour(Colour& colour);
void setTitleBarColour(Colour& colour);
#include "voptions.h"
-VOptions::VOptions(VWelcome* tvwelcome)
+VOptions::VOptions(View* tparent, const char* title, const OPTIONDATA* toptionData, const int tnumOptions)
{
- vwelcome = tvwelcome;
viewman = ViewMan::getInstance();
- create(530, 85+(NUM_OPTIONS*30));
- if (Video::getInstance()->getFormat() == Video::PAL)
- {
- setScreenPos(104, 130);
- }
- else
- {
- setScreenPos(94, 70);
- }
+ parent = tparent;
+ optionData = toptionData;
+ numOptions = tnumOptions;
+
+ create(530, 85 + (numOptions * 30));
setBackgroundColour(Colour::VIEWBACKGROUND);
setTitleBarOn(1);
setTitleBarColour(Colour::TITLEBARBACKGROUND);
- setTitleText(tr("Options"));
+ setTitleText(title);
int fontHeight = surface->getFontHeight();
- UINT i;
- for (i = 0; i < numOptions; i++)
- {
- optionBox[i].setSurface(surface);
- optionBox[i].setSurfaceOffset(346, 45 + (i * 30));
- optionBox[i].setDimensions(150, fontHeight);
- for (UINT j = 0; j < optionData[i].optionCount; j++)
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Add option: %s", optionData[i].options[j]);
- optionBox[i].addOption(tr((char*)optionData[i].options[j]));
- }
- }
+ optionBoxes = new WOptionBox[numOptions];
+ UINT i, j;
char* config;
vdr = VDR::getInstance();
+ // After setup, save all current indexes
+ optionsAtStart = new int[numOptions];
for (i = 0; i < numOptions; i++)
{
- optionBox[i].setSelected(tr((char*)optionData[i].options[optionData[i].defaultOption]));
+ optionBoxes[i].setSurface(surface);
+ optionBoxes[i].setSurfaceOffset(346, 45 + (i * 30));
+ optionBoxes[i].setDimensions(150, fontHeight);
+
+ if (optionData[i].optionType == OPTIONTYPE_TEXT)
+ {
+ for (j = 0; j < optionData[i].optionCount; j++)
+ {
+ Log::getInstance()->log("Options", Log::DEBUG, "Add option: %s", optionData[i].options[j]);
+ optionBoxes[i].addOption(tr((char*)optionData[i].options[j]));
+ }
+
+ // Set the built in default
+ optionBoxes[i].setSelected(tr((char*)optionData[i].options[optionData[i].defaultOption]));
+ }
+ else
+ {
+ // int mode
+ optionBoxes[i].setIntMode(optionData[i].startInt, optionData[i].optionCount);
+ optionBoxes[i].setSelected(optionData[i].defaultOption);
+ }
+
+ // Now see if there is a config option for it
config = vdr->configLoad(optionData[i].configSection, optionData[i].configParam);
if (config)
{
- for (UINT j = 0; j < optionData[i].optionCount; j++)
+ if (optionData[i].optionType == OPTIONTYPE_TEXT)
{
- if (!strcasecmp(config, optionData[i].options[j]))
+ for (j = 0; j < optionData[i].optionCount; j++)
{
- optionBox[i].setSelected(tr((char*)optionData[i].options[j]));
+ if (!strcasecmp(config, optionData[i].options[j]))
+ {
+ optionBoxes[i].setSelected(tr((char*)optionData[i].options[j]));
+ }
}
}
+ else
+ {
+ optionBoxes[i].setSelected(atoi(config));
+ }
delete[] config;
}
+
+ // After setup, save initial option
+ optionsAtStart[i] = optionBoxes[i].getSelectedIndex();
}
- // After setup, save all current indexes
- optionsAtStart = new int[numOptions];
+ selectedOption = 0;
+ optionBoxes[0].setActive(1);
- for (i = 0; i < numOptions; i++)
+ int voff = 0;
+ if ((numOptions < 8) && (numOptions >= 4))
+ {
+ voff = (8 - numOptions) * 10;
+ }
+ else if (numOptions < 4)
{
- optionsAtStart[i] = optionBox[i].getSelectedIndex();
+ voff = 40; //(4 * 10)
}
- selectedOption = 0;
- optionBox[0].setActive(1);
+ if (Video::getInstance()->getFormat() == Video::PAL)
+ {
+ setScreenPos(104, 130 + voff);
+ }
+ else
+ {
+ setScreenPos(94, 70 + voff);
+ }
}
VOptions::~VOptions()
{
delete[] optionsAtStart;
+ delete[] optionBoxes;
}
void VOptions::draw()
wsy.nextSymbol = WSymbol::RIGHTARROW;
wsy.setSurfaceOffset(498, 47 + (i * 30));
wsy.draw();
- optionBox[i].draw();
+ optionBoxes[i].draw();
}
}
{
if (selectedOption > 0)
{
- optionBox[selectedOption].setActive(0);
+ optionBoxes[selectedOption].setActive(0);
--selectedOption;
- optionBox[selectedOption].setActive(1);
+ optionBoxes[selectedOption].setActive(1);
draw();
viewman->updateView(this);
}
{
if (selectedOption < (numOptions - 1))
{
- optionBox[selectedOption].setActive(0);
+ optionBoxes[selectedOption].setActive(0);
++selectedOption;
- optionBox[selectedOption].setActive(1);
+ optionBoxes[selectedOption].setActive(1);
draw();
viewman->updateView(this);
}
case Remote::DF_LEFT:
case Remote::LEFT:
{
- optionBox[selectedOption].left();
+ optionBoxes[selectedOption].left();
draw();
viewman->updateView(this);
return 2;
case Remote::DF_RIGHT:
case Remote::RIGHT:
{
- optionBox[selectedOption].right();
+ optionBoxes[selectedOption].right();
draw();
viewman->updateView(this);
return 2;
case Remote::BACK:
{
doSave();
- return 4;
+
+ // Instead of returning 4 here which would delete this view
+ // before the doSave message is processed, let the message queue
+ // do the doSave then this close message. That will make the options menu
+ // disappear before this view
+
+ Message* m = new Message();
+ m->message = Message::CLOSE_ME;
+ m->from = this;
+ m->to = viewman;
+ viewman->postMessage(m);
+
+ return 2;
}
case Remote::OK:
{
- optionBox[selectedOption].cycle();
+ optionBoxes[selectedOption].cycle();
draw();
viewman->updateView(this);
}
void VOptions::doSave()
{
+ UINT i;
int result[numOptions];
- for (UINT i = 0; i < numOptions; i++)
+ for (i = 0; i < numOptions; i++)
{
- result[i] = optionBox[i].getSelectedIndex();
+ result[i] = optionBoxes[i].getSelectedIndex();
if (result[i] != optionsAtStart[i])
{
Log::getInstance()->log("Options", Log::DEBUG, "Option %i has changed", i);
- vdr->configSave(optionData[i].configSection, optionData[i].configParam,
- optionData[i].options[result[i]]);
+ if (optionData[i].optionType == OPTIONTYPE_TEXT)
+ {
+ vdr->configSave(optionData[i].configSection, optionData[i].configParam,
+ optionData[i].options[result[i]]);
+ }
+ else
+ {
+ char buffer[20];
+ sprintf(buffer, "%i", result[i]);
+ vdr->configSave(optionData[i].configSection, optionData[i].configParam,
+ buffer);
+ }
}
}
- // Apply changes
- Video* video = Video::getInstance();
-
- if (result[0] != optionsAtStart[0])
- {
- if (result[0] == 1)
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Setting New Remote");
- Remote::getInstance()->setRemoteType(Remote::NEWREMOTE);
- }
- else
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Setting Old Remote");
- Remote::getInstance()->setRemoteType(Remote::OLDREMOTE);
- }
- }
+ // Save a vector of option IDs that have changed
- if (result[1] != optionsAtStart[1])
- {
- I18n::initialize();
- vwelcome->redrawLang();
- }
+ map<int, int>* optionChanges = new map<int, int>;
- if (result[2] != optionsAtStart[2])
+ for (i = 0; i < numOptions; i++)
{
- if (result[2] == 1)
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Setting S-Video");
- video->setConnection(Video::SVIDEO);
- }
- else
+ if (result[i] != optionsAtStart[i])
{
- Log::getInstance()->log("Options", Log::DEBUG, "Setting RGB/Composite");
- video->setConnection(Video::COMPOSITERGB);
+ (*optionChanges)[optionData[i].id] = result[i];
}
}
- if (result[3] != optionsAtStart[3])
- {
- if (result[3] == 1)
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Setting 16:9 TV");
- video->setTVsize(Video::ASPECT16X9);
- }
- else
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Setting 4:3 TV");
- video->setTVsize(Video::ASPECT4X3);
- }
- }
+ // Send it to parent for changes to be applied
+ Message* m = new Message();
+ m->message = Message::CHANGED_OPTIONS;
+ m->to = parent;
+ m->parameter = (ULONG)optionChanges;
+ viewman->postMessage(m);
- if (result[4] != optionsAtStart[4])
- {
- if (result[4] == 1)
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Setting letterbox");
- video->setMode(Video::LETTERBOX);
- }
- else
- {
- Log::getInstance()->log("Options", Log::DEBUG, "Setting chop-sides");
- video->setMode(Video::NORMAL);
- }
- }
}
#ifndef VOPTIONS_H
#define VOPTIONS_H
+#include <map>
#include "view.h"
-#include "remote.h"
#include "viewman.h"
#include "vdr.h"
#include "colour.h"
#include "woptionbox.h"
#include "wsymbol.h"
#include "i18n.h"
-#include "vwelcome.h"
-#define NUM_OPTIONS 8
typedef struct
{
+ UINT id; // Used for working out what has changed at the end
char *title; // Name of the option
char *configSection; // Which section of the config file
char *configParam; // Parameter name in the config file
+ UINT optionType; // 1 for text, 2 for int
UINT optionCount; // How many choices?
- UINT defaultOption; // Serial of the default choice (base 0)
- const char * const * options; // Text for the options
+ UINT defaultOption; // Serial of the default choice (base 0), or actual option in int mode
+ int startInt; // Starting int for int mode
+ const char * const * options; // Text for the options (null for int mode)
} OPTIONDATA;
-static const char* options0[] = {"Old", "New"};
-static const char* options1[] = {"RGB+composite", "S-Video"};
-static const char* options2[] = {"4:3", "16:9"};
-static const char* options3[] = {"Chop sides", "Letterbox"};
-static const char* options4[] = {"On", "Off", "Last state"};
-static const char* options5[] = {"All", "FTA only"};
-static const char* options6[] = {"0", "5", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "99"};
-
-const static OPTIONDATA optionData[NUM_OPTIONS] =
-{
- {"Remote control type", "General", "Remote type", 2, 0, options0 },
- {"Language", "General", "Language", I18n::NumLanguages, 0, I18n::Languages },
- {"TV connection type", "TV", "Connection", 2, 0, options1 },
- {"TV aspect ratio", "TV", "Aspect", 2, 0, options2 },
- {"16:9 on 4:3 display mode", "TV", "Widemode", 2, 0, options3 },
- {"Power state after bootup", "General", "Power After Boot", 3, 0, options4 },
- {"Display channels", "General", "Channels", 2, 0, options5 },
- {"VDR-Pri 0=OK !See forums!","General", "Live priority", 21, 0, options6 }
-};
-
-class VWelcome;
-
class VOptions : public View
{
public:
- VOptions(VWelcome* tvwelcome);
+ VOptions(View* tparent, const char* title, const OPTIONDATA* toptionData, const int tnumOptions);
~VOptions();
int handleCommand(int command);
private:
void doSave();
- const static UINT numOptions = NUM_OPTIONS;
+ const OPTIONDATA* optionData;
+ UINT numOptions;
UINT selectedOption;
- WOptionBox optionBox[numOptions];
+ WOptionBox* optionBoxes;
VDR* vdr;
int* optionsAtStart;
ViewMan* viewman;
- VWelcome* vwelcome;
+ View* parent;
};
#endif
#include "vwelcome.h"
+VWelcome* VWelcome::instance = NULL;
+
VWelcome::VWelcome()
{
+ instance = this;
+
viewman = ViewMan::getInstance();
clockRegion.x = 400;
VWelcome::~VWelcome()
{
+ instance = NULL;
Timers::getInstance()->cancelTimer(this, 1);
}
+VWelcome* VWelcome::getInstance()
+{
+ return instance;
+}
+
void VWelcome::setup()
{
sl.clear();
void VWelcome::doOptions()
{
- VOptions* voptions = new VOptions(this);
- voptions->draw();
- viewman->add(voptions);
- viewman->updateView(voptions);
+ VOptionsMenu* voptionsmenu = new VOptionsMenu();
+ voptionsmenu->draw();
+ viewman->add(voptionsmenu);
+ viewman->updateView(voptionsmenu);
}
void VWelcome::redrawLang()
#include "message.h"
#include "colour.h"
#include "video.h"
-#include "voptions.h"
+#include "voptionsmenu.h"
#include "i18n.h"
#include "timers.h"
+// FIXME - take out singleton when broadcast messages exist
+
class VWelcome : public View, public TimerReceiver
{
public:
VWelcome();
~VWelcome();
+ static VWelcome* getInstance();
void setup();
int handleCommand(int command);
void redrawLang();
private:
+ static VWelcome* instance;
+
WSelectList sl;
WJpeg jpeg;
mytext = NULL;
active = 0;
+ tag = 0;
}
WButton::~WButton()
drawText(mytext, 0, 0, Colour::LIGHTTEXT);
}
}
+
+void WButton::setTag(int newTag)
+{
+ tag = newTag;
+}
+
+int WButton::getTag()
+{
+ return tag;
+}
void setText(char* text);
void setActive(UCHAR tactive);
void draw();
+ void setTag(int tag);
+ int getTag();
private:
UCHAR active;
char* mytext;
+ int tag;
};
#endif
options = NULL;
active = 0;
currentOption = 0;
+
+ mode = MODE_TEXT;
}
WOptionBox::~WOptionBox()
int length = strlen(takeText);
char* newOption = new char[length + 1];
strcpy(newOption, takeText);
-
- Log::getInstance()->log("Temp", Log::DEBUG, "About to realloc, num Options=%i, current options = %p, new text = %s", numOptions, options, newOption);
-
options = (char**)realloc(options, (numOptions+1) * sizeof(char*));
- Log::getInstance()->log("Temp", Log::DEBUG, "");
-
options[numOptions] = newOption;
-
numOptions++;
}
currentOption = 0;
}
-char* WOptionBox::getSelected()
+//char* WOptionBox::getSelected()
+//{
+// return options[currentOption];
+//}
+
+int WOptionBox::getSelectedIndex()
{
- return options[currentOption];
+ if (mode == MODE_TEXT)
+ {
+ return currentOption;
+ }
+ else
+ {
+ return atoi(options[currentOption]);
+ }
}
-int WOptionBox::getSelectedIndex()
+void WOptionBox::setIntMode(int startInt, int setNumOptions)
+{
+ mode = MODE_INT;
+
+ int cInt;
+ char buffer[20];
+
+ for (cInt = startInt; cInt < (startInt + setNumOptions); cInt++)
+ {
+ sprintf(buffer, "%i", cInt);
+ addOption(buffer);
+ }
+}
+
+void WOptionBox::setSelected(int toSelect)
{
- return currentOption;
+ for(UINT i = 0; i < numOptions; i++)
+ {
+ if (atoi(options[i]) == toSelect)
+ {
+ currentOption = i;
+ return;
+ }
+ }
+ currentOption = 0;
}
public:
WOptionBox();
~WOptionBox();
+
+ // Int mode stuff
+ void setIntMode(int start, int numOptions);
+ void setSelected(int newSelection);
+
void addOption(const char* newOption);
void setSelected(const char* selectedOption);
- char* getSelected();
+// char* getSelected();
void setActive(UCHAR tactive);
void left();
void right();
void draw();
int getSelectedIndex();
+ const static int MODE_TEXT = 1;
+ const static int MODE_INT = 2;
+
private:
UCHAR active;
UINT numOptions;
char** options;
UINT currentOption;
+
+ int mode;
};
#endif