Playlist.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "stdafx.h"
00023 #include "mplayerc.h"
00024 #include "playlist.h"
00025 
00026 //
00027 // CPlaylistItem
00028 //
00029 
00030 UINT CPlaylistItem::m_globalid  = 0;
00031 
00032 CPlaylistItem::CPlaylistItem()
00033         : m_type(file)
00034         , m_fInvalid(false)
00035         , m_duration(0)
00036         , m_vinput(-1)
00037         , m_vchannel(-1)
00038         , m_ainput(-1)
00039 {
00040         m_id = m_globalid++;
00041 }
00042 
00043 CPlaylistItem::~CPlaylistItem()
00044 {
00045 }
00046 
00047 CPlaylistItem::CPlaylistItem(const CPlaylistItem& pli)
00048 {
00049         *this = pli;
00050 }
00051 
00052 CPlaylistItem& CPlaylistItem::operator = (const CPlaylistItem& pli)
00053 {
00054         m_id = pli.m_id;
00055         m_label = pli.m_label;
00056         m_fns.RemoveAll();
00057         m_fns.AddTail((CList<CString>*)&pli.m_fns);
00058         m_subs.RemoveAll();
00059         m_subs.AddTail((CList<CString>*)&pli.m_subs);
00060         m_type = pli.m_type;
00061         m_fInvalid = pli.m_fInvalid;
00062         m_duration = pli.m_duration;
00063         m_vinput = pli.m_vinput;
00064         m_vchannel = pli.m_vchannel;
00065         m_ainput = pli.m_ainput;
00066         return(*this);
00067 }
00068 
00069 POSITION CPlaylistItem::FindFile(CString path)
00070 {
00071         POSITION pos = m_fns.GetHeadPosition();
00072         while(pos && !m_fns.GetAt(pos).CompareNoCase(path)) m_fns.GetNext(pos);
00073         return(NULL);
00074 }
00075 
00076 static CString StripPath(CString path)
00077 {
00078         CString p = path;
00079         p.Replace('\\', '/');
00080         p = p.Mid(p.ReverseFind('/')+1);
00081         return(p.IsEmpty() ? path : p);
00082 }
00083 
00084 CString CPlaylistItem::GetLabel(int i)
00085 {
00086         CString str;
00087 
00088         if(i == 0)
00089         {
00090                 if(!m_label.IsEmpty()) str = m_label;
00091                 else if(!m_fns.IsEmpty()) str = StripPath(m_fns.GetHead());
00092         }
00093         else if(i == 1)
00094         {
00095                 if(m_fInvalid) return _T("Invalid");
00096 
00097                 if(m_type == file)
00098                 {
00099                         REFERENCE_TIME rt = m_duration;
00100 
00101                         if(rt > 0)
00102                         {
00103                                 rt /= 10000000;
00104                                 int ss = int(rt%60);
00105                                 rt /= 60;
00106                                 int mm = int(rt%60);
00107                                 rt /= 60;
00108                                 int hh = int(rt);
00109 
00110                                 str.Format(_T("%02d:%02d:%02d"), hh, mm, ss);
00111                         }
00112                 }
00113                 else if(m_type == device)
00114                 {
00115                         // TODO
00116                 }
00117 
00118         }
00119 
00120         return str;
00121 }
00122 
00123 //
00124 // CPlaylist
00125 //
00126 
00127 CPlaylist::CPlaylist()
00128         : m_pos(NULL)
00129 {
00130 }
00131 
00132 CPlaylist::~CPlaylist()
00133 {
00134 }
00135 
00136 void CPlaylist::RemoveAll()
00137 {
00138         __super::RemoveAll();
00139         m_pos = NULL;
00140 }
00141 
00142 bool CPlaylist::RemoveAt(POSITION pos)
00143 {
00144         if(pos)
00145         {
00146                 __super::RemoveAt(pos);
00147                 if(m_pos == pos) {m_pos = NULL; return(true);}
00148         }
00149 
00150         return(false);
00151 }
00152 
00153 typedef struct {UINT n; POSITION pos;} plsort_t;
00154 
00155 static int compare(const void* arg1, const void* arg2)
00156 {
00157         UINT a1 = ((plsort_t*)arg1)->n;
00158         UINT a2 = ((plsort_t*)arg2)->n;
00159         return a1 > a2 ? 1 : a1 < a2 ? -1 : 0;
00160 }
00161 
00162 typedef struct {LPCTSTR str; POSITION pos;} plsort2_t;
00163 
00164 int compare2(const void* arg1, const void* arg2)
00165 {
00166         return _tcsicmp(((plsort2_t*)arg1)->str, ((plsort2_t*)arg2)->str);
00167 }
00168 
00169 void CPlaylist::SortById()
00170 {
00171         CArray<plsort_t> a;
00172         a.SetSize(GetCount());
00173         POSITION pos = GetHeadPosition();
00174         for(int i = 0; pos; i++, GetNext(pos))
00175                 a[i].n = GetAt(pos).m_id, a[i].pos = pos;
00176         qsort(a.GetData(), a.GetCount(), sizeof(plsort_t), compare);
00177         for(int i = 0; i < a.GetCount(); i++)
00178         {
00179                 AddTail(GetAt(a[i].pos));
00180                 __super::RemoveAt(a[i].pos);
00181                 if(m_pos == a[i].pos) m_pos = GetTailPosition(); 
00182         }
00183 }
00184 
00185 void CPlaylist::SortByName()
00186 {
00187         CArray<plsort2_t> a;
00188         a.SetSize(GetCount());
00189         POSITION pos = GetHeadPosition();
00190         for(int i = 0; pos; i++, GetNext(pos))
00191         {
00192                 CString& fn = GetAt(pos).m_fns.GetHead();
00193                 a[i].str = (LPCTSTR)fn + max(fn.ReverseFind('/'), fn.ReverseFind('\\')) + 1;
00194                 a[i].pos = pos;
00195         }
00196         qsort(a.GetData(), a.GetCount(), sizeof(plsort2_t), compare2);
00197         for(int i = 0; i < a.GetCount(); i++)
00198         {
00199                 AddTail(GetAt(a[i].pos));
00200                 __super::RemoveAt(a[i].pos);
00201                 if(m_pos == a[i].pos) m_pos = GetTailPosition(); 
00202         }
00203 }
00204 
00205 void CPlaylist::SortByPath()
00206 {
00207         CArray<plsort2_t> a;
00208         a.SetSize(GetCount());
00209         POSITION pos = GetHeadPosition();
00210         for(int i = 0; pos; i++, GetNext(pos))
00211                 a[i].str = GetAt(pos).m_fns.GetHead(), a[i].pos = pos;
00212         qsort(a.GetData(), a.GetCount(), sizeof(plsort2_t), compare2);
00213         for(int i = 0; i < a.GetCount(); i++)
00214         {
00215                 AddTail(GetAt(a[i].pos));
00216                 __super::RemoveAt(a[i].pos);
00217                 if(m_pos == a[i].pos) m_pos = GetTailPosition(); 
00218         }
00219 }
00220 
00221 void CPlaylist::Randomize()
00222 {
00223         CArray<plsort_t> a;
00224         a.SetSize(GetCount());
00225         srand((unsigned int)time(NULL));
00226         POSITION pos = GetHeadPosition();
00227         for(int i = 0; pos; i++, GetNext(pos))
00228                 a[i].n = rand(), a[i].pos = pos;
00229         qsort(a.GetData(), a.GetCount(), sizeof(plsort_t), compare);
00230         CList<CPlaylistItem> pl;
00231         for(int i = 0; i < a.GetCount(); i++)
00232         {
00233                 AddTail(GetAt(a[i].pos));
00234                 __super::RemoveAt(a[i].pos);
00235                 if(m_pos == a[i].pos)
00236                         m_pos = GetTailPosition(); 
00237         }
00238 }
00239 
00240 POSITION CPlaylist::GetPos()
00241 {
00242         return(m_pos);
00243 }
00244 
00245 void CPlaylist::SetPos(POSITION pos)
00246 {
00247         m_pos = pos;
00248 }
00249 
00250 CPlaylistItem& CPlaylist::GetNextWrap(POSITION& pos)
00251 {
00252         GetNext(pos);
00253 
00254         if(!pos)
00255         {
00256                 // FIXME: add param: , bool fShuffle
00257                 if(GetCount() > 2 && AfxGetApp()->GetProfileInt(ResStr(IDS_R_SETTINGS), _T("ShufflePlaylistItems"), FALSE))
00258                         Randomize();
00259 
00260                 pos = GetHeadPosition();
00261         }
00262 
00263         return(GetAt(pos));
00264 }
00265 
00266 CPlaylistItem& CPlaylist::GetPrevWrap(POSITION& pos)
00267 {
00268         GetPrev(pos);
00269         if(!pos) pos = GetTailPosition();
00270         return(GetAt(pos));
00271 }
00272 

Generated on Tue Dec 13 14:46:59 2005 for guliverkli by  doxygen 1.4.5