- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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