nathan@0: /* nathan@0: * MP3/MPlayer plugin to VDR (C++) nathan@0: * nathan@0: * (C) 2001-2007 Stefan Huelswitt nathan@0: * nathan@0: * This code is free software; you can redistribute it and/or nathan@0: * modify it under the terms of the GNU General Public License nathan@0: * as published by the Free Software Foundation; either version 2 nathan@0: * of the License, or (at your option) any later version. nathan@0: * nathan@0: * This code is distributed in the hope that it will be useful, nathan@0: * but WITHOUT ANY WARRANTY; without even the implied warranty of nathan@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nathan@0: * GNU General Public License for more details. nathan@0: * nathan@0: * You should have received a copy of the GNU General Public License nathan@0: * along with this program; if not, write to the Free Software nathan@0: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. nathan@0: * Or, point your browser to http://www.gnu.org/copyleft/gpl.html nathan@0: */ nathan@0: nathan@0: #include nathan@0: #include nathan@0: #include nathan@0: #include nathan@0: #include nathan@0: #include nathan@0: #include nathan@0: #include nathan@0: #include nathan@0: nathan@0: #include "common.h" nathan@0: #include "menu.h" nathan@0: #include "data.h" nathan@0: #include "data-src.h" nathan@0: #include "i18n.h" nathan@0: nathan@0: // ----------------------------------------------------------------------------- nathan@0: nathan@0: void Status(const char *text) nathan@0: { nathan@0: #if APIVERSNUM >= 10307 nathan@0: Skins.Message(mtStatus,text); nathan@0: #else nathan@0: if(text) { nathan@0: Interface->Status(text); nathan@0: Interface->Flush(); nathan@0: } nathan@0: #endif nathan@0: } nathan@0: nathan@0: void Error(const char *text) nathan@0: { nathan@0: #if APIVERSNUM >= 10307 nathan@0: Skins.Message(mtError,text); nathan@0: #else nathan@0: Interface->Error(text); nathan@0: #endif nathan@0: } nathan@0: nathan@0: void Info(const char *text) nathan@0: { nathan@0: #if APIVERSNUM >= 10307 nathan@0: Skins.Message(mtInfo,text); nathan@0: #else nathan@0: Interface->Info(text); nathan@0: #endif nathan@0: } nathan@0: nathan@0: // --- cMenuBrowseItem --------------------------------------------------------- nathan@0: nathan@0: class cMenuBrowseItem : public cOsdItem { nathan@0: private: nathan@0: cFileObj *item; nathan@0: virtual void Set(void); nathan@0: public: nathan@0: cMenuBrowseItem(cFileObj *Item); nathan@0: cFileObj *Item(void) { return item; } nathan@0: }; nathan@0: nathan@0: cMenuBrowseItem::cMenuBrowseItem(cFileObj *Item) nathan@0: { nathan@0: item = Item; nathan@0: Set(); nathan@0: } nathan@0: nathan@0: void cMenuBrowseItem::Set(void) nathan@0: { nathan@0: char *buffer=0; nathan@0: asprintf(&buffer,item->Type()==otFile?"%s":"[%s]",item->Name()); nathan@0: SetText(buffer,false); nathan@0: } nathan@0: nathan@0: // --- cMenuBrowse ------------------------------------------------------ nathan@0: nathan@0: cFileObj *cMenuBrowse::lastselect=0; nathan@0: nathan@0: cMenuBrowse::cMenuBrowse(cFileSource *Source, bool Dirselect, bool WithID3, const char *title, const char * const *Excl) nathan@0: :cOsdMenu(title) nathan@0: { nathan@0: currentdir=parent=0; nathan@0: delete lastselect; lastselect=0; nathan@0: list=new cDirList; nathan@0: nathan@0: dirselectable=Dirselect; nathan@0: withID3=WithID3; nathan@0: excl=Excl; nathan@0: nathan@0: SetSource(Source); nathan@0: NewDir(currentdir); nathan@0: } nathan@0: nathan@0: cMenuBrowse::~cMenuBrowse() nathan@0: { nathan@0: free(parent); nathan@0: free(currentdir); nathan@0: delete list; nathan@0: } nathan@0: nathan@0: cFileObj *cMenuBrowse::CurrentItem(void) nathan@0: { nathan@0: cMenuBrowseItem *item = (cMenuBrowseItem *)Get(Current()); nathan@0: return item ? item->Item():0; nathan@0: } nathan@0: nathan@0: void cMenuBrowse::SetButtons(void) nathan@0: { nathan@0: SetHelp(tr("Select"), currentdir?tr("Parent"):0, 0, withID3?tr("ID3 info"):0); nathan@0: Display(); nathan@0: } nathan@0: nathan@0: void cMenuBrowse::SetSource(cFileSource *Source) nathan@0: { nathan@0: source=Source; nathan@0: free(currentdir); currentdir=0; nathan@0: free(parent); parent=0; nathan@0: source->GetRemember(currentdir,parent); nathan@0: } nathan@0: nathan@0: bool cMenuBrowse::LoadDir(const char *dir) nathan@0: { nathan@0: Clear(); nathan@0: Status(tr("Scanning directory...")); nathan@0: bool res=list->Load(source,dir,excl); nathan@0: if(res) { nathan@0: cFileObj *item=list->First(); nathan@0: while(item) { nathan@0: Add(new cMenuBrowseItem(item),(parent && !strcmp(item->Name(),parent))); nathan@0: item=list->Next(item); nathan@0: } nathan@0: } nathan@0: Status(0); nathan@0: return res; nathan@0: } nathan@0: nathan@0: bool cMenuBrowse::NewDir(const char *dir) nathan@0: { nathan@0: char *ncur=dir ? strdup(dir):0; nathan@0: bool r=LoadDir(ncur); nathan@0: if(!r && ncur) { nathan@0: free(ncur); ncur=0; nathan@0: r=LoadDir(ncur); nathan@0: } nathan@0: if(r) { nathan@0: free(currentdir); currentdir=ncur; nathan@0: nathan@0: cFileObj *item=CurrentItem(); nathan@0: source->SetRemember(currentdir,item?item->Name():0); nathan@0: nathan@0: SetButtons(); nathan@0: return true; nathan@0: } nathan@0: free(ncur); nathan@0: Error(tr("Error scanning directory!")); nathan@0: return false; nathan@0: } nathan@0: nathan@0: eOSState cMenuBrowse::Parent(void) nathan@0: { nathan@0: eOSState res=osContinue; nathan@0: nathan@0: if(currentdir) { nathan@0: free(parent); nathan@0: char *ss=strrchr(currentdir,'/'); nathan@0: if(ss) { nathan@0: *ss++=0; nathan@0: parent=strdup(ss); nathan@0: ss=currentdir; nathan@0: } nathan@0: else parent=strdup(currentdir); nathan@0: nathan@0: if(!NewDir(ss)) res=osEnd; nathan@0: } nathan@0: return res; nathan@0: } nathan@0: nathan@0: eOSState cMenuBrowse::Select(bool isred) nathan@0: { nathan@0: eOSState res=osContinue; nathan@0: cFileObj *item; nathan@0: nathan@0: if((item=CurrentItem())) { nathan@0: switch(item->Type()) { nathan@0: case otParent: nathan@0: if(!isred || !dirselectable) nathan@0: res=Parent(); nathan@0: break; nathan@0: case otDir: nathan@0: if(!isred || !dirselectable) { nathan@0: if(!NewDir(item->Path())) res=osEnd; nathan@0: break; nathan@0: } nathan@0: // fall through to otFile nathan@0: case otFile: nathan@0: lastselect=new cFileObj(item); nathan@0: res=osBack; nathan@0: break; nathan@0: default: nathan@0: break; nathan@0: } nathan@0: } nathan@0: return res; nathan@0: } nathan@0: nathan@0: eOSState cMenuBrowse::ID3Info(void) nathan@0: { nathan@0: return osContinue; nathan@0: } nathan@0: nathan@0: eOSState cMenuBrowse::ProcessStdKey(eKeys Key, eOSState state) nathan@0: { nathan@0: if(state==osUnknown) { nathan@0: switch (Key) { nathan@0: case kOk: state=Select(false); break; nathan@0: case kRed: state=Select(true); break; nathan@0: case kGreen: state=Parent(); break; nathan@0: case kBlue: if(withID3) state=ID3Info(); nathan@0: break; nathan@0: //case kMenu: state=osEnd; break; nathan@0: default: break; nathan@0: } nathan@0: } nathan@0: if(state==osEnd || state==osBack) { nathan@0: cFileObj *item=CurrentItem(); nathan@0: if(item) source->SetRemember(currentdir,item->Name()); nathan@0: } nathan@0: return state; nathan@0: } nathan@0: nathan@0: // --- cMenuSourceItem ---------------------------------------------------------- nathan@0: nathan@0: class cMenuSourceItem : public cOsdItem { nathan@0: private: nathan@0: cFileSource *source; nathan@0: virtual void Set(void); nathan@0: public: nathan@0: cMenuSourceItem(cFileSource *Source); nathan@0: cFileSource *Source(void) { return source; } nathan@0: }; nathan@0: nathan@0: cMenuSourceItem::cMenuSourceItem(cFileSource *Source) nathan@0: { nathan@0: source=Source; nathan@0: Set(); nathan@0: } nathan@0: nathan@0: void cMenuSourceItem::Set(void) nathan@0: { nathan@0: char *buffer=0; nathan@0: asprintf(&buffer, "%s\t%s\t%s", source->NeedsMount()?(source->Status()?"*":">"):"", source->Description(), source->BaseDir()); nathan@0: SetText(buffer,false); nathan@0: } nathan@0: nathan@0: // --- cMenuSource -------------------------------------------------- nathan@0: nathan@0: cFileSource *cMenuSource::selected=0; nathan@0: nathan@0: cMenuSource::cMenuSource(cFileSources *Sources, const char *title) nathan@0: :cOsdMenu(title,2,20) nathan@0: { nathan@0: selected=0; nathan@0: current=Sources->GetSource(); nathan@0: cFileSource *source=Sources->First(); nathan@0: while(source) { nathan@0: cOsdMenu::Add(new cMenuSourceItem(source),source==current); nathan@0: source=Sources->Next(source); nathan@0: } nathan@0: nathan@0: SetHelp(tr("Select"), tr("Mount"), tr("Unmount"), tr("Eject")); nathan@0: Display(); nathan@0: } nathan@0: nathan@0: bool cMenuSource::DoMount(cFileSource *src) nathan@0: { nathan@0: bool res=src->Mount(); nathan@0: RefreshCurrent(); nathan@0: DisplayCurrent(true); nathan@0: return res; nathan@0: } nathan@0: nathan@0: bool cMenuSource::CheckMount(void) nathan@0: { nathan@0: cFileSource *src=selected ? selected:current; nathan@0: if(src->NeedsMount() && !src->Status()) { nathan@0: Error(tr("Selected source is not mounted!")); nathan@0: return false; nathan@0: } nathan@0: return true; nathan@0: } nathan@0: nathan@0: eOSState cMenuSource::Select(void) nathan@0: { nathan@0: if(HasSubMenu() || Count() == 0) return osContinue; nathan@0: nathan@0: cFileSource *src = ((cMenuSourceItem *)Get(Current()))->Source(); nathan@0: if(src->NeedsMount() && !src->Status()) { nathan@0: if(!DoMount(src)) Error(tr("Mount failed!")); nathan@0: } nathan@0: if(!src->NeedsMount() || src->Status()) { nathan@0: selected=src; nathan@0: return osBack; nathan@0: } nathan@0: return osContinue; nathan@0: } nathan@0: nathan@0: eOSState cMenuSource::Mount(void) nathan@0: { nathan@0: if(HasSubMenu() || Count() == 0) return osContinue; nathan@0: nathan@0: cFileSource *src = ((cMenuSourceItem *)Get(Current()))->Source(); nathan@0: if(src->NeedsMount() && !src->Status()) { nathan@0: if(DoMount(src)) Info(tr("Mount succeeded")); nathan@0: else Error(tr("Mount failed!")); nathan@0: } nathan@0: return osContinue; nathan@0: } nathan@0: nathan@0: eOSState cMenuSource::Unmount(void) nathan@0: { nathan@0: if(HasSubMenu() || Count() == 0) return osContinue; nathan@0: nathan@0: cFileSource *src = ((cMenuSourceItem *)Get(Current()))->Source(); nathan@0: if(src->NeedsMount() && src->Status()) { nathan@0: bool res=src->Unmount(); nathan@0: RefreshCurrent(); nathan@0: DisplayCurrent(true); nathan@0: if(res) Info(tr("Unmount succeeded")); nathan@0: else Error(tr("Unmount failed!")); nathan@0: } nathan@0: return osContinue; nathan@0: } nathan@0: nathan@0: eOSState cMenuSource::Eject(void) nathan@0: { nathan@0: if(HasSubMenu() || Count() == 0) return osContinue; nathan@0: nathan@0: cFileSource *src = ((cMenuSourceItem *)Get(Current()))->Source(); nathan@0: if(src->NeedsMount()) { nathan@0: bool res=src->Eject(); nathan@0: RefreshCurrent(); nathan@0: DisplayCurrent(true); nathan@0: if(!res) Error(tr("Eject failed!")); nathan@0: } nathan@0: return osContinue; nathan@0: } nathan@0: nathan@0: eOSState cMenuSource::ProcessKey(eKeys Key) nathan@0: { nathan@0: eOSState state = cOsdMenu::ProcessKey(Key); nathan@0: nathan@0: if(state==osBack && !CheckMount()) state=osContinue; nathan@0: if(state==osUnknown) { nathan@0: switch(Key) { nathan@0: case kOk: nathan@0: case kRed: return Select(); nathan@0: case kGreen: return Mount(); nathan@0: case kYellow: return Unmount(); nathan@0: case kBlue: return Eject(); nathan@0: case kMenu: CheckMount(); return osEnd; nathan@0: default: break; nathan@0: } nathan@0: } nathan@0: return state; nathan@0: } nathan@0: nathan@0: // --- cProgressBar ------------------------------------------------------------ nathan@0: nathan@0: cProgressBar::cProgressBar(int Width, int Height, int Current, int Total) nathan@0: :cBitmap(Width, Height, 2) nathan@0: { nathan@0: if(Total > 0) { nathan@0: int p = Current * Width / Total;; nathan@0: #if APIVERSNUM >= 10307 nathan@0: DrawRectangle(0, 0, p, Height - 1, clrGreen); nathan@0: DrawRectangle(p + 1, 0, Width - 1, Height - 1, clrWhite); nathan@0: #else nathan@0: Fill(0, 0, p, Height - 1, clrGreen); nathan@0: Fill(p + 1, 0, Width - 1, Height - 1, clrWhite); nathan@0: #endif nathan@0: } nathan@0: } nathan@0: