- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# PlayerSubresyncBar.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 // PlayerSubresyncBar.cpp : implementation file
    00023 //
    00024
    00025 #include "stdafx.h"
    00026 #include "mplayerc.h"
    00027 #include "mainfrm.h"
    00028 #include "PlayerSubresyncBar.h"
    00029
    00030 // CPlayerSubresyncBar
    00031
    00032 IMPLEMENT_DYNAMIC(CPlayerSubresyncBar, CSizingControlBarG)
    00033 CPlayerSubresyncBar::CPlayerSubresyncBar()
    00034 {
    00035         m_rt = 0;
    00036         m_fUnlink = false;
    00037         m_lastSegment = -1;
    00038 }
    00039
    00040 CPlayerSubresyncBar::~CPlayerSubresyncBar()
    00041 {
    00042 }
    00043
    00044 BOOL CPlayerSubresyncBar::Create(CWnd* pParentWnd, CCritSec* pSubLock)
    00045 {
    00046         if(!CSizingControlBarG::Create(_T("Subresync"), pParentWnd, 50))
    00047                 return FALSE;
    00048
    00049         m_pSubLock = pSubLock;
    00050
    00051         m_list.CreateEx(
    00052                 WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE,
    00053                 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_TABSTOP|LVS_REPORT/*|LVS_SHOWSELALWAYS*/|LVS_AUTOARRANGE|LVS_NOSORTHEADER,
    00054                 CRect(0,0,100,100), this, IDC_SUBRESYNCLIST);
    00055
    00056         m_list.SetExtendedStyle(m_list.GetExtendedStyle()|LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER);
    00057
    00058         return TRUE;
    00059 }
    00060
    00061 BOOL CPlayerSubresyncBar::PreCreateWindow(CREATESTRUCT& cs)
    00062 {
    00063         if(!CSizingControlBarG::PreCreateWindow(cs))
    00064                 return FALSE;
    00065
    00066         return TRUE;
    00067 }
    00068
    00069 BOOL CPlayerSubresyncBar::PreTranslateMessage(MSG* pMsg)
    00070 {
    00071         if(IsWindow(pMsg->hwnd) && IsVisible() && pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
    00072         {
    00073                 if(IsDialogMessage(pMsg))
    00074                         return TRUE;
    00075         }
    00076
    00077         return CSizingControlBarG::PreTranslateMessage(pMsg);
    00078 }
    00079
    00080 void CPlayerSubresyncBar::SetTime(__int64 rt)
    00081 {
    00082         m_rt = rt;
    00083
    00084         int curSegment;
    00085
    00086         if(!m_sts.SearchSubs((int)(rt/10000), 25, &curSegment))
    00087         {
    00088                 curSegment = -1;
    00089         }
    00090
    00091         if(m_lastSegment != curSegment) m_list.Invalidate();
    00092         m_lastSegment = curSegment;
    00093 }
    00094
    00095 void CPlayerSubresyncBar::SetSubtitle(ISubStream* pSubStream, double fps)
    00096 {
    00097         m_pSubStream = pSubStream;
    00098
    00099         m_mode = NONE;
    00100         m_lastSegment = -1;
    00101         m_sts.Empty();
    00102
    00103         ResetSubtitle();
    00104
    00105         if(!m_pSubStream) return;
    00106
    00107         CLSID clsid;
    00108         m_pSubStream->GetClassID(&clsid);
    00109
    00110         if(clsid == __uuidof(CVobSubFile))
    00111         {
    00112                 CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream;
    00113
    00114                 m_mode = VOBSUB;
    00115
    00116                 CArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos;
    00117
    00118                 for(int i = 0, j = sp.GetSize(); i < j; i++)
    00119                 {
    00120                         CString str;
    00121                         str.Format(_T("%d,%d,%d,%d"), sp[i].vobid, sp[i].cellid, sp[i].fForced, i);
    00122                         m_sts.Add(TToW(str), false, (int)sp[i].start, (int)sp[i].stop);
    00123                 }
    00124
    00125                 m_sts.CreateDefaultStyle(DEFAULT_CHARSET);
    00126
    00127                 pVSF->m_fOnlyShowForcedSubs = false;
    00128
    00129                 for(int i = 0, j = m_list.GetHeaderCtrl()->GetItemCount(); i < j; i++) m_list.DeleteColumn(0);
    00130                 m_list.InsertColumn(COL_START, _T("Time"), LVCFMT_LEFT, 80);
    00131                 m_list.InsertColumn(COL_END, _T("End"), LVCFMT_LEFT, 80);
    00132                 m_list.InsertColumn(COL_PREVSTART, _T("Preview"), LVCFMT_LEFT, 80);
    00133                 m_list.InsertColumn(COL_PREVEND, _T("End"), LVCFMT_LEFT, 80);
    00134                 m_list.InsertColumn(COL_VOBID, _T("Vob ID"), LVCFMT_CENTER, 60);
    00135                 m_list.InsertColumn(COL_CELLID, _T("Cell ID"), LVCFMT_CENTER, 60);
    00136                 m_list.InsertColumn(COL_FORCED, _T("Forced"), LVCFMT_CENTER, 60);
    00137         }
    00138         else if(clsid == __uuidof(CRenderedTextSubtitle))
    00139         {
    00140                 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
    00141
    00142                 m_mode = TEXTSUB;
    00143
    00144                 m_sts.Copy(*pRTS);
    00145                 m_sts.ConvertToTimeBased(fps);
    00146                 m_sts.Sort(true);
    00148 #ifndef UNICODE
    00149                 if(!m_sts.IsEntryUnicode(0))
    00150                 {
    00151                         CFont* f = m_list.GetFont();
    00152                         LOGFONT lf;
    00153                         f->GetLogFont(&lf);
    00154                         lf.lfCharSet = m_sts.GetCharSet(0);
    00155                         m_font.DeleteObject();
    00156                         m_font.CreateFontIndirect(&lf);
    00157                         m_list.SetFont(&m_font);
    00158                 }
    00159 #endif
    00160                 for(int i = 0, j = m_list.GetHeaderCtrl()->GetItemCount(); i < j; i++) m_list.DeleteColumn(0);
    00161                 m_list.InsertColumn(COL_START, _T("Time"), LVCFMT_LEFT, 90);
    00162                 m_list.InsertColumn(COL_END, _T("End"), LVCFMT_LEFT, 4);
    00163                 m_list.InsertColumn(COL_PREVSTART, _T("Preview"), LVCFMT_LEFT, 80);
    00164                 m_list.InsertColumn(COL_PREVEND, _T("End"), LVCFMT_LEFT, 4);
    00165                 m_list.InsertColumn(COL_TEXT, _T("Text"), LVCFMT_LEFT, 275);
    00166                 m_list.InsertColumn(COL_STYLE, _T("Style"), LVCFMT_LEFT, 80);
    00167                 m_list.InsertColumn(COL_FONT, _T("Font"), LVCFMT_LEFT, 60);
    00168                 m_list.InsertColumn(COL_CHARSET, _T("CharSet"), LVCFMT_CENTER, 20);
    00169                 m_list.InsertColumn(COL_UNICODE, _T("Unicode"), LVCFMT_CENTER, 40);
    00170                 m_list.InsertColumn(COL_LAYER, _T("Layer"), LVCFMT_CENTER, 50);
    00171                 m_list.InsertColumn(COL_ACTOR, _T("Actor"), LVCFMT_LEFT, 80);
    00172                 m_list.InsertColumn(COL_EFFECT, _T("Effect"), LVCFMT_LEFT, 80);
    00173         }
    00174
    00175         m_subtimes.SetSize(m_sts.GetSize());
    00176
    00177         for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00178         {
    00179                 m_subtimes[i].orgstart = m_sts[i].start;
    00180                 m_subtimes[i].orgend = m_sts[i].end;
    00181         }
    00182
    00183         ResetSubtitle();
    00184 }
    00185
    00186 void CPlayerSubresyncBar::ResetSubtitle()
    00187 {
    00188         m_list.DeleteAllItems();
    00189
    00190         if(m_mode == VOBSUB || m_mode == TEXTSUB)
    00191         {
    00192                 TCHAR buff[32];
    00193
    00194                 int prevstart = INT_MIN;
    00195
    00196                 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00197                 {
    00198                         m_subtimes[i].newstart = m_subtimes[i].orgstart;
    00199                         m_subtimes[i].newend = m_subtimes[i].orgend;
    00200
    00201                         FormatTime(i, buff, 0, false);
    00202                         m_list.InsertItem(i, buff, COL_START);
    00203                         FormatTime(i, buff, 0, true);
    00204                         m_list.SetItemText(i, COL_END, buff);
    00205
    00206                         if(prevstart > m_subtimes[i].orgstart) m_list.SetItemData(i, TSEP);
    00207                         prevstart = m_subtimes[i].orgstart;
    00208
    00209                         SetCheck(i, false, false);
    00210                 }
    00211
    00212                 UpdatePreview();
    00213
    00214                 m_list.SetColumnWidth(COL_START, LVSCW_AUTOSIZE);
    00215                 m_list.SetColumnWidth(COL_PREVSTART, LVSCW_AUTOSIZE);
    00216         }
    00217
    00218         UpdateStrings();
    00219 }
    00220
    00221 void CPlayerSubresyncBar::SaveSubtitle()
    00222 {
    00223         CMainFrame* pFrame = ((CMainFrame*)AfxGetMainWnd());
    00224         if(!pFrame) return;
    00225
    00226         CLSID clsid;
    00227         m_pSubStream->GetClassID(&clsid);
    00228
    00229         if(clsid == __uuidof(CVobSubFile) && m_mode == VOBSUB)
    00230         {
    00231                 CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)m_pSubStream;
    00232
    00233                 CAutoLock cAutoLock(m_pSubLock);
    00234
    00235                 CArray<CVobSubFile::SubPos>& sp = pVSF->m_langs[pVSF->m_iLang].subpos;
    00236
    00237                 for(int i = 0, j = sp.GetSize(); i < j; i++)
    00238                 {
    00239                         sp[i].fValid = false;
    00240                 }
    00241
    00242                 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00243                 {
    00244                         int vobid, cellid, forced, spnum, c;
    00245                         if(_stscanf(m_sts.GetStr(i), _T("%d%c%d%c%d%c%d"), &vobid, &c, &cellid, &c, &forced, &c, &spnum) != 7) continue;
    00246             sp[spnum].start = m_sts[i].start;
    00247                         sp[spnum].stop = m_sts[i].end;
    00248                         sp[spnum].fValid = true;
    00249                 }
    00250         }
    00251         else if(clsid == __uuidof(CRenderedTextSubtitle) && m_mode == TEXTSUB)
    00252         {
    00253                 CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)m_pSubStream;
    00254
    00255                 CAutoLock cAutoLock(m_pSubLock);
    00256
    00257                 pRTS->Copy(m_sts);
    00258         }
    00259         else
    00260         {
    00261                 return;
    00262         }
    00263
    00264         pFrame->InvalidateSubtitle();
    00265 }
    00266
    00267 void CPlayerSubresyncBar::UpdatePreview()
    00268 {
    00269         if(m_mode == VOBSUB || m_mode == TEXTSUB)
    00270         {
    00271                 if(0/*m_fUnlink*/)
    00272                 {
    00273                         for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00274                         {
    00275                                 bool fStartMod, fEndMod, fStartAdj, fEndAdj;
    00276                                 GetCheck(i, fStartMod, fEndMod, fStartAdj, fEndAdj);
    00277                                 m_sts[i].start = (fStartMod||fStartAdj) ? m_subtimes[i].newstart : m_subtimes[i].orgstart;
    00278                                 m_sts[i].end = (fEndMod||fEndAdj) ? m_subtimes[i].newend : m_subtimes[i].orgend;
    00279                         }
    00280                 }
    00281                 else
    00282                 {
    00283                         CArray <int, int> schk;
    00284
    00285                         for(int i = 0, j = m_sts.GetSize(); i < j;)
    00286                         {
    00287                                 schk.RemoveAll();
    00288
    00289                                 int start = i, end;
    00290
    00291                                 for(end = i; end < j; end++)
    00292                                 {
    00293                                         int data = (int)m_list.GetItemData(end);
    00294                                         if((data&TSEP) && end > i) break;
    00295                                         if(data&(TSMOD|TSADJ))
    00296                                                 schk.Add(end);
    00297                                 }
    00298
    00299                                 if(schk.GetSize() == 0)
    00300                                 {
    00301                                         for(; start < end; start++)
    00302                                         {
    00303                                                 m_sts[start].start = m_subtimes[start].orgstart;
    00304                                                 m_sts[start].end = m_subtimes[start].orgend;
    00305                                         }
    00306                                 }
    00307                                 else if(schk.GetSize() == 1)
    00308                                 {
    00309                                         int k = schk[0];
    00310                                         int dt = m_subtimes[k].newstart - m_subtimes[k].orgstart;
    00311                                         for(; start < end; start++)
    00312                                         {
    00313                                                 m_sts[start].start = m_subtimes[start].orgstart + dt;
    00314                                                 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
    00315                                                         ? m_subtimes[start].newend
    00316                                                         : (m_subtimes[start].orgend + dt);
    00317                                         }
    00318                                 }
    00319                                 else if(schk.GetSize() >= 2)
    00320                                 {
    00321                                         int i0, i1, ti0, ds;
    00322                                         double m = 0;
    00323
    00324                                         for(int k = 0, l = schk.GetSize()-1; k < l; k++)
    00325                                         {
    00326                                                 i0 = schk[k];
    00327                                                 i1 = schk[k+1];
    00328
    00329                                                 ti0 = m_subtimes[i0].orgstart;
    00330                                                 ds = m_subtimes[i1].orgstart - ti0;
    00331
    00332                                                 if(ds == 0)
    00333                                                 {
    00334                                                         for(; start < i1; start++)
    00335                                                         {
    00336                                                                 m_sts[start].start = ti0;
    00337                                                                 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
    00338                                                                         ? m_subtimes[start].newend
    00339                                                                         : (ti0 + m_subtimes[start].orgend - m_subtimes[start].orgstart);
    00340                                                         }
    00341                                                 }
    00342                                                 else
    00343                                                 {
    00344                                                         m = double(m_subtimes[i1].newstart - m_subtimes[i0].newstart) / ds;
    00345
    00346                                                         for(; start < i1; start++)
    00347                                                         {
    00348                                                                 m_sts[start].start = int((m_subtimes[start].orgstart - ti0)*m + m_subtimes[i0].newstart);
    00349                                                                 m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
    00350                                                                         ? m_subtimes[start].newend
    00351                                                                         : m_mode == VOBSUB
    00352                                                                         ? (m_sts[start].start + m_subtimes[start].orgend - m_subtimes[start].orgstart)
    00353                                                                         : (m_sts[start].start + int((m_subtimes[start].orgend - m_subtimes[start].orgstart)*m));
    00354                                                         }
    00355                                                 }
    00356                                         }
    00357
    00358                                         if(ds == 0)
    00359                                         {
    00360                                                 for(; start < end; start++)
    00361                                                 {
    00362                                                         m_sts[start].start = ti0;
    00363                                                         m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
    00364                                                                 ? m_subtimes[start].newend
    00365                                                                 : (ti0 + (m_subtimes[start].orgend - m_subtimes[start].orgstart));
    00366                                                 }
    00367                                         }
    00368                                         else
    00369                                         {
    00370                                                 for(; start < end; start++)
    00371                                                 {
    00372                                                         m_sts[start].start = int((m_subtimes[start].orgstart - ti0)*m + m_subtimes[i0].newstart);
    00373                                                         m_sts[start].end = (m_list.GetItemData(start)&TEMOD)
    00374                                                                 ? m_subtimes[start].newend
    00375                                                                 : m_mode == VOBSUB
    00376                                                                 ? (m_sts[start].start + m_subtimes[start].orgend - m_subtimes[start].orgstart)
    00377                                                                 : (m_sts[start].start + int((m_subtimes[start].orgend - m_subtimes[start].orgstart)*m));
    00378                                                 }
    00379                                         }
    00380                                 }
    00381
    00382                                 i = end;
    00383                         }
    00384                 }
    00385
    00386                 m_sts.CreateSegments();
    00387
    00388                 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00389                 {
    00390                         TCHAR buff[32];
    00391                         FormatTime(i, buff, 2, false);
    00392                         m_list.SetItemText(i, COL_PREVSTART, buff);
    00393                         FormatTime(i, buff, 2, true);
    00394                         m_list.SetItemText(i, COL_PREVEND, buff);
    00395                 }
    00396
    00397                 if(IsWindowVisible())
    00398                 {
    00399                         SaveSubtitle();
    00400                 }
    00401         }
    00402 }
    00403
    00404 void CPlayerSubresyncBar::UpdateStrings()
    00405 {
    00406         CString str;
    00407
    00408         if(m_mode == TEXTSUB)
    00409         {
    00410                 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00411                 {
    00412                         STSStyle stss;
    00413                         m_sts.GetStyle(i, stss);
    00414
    00415                         m_list.SetItemText(i, COL_TEXT, m_sts.GetStr(i, true));
    00416                         m_list.SetItemText(i, COL_STYLE, m_sts[i].style);
    00417                         m_list.SetItemText(i, COL_FONT, stss.fontName);
    00418                         str.Format(_T("%d"), stss.charSet);
    00419                         m_list.SetItemText(i, COL_CHARSET, str);
    00420                         m_list.SetItemText(i, COL_UNICODE, m_sts.IsEntryUnicode(i) ? _T("yes") : _T("no"));
    00421                         str.Format(_T("%d"), m_sts[i].layer);
    00422                         m_list.SetItemText(i, COL_LAYER, str);
    00423                         m_list.SetItemText(i, COL_ACTOR, m_sts[i].actor);
    00424                         m_list.SetItemText(i, COL_EFFECT, m_sts[i].effect);
    00425                 }
    00426         }
    00427         else if(m_mode == VOBSUB)
    00428         {
    00429                 for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00430                 {
    00431                         int vobid, cellid, forced, c;
    00432                         if(_stscanf(m_sts.GetStr(i), _T("%d%c%d%c%d"), &vobid, &c, &cellid, &c, &forced) != 5) continue;
    00433                         if(vobid < 0) str = _T("-");
    00434                         else str.Format(_T("%d"), vobid);
    00435                         m_list.SetItemText(i, COL_VOBID, str);
    00436                         if(cellid < 0) str = _T("-");
    00437                         else str.Format(_T("%d"), cellid);
    00438                         m_list.SetItemText(i, COL_CELLID, str);
    00439                         str = forced?_T("Yes"):_T("");
    00440                         m_list.SetItemText(i, COL_FORCED, str);
    00441                 }
    00442         }
    00443 }
    00444
    00445 void CPlayerSubresyncBar::GetCheck(int iItem, bool& fStartMod, bool& fEndMod, bool& fStartAdj, bool& fEndAdj)
    00446 {
    00447         if(0 <= iItem && iItem < m_sts.GetSize())
    00448         {
    00449         int nCheck = (int)m_list.GetItemData(iItem);
    00450                 fStartMod = !!(nCheck&TSMOD);
    00451                 fEndMod = !!(nCheck&TEMOD);
    00452                 fStartAdj = !!(nCheck&TSADJ);
    00453                 fEndAdj = !!(nCheck&TEADJ);
    00454         }
    00455 }
    00456
    00457 void CPlayerSubresyncBar::SetCheck(int iItem, bool fStart, bool fEnd)
    00458 {
    00459         if(0 <= iItem && iItem < m_sts.GetSize())
    00460         {
    00461                 SubTime& st = m_subtimes[iItem];
    00462
    00463         int nCheck = (int)m_list.GetItemData(iItem) & TSEP;
    00464
    00465                 if(fStart) nCheck |= TSMOD;
    00466                 else if(abs(st.orgstart-st.newstart)) nCheck |= TSADJ;
    00467                 if(fEnd) nCheck |= TEMOD;
    00468                 else if(abs(st.orgend-st.newend)) nCheck |= TEADJ;
    00469
    00470                 m_list.SetItemData(iItem, (DWORD)nCheck);
    00471
    00472                 TCHAR buff[32];
    00473                 FormatTime(iItem, buff, fStart, false);
    00474                 m_list.SetItemText(iItem, COL_START, buff);
    00475                 FormatTime(iItem, buff, fEnd, true);
    00476                 m_list.SetItemText(iItem, COL_END, buff);
    00477         }
    00478 }
    00479
    00480 bool CPlayerSubresyncBar::ModStart(int iItem, int t, bool fReset)
    00481 {
    00482         bool fRet = false;
    00483
    00484         bool fStartMod, fEndMod, fStartAdj, fEndAdj;
    00485         GetCheck(iItem, fStartMod, fEndMod, fStartAdj, fEndAdj);
    00486
    00487         SubTime& st = m_subtimes[iItem];
    00488
    00489 //      if(fStartMod || fStartAdj || st.orgstart != t || fReset)
    00490         {
    00491                 fRet = (st.newstart != t);
    00492
    00493                 st.newstart = t;
    00494                 if(!fEndMod) st.newend = st.newstart + (st.orgend - st.orgstart);
    00495                 else if(fReset) st.newstart = st.newend - (st.orgend - st.orgstart);
    00496
    00497                 SetCheck(iItem, !fReset, fEndMod);
    00498         }
    00499
    00500         return(fRet);
    00501 }
    00502
    00503 bool CPlayerSubresyncBar::ModEnd(int iItem, int t, bool fReset)
    00504 {
    00505         bool fRet = false;
    00506
    00507         bool fStartMod, fEndMod, fStartAdj, fEndAdj;
    00508         GetCheck(iItem, fStartMod, fEndMod, fStartAdj, fEndAdj);
    00509
    00510         SubTime& st = m_subtimes[iItem];
    00511
    00512 //      if(fEndMod || fEndAdj || st.orgend != t || fReset)
    00513         {
    00514                 fRet = (st.newend != t);
    00515
    00516                 st.newend = t;
    00517                 if(!fStartMod) st.newstart = st.newend - (st.orgend - st.orgstart);
    00518                 else if(fReset) st.newend = st.newstart + (st.orgend - st.orgstart);
    00519
    00520                 SetCheck(iItem, fStartMod, !fReset);
    00521         }
    00522
    00523         return(fRet);
    00524 }
    00525
    00526 void CPlayerSubresyncBar::FormatTime(int iItem, TCHAR* buff, int time, bool fEnd)
    00527 {
    00528         int t = !fEnd
    00529                 ?(time == 2 ? m_sts[iItem].start
    00530                 : time == 1     ? m_subtimes[iItem].newstart
    00531                 : m_subtimes[iItem].orgstart)
    00532                 : (time == 2 ? m_sts[iItem].end
    00533                 : time == 1     ? m_subtimes[iItem].newend
    00534                 : m_subtimes[iItem].orgend);
    00535
    00536         _stprintf(buff, t >= 0
    00537                                         ? _T("%02d:%02d:%02d.%03d")
    00538                                         : _T("-%02d:%02d:%02d.%03d"),
    00539                 abs(t)/60/60/1000,
    00540                 (abs(t)/60/1000)%60,
    00541                 (abs(t)/1000)%60,
    00542                 abs(t)%1000);
    00543 }
    00544
    00545
    00546 BEGIN_MESSAGE_MAP(CPlayerSubresyncBar, CSizingControlBarG)
    00547         ON_WM_SIZE()
    00548         ON_NOTIFY(LVN_BEGINLABELEDIT, IDC_SUBRESYNCLIST, OnBeginlabeleditList)
    00549         ON_NOTIFY(LVN_DOLABELEDIT, IDC_SUBRESYNCLIST, OnDolabeleditList)
    00550         ON_NOTIFY(LVN_ENDLABELEDIT, IDC_SUBRESYNCLIST, OnEndlabeleditList)
    00551         ON_NOTIFY(NM_RCLICK, IDC_SUBRESYNCLIST, OnRclickList)
    00552         ON_NOTIFY(NM_DBLCLK, IDC_SUBRESYNCLIST, OnNMDblclkList)
    00553         ON_NOTIFY(LVN_KEYDOWN, IDC_SUBRESYNCLIST, OnLvnKeydownList)
    00554         ON_NOTIFY(NM_CUSTOMDRAW, IDC_SUBRESYNCLIST, OnCustomdrawList)
    00555 END_MESSAGE_MAP()
    00556
    00557
    00558 // CPlayerSubresyncBar message handlers
    00559
    00560 void CPlayerSubresyncBar::OnSize(UINT nType, int cx, int cy)
    00561 {
    00562         CSizingControlBarG::OnSize(nType, cx, cy);
    00563
    00564         if(::IsWindow(m_list.m_hWnd))
    00565         {
    00566                 CRect r;
    00567                 GetClientRect(r);
    00568                 r.DeflateRect(2, 2);
    00569                 m_list.MoveWindow(r);
    00570         }
    00571 }
    00572
    00573 static bool ParseTime(CString str, int& ret, bool fWarn = true)
    00574 {
    00575         int sign = 1, h, m, s, ms;
    00576         TCHAR c;
    00577
    00578         str.Trim();
    00579         if(str.GetLength() > 0 && str[0] == '-') sign = -1;
    00580
    00581         int n = _stscanf(str, _T("%d%c%d%c%d%c%d"), &h, &c, &m, &c, &s, &c, &ms);
    00582
    00583         h = abs(h);
    00584
    00585         if(n == 7
    00586         && 0 <= h && h < 24
    00587         && 0 <= m && m < 60
    00588         && 0 <= s && s < 60
    00589         && 0 <= ms && ms < 1000)
    00590         {
    00591                 ret = sign*(h*60*60*1000+m*60*1000+s*1000+ms);
    00592                 return(true);
    00593         }
    00594
    00595         if(fWarn) AfxMessageBox(_T("The correct time format is [-]hh:mm:ss.ms\n(e.g. 01:23:45.678)"));
    00596         return(false);
    00597 }
    00598
    00599 void CPlayerSubresyncBar::OnBeginlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
    00600 {
    00601         LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
    00602         LV_ITEM* pItem = &pDispInfo->item;
    00603
    00604         *pResult = FALSE;
    00605
    00606         if(pItem->iItem >= 0)
    00607         {
    00608                 if((pItem->iSubItem == COL_START || pItem->iSubItem == COL_END || pItem->iSubItem == COL_TEXT
    00609                         || pItem->iSubItem == COL_STYLE || pItem->iSubItem == COL_LAYER
    00610                         || pItem->iSubItem == COL_ACTOR || pItem->iSubItem == COL_EFFECT)
    00611                         && m_mode == TEXTSUB)
    00612                 {
    00613                         *pResult = TRUE;
    00614                 }
    00615                 else if((pItem->iSubItem == COL_START)
    00616                         && m_mode == VOBSUB)
    00617                 {
    00618                         *pResult = TRUE;
    00619                 }
    00620         }
    00621 }
    00622
    00623 void CPlayerSubresyncBar::OnDolabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
    00624 {
    00625         LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
    00626         LV_ITEM* pItem = &pDispInfo->item;
    00627
    00628         *pResult = FALSE;
    00629
    00630         if(pItem->iItem >= 0)
    00631         {
    00632                 if((pItem->iSubItem == COL_START || pItem->iSubItem == COL_END || pItem->iSubItem == COL_TEXT
    00633                         || pItem->iSubItem == COL_STYLE || pItem->iSubItem == COL_LAYER
    00634                         || pItem->iSubItem == COL_ACTOR || pItem->iSubItem == COL_EFFECT)
    00635                         && m_mode == TEXTSUB)
    00636                 {
    00637                         m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
    00638                         *pResult = TRUE;
    00639                 }
    00640                 else if((pItem->iSubItem == COL_START)
    00641                         && m_mode == VOBSUB)
    00642                 {
    00643                         m_list.ShowInPlaceEdit(pItem->iItem, pItem->iSubItem);
    00644                         *pResult = TRUE;
    00645                 }
    00646         }
    00647 }
    00648
    00649 void CPlayerSubresyncBar::OnEndlabeleditList(NMHDR* pNMHDR, LRESULT* pResult)
    00650 {
    00651         LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
    00652         LV_ITEM* pItem = &pDispInfo->item;
    00653
    00654         *pResult = FALSE;
    00655
    00656         if(!m_list.m_fInPlaceDirty)
    00657                 return;
    00658
    00659         bool fNeedsUpdate = false;
    00660
    00661         if(pItem->iItem >= 0 && pItem->pszText && (m_mode == VOBSUB || m_mode == TEXTSUB))
    00662         {
    00663                 if(pItem->iSubItem == COL_START)
    00664                 {
    00665                         int t;
    00666                         if(ParseTime(pItem->pszText, t))
    00667                         {
    00668                                 fNeedsUpdate = ModStart(pItem->iItem, t);
    00669
    00670                                 *pResult = TRUE;
    00671                         }
    00672                 }
    00673                 else if(pItem->iSubItem == COL_END && m_mode == TEXTSUB)
    00674                 {
    00675                         int t;
    00676                         if(ParseTime(pItem->pszText, t))
    00677                         {
    00678                                 fNeedsUpdate = ModEnd(pItem->iItem, t);
    00679
    00680                                 *pResult = TRUE;
    00681                         }
    00682                 }
    00683                 else if(pItem->iSubItem == COL_TEXT && m_mode == TEXTSUB)
    00684                 {
    00685                         CString str = m_sts.GetStr(pItem->iItem, true);
    00686
    00687                         if(str != pItem->pszText)
    00688                         {
    00689                                 fNeedsUpdate = true;
    00690                                 m_sts.SetStr(pItem->iItem, CString(pItem->pszText), true);
    00691                                 m_list.SetItemText(pItem->iItem, pItem->iSubItem, m_sts.GetStr(pItem->iItem, true));
    00692                         }
    00693                 }
    00694                 else if(pItem->iSubItem == COL_STYLE && m_mode == TEXTSUB)
    00695                 {
    00696                         CString str(pItem->pszText);
    00697                         str.Trim();
    00698
    00699                         if(!str.IsEmpty() && m_sts[pItem->iItem].style != str)
    00700                         {
    00701                                 fNeedsUpdate = true;
    00702
    00703                                 void* val;
    00704                                 if(!m_sts.m_styles.Lookup(str, val))
    00705                                         m_sts.AddStyle(str, new STSStyle());
    00706
    00707                                 m_sts[pItem->iItem].style = str;
    00708
    00709                                 m_list.SetItemText(pItem->iItem, pItem->iSubItem, pItem->pszText);
    00710                         }
    00711                 }
    00712                 else if(pItem->iSubItem == COL_LAYER && m_mode == TEXTSUB)
    00713                 {
    00714                         int l;
    00715                         if(_stscanf(pItem->pszText, _T("%d"), &l) == 1)
    00716                         {
    00717                                 fNeedsUpdate = true;
    00718                                 m_sts[pItem->iItem].layer = l;
    00719                                 CString str;
    00720                                 str.Format(_T("%d"), l);
    00721                                 m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
    00722                         }
    00723                 }
    00724                 else if(pItem->iSubItem == COL_ACTOR && m_mode == TEXTSUB)
    00725                 {
    00726                         CString str(pItem->pszText);
    00727                         str.Trim();
    00728                         if(!str.IsEmpty())
    00729                         {
    00730                                 fNeedsUpdate = true;
    00731                                 m_sts[pItem->iItem].actor = str;
    00732                                 m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
    00733                         }
    00734                 }
    00735                 else if(pItem->iSubItem == COL_EFFECT && m_mode == TEXTSUB)
    00736                 {
    00737                         CString str(pItem->pszText);
    00738                         str.Trim();
    00739                         if(!str.IsEmpty())
    00740                         {
    00741                                 fNeedsUpdate = true;
    00742                                 m_sts[pItem->iItem].effect = str;
    00743                                 m_list.SetItemText(pItem->iItem, pItem->iSubItem, str);
    00744                         }
    00745                 }
    00746         }
    00747
    00748         if(fNeedsUpdate)
    00749         {
    00750                 UpdatePreview();
    00751         }
    00752 }
    00753
    00754 static int uintcomp(const void* i1, const void* i2)
    00755 {
    00756         return(*((UINT*)i2) - *((UINT*)i1));
    00757 }
    00758
    00759 void CPlayerSubresyncBar::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult)
    00760 {
    00761         LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
    00762
    00763         if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem >= 0)
    00764         {
    00765                 enum
    00766                 {
    00767                         TOGSEP=1,
    00768                         DUPITEM, DELITEM,
    00769                         RESETS, SETOS, SETCS, RESETE, SETOE, SETCE,
    00770                         STYLEFIRST, STYLELAST=STYLEFIRST+1000, STYLEEDIT,
    00771                         UNICODEYES, UNICODENO,
    00772                         LAYERDEC, LAYERINC,
    00773                         ACTORFIRST, ACTORLAST=ACTORFIRST+1000,
    00774                         EFFECTFIRST, EFFECTLAST=EFFECTFIRST+1000
    00775                 };
    00776
    00777                 CStringArray styles;
    00778                 CStringArray actors;
    00779                 CStringArray effects;
    00780
    00781                 CMenu m;
    00782                 m.CreatePopupMenu();
    00783
    00784                 if(m_mode == VOBSUB || m_mode == TEXTSUB)
    00785                 {
    00786                         m.AppendMenu(MF_STRING|MF_ENABLED, TOGSEP, ResStr(IDS_SUBRESYNC_SEPARATOR));
    00787                         m.AppendMenu(MF_SEPARATOR);
    00788                         if(m_mode == TEXTSUB) m.AppendMenu(MF_STRING|MF_ENABLED, DUPITEM, ResStr(IDS_SUBRESYNC_DUPLICATE));
    00789                         m.AppendMenu(MF_STRING|MF_ENABLED, DELITEM, ResStr(IDS_SUBRESYNC_DELETE));
    00790                 }
    00791
    00792                 if(lpnmlv->iSubItem == COL_START && (m_mode == VOBSUB || m_mode == TEXTSUB))
    00793                 {
    00794                         m.AppendMenu(MF_SEPARATOR);
    00795                         m.AppendMenu(MF_STRING|MF_ENABLED, RESETS, ResStr(IDS_SUBRESYNC_RESET));
    00796                         m.AppendMenu(MF_STRING|MF_ENABLED, SETOS, ResStr(IDS_SUBRESYNC_ORIGINAL));
    00797                         m.AppendMenu(MF_STRING|MF_ENABLED, SETCS, ResStr(IDS_SUBRESYNC_CURRENT));
    00798                 }
    00799                 else if(lpnmlv->iSubItem == COL_END && m_mode == TEXTSUB)
    00800                 {
    00801                         m.AppendMenu(MF_SEPARATOR);
    00802                         m.AppendMenu(MF_STRING|MF_ENABLED, RESETE, ResStr(IDS_SUBRESYNC_RESET));
    00803                         m.AppendMenu(MF_STRING|MF_ENABLED, SETOE, ResStr(IDS_SUBRESYNC_ORIGINAL));
    00804                         m.AppendMenu(MF_STRING|MF_ENABLED, SETCE, ResStr(IDS_SUBRESYNC_CURRENT));
    00805                 }
    00806                 else if(lpnmlv->iSubItem == COL_STYLE && m_mode == TEXTSUB)
    00807                 {
    00808                         m.AppendMenu(MF_SEPARATOR);
    00809
    00810                         int id = STYLEFIRST;
    00811
    00812                         POSITION pos = m_sts.m_styles.GetStartPosition();
    00813                         while(pos && id <= STYLELAST)
    00814                         {
    00815                                 CString key;
    00816                                 void* val;
    00817                                 m_sts.m_styles.GetNextAssoc(pos, key, val);
    00818
    00819                                 styles.Add(key);
    00820
    00821                                 m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
    00822                         }
    00823
    00824                         if(id > STYLEFIRST && m_list.GetSelectedCount() == 1)
    00825                         {
    00826                                 m.AppendMenu(MF_SEPARATOR);
    00827                                 m.AppendMenu(MF_STRING|MF_ENABLED, STYLEEDIT, ResStr(IDS_SUBRESYNC_EDIT));
    00828                         }
    00829                 }
    00830                 else if(lpnmlv->iSubItem == COL_UNICODE && m_mode == TEXTSUB)
    00831                 {
    00832                         m.AppendMenu(MF_SEPARATOR);
    00833                         m.AppendMenu(MF_STRING|MF_ENABLED, UNICODEYES, ResStr(IDS_SUBRESYNC_YES));
    00834                         m.AppendMenu(MF_STRING|MF_ENABLED, UNICODENO, ResStr(IDS_SUBRESYNC_NO));
    00835                 }
    00836                 else if(lpnmlv->iSubItem == COL_LAYER && m_mode == TEXTSUB)
    00837                 {
    00838                         m.AppendMenu(MF_SEPARATOR);
    00839                         m.AppendMenu(MF_STRING|MF_ENABLED, LAYERDEC, ResStr(IDS_SUBRESYNC_DECREASE));
    00840                         m.AppendMenu(MF_STRING|MF_ENABLED, LAYERINC, ResStr(IDS_SUBRESYNC_INCREASE));
    00841                 }
    00842                 else if(lpnmlv->iSubItem == COL_ACTOR && m_mode == TEXTSUB)
    00843                 {
    00844                         CMapStringToPtr actormap;
    00845
    00846                         for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00847                                 actormap[m_sts[i].actor] = NULL;
    00848
    00849                         actormap.RemoveKey(_T(""));
    00850
    00851                         if(actormap.GetCount() > 0)
    00852                         {
    00853                                 m.AppendMenu(MF_SEPARATOR);
    00854
    00855                                 int id = ACTORFIRST;
    00856
    00857                                 POSITION pos = actormap.GetStartPosition();
    00858                                 while(pos && id <= ACTORLAST)
    00859                                 {
    00860                                         CString key;
    00861                                         void* val;
    00862                                         actormap.GetNextAssoc(pos, key, val);
    00863
    00864                                         actors.Add(key);
    00865
    00866                                         m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
    00867                                 }
    00868                         }
    00869                 }
    00870                 else if(lpnmlv->iSubItem == COL_EFFECT && m_mode == TEXTSUB)
    00871                 {
    00872                         CMapStringToPtr effectmap;
    00873
    00874                         for(int i = 0, j = m_sts.GetSize(); i < j; i++)
    00875                                 effectmap[m_sts[i].effect] = NULL;
    00876
    00877                         effectmap.RemoveKey(_T(""));
    00878
    00879                         if(effectmap.GetCount() > 0)
    00880                         {
    00881                                 m.AppendMenu(MF_SEPARATOR);
    00882
    00883                                 int id = EFFECTFIRST;
    00884
    00885                                 POSITION pos = effectmap.GetStartPosition();
    00886                                 while(pos && id <= EFFECTLAST)
    00887                                 {
    00888                                         CString key;
    00889                                         void* val;
    00890                                         effectmap.GetNextAssoc(pos, key, val);
    00891
    00892                                         effects.Add(key);
    00893
    00894                                         m.AppendMenu(MF_STRING|MF_ENABLED, id++, key);
    00895                                 }
    00896                         }
    00897                 }
    00898
    00899                 CPoint p = lpnmlv->ptAction;
    00900                 ::MapWindowPoints(pNMHDR->hwndFrom, HWND_DESKTOP, &p, 1);
    00901
    00902                 UINT id = m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this);
    00903
    00904                 bool fNeedsUpdate = false;
    00905
    00906                 POSITION pos = m_list.GetFirstSelectedItemPosition();
    00907                 while(pos)
    00908                 {
    00909                         int iItem = m_list.GetNextSelectedItem(pos);
    00910
    00911                         SubTime& st = m_subtimes[iItem];
    00912
    00913                         switch(id)
    00914                         {
    00915                         case TOGSEP:
    00916                                 m_list.SetItemData(iItem, m_list.GetItemData(iItem)^TSEP);
    00917                                 m_list.Invalidate();
    00918                                 fNeedsUpdate = true;
    00919                                 break;
    00920                         case DUPITEM:
    00921                                 {
    00922                                         CUIntArray items;
    00923                                         pos = m_list.GetFirstSelectedItemPosition();
    00924                                         while(pos) items.Add(m_list.GetNextSelectedItem(pos));
    00925
    00926                                         qsort(items.GetData(), items.GetSize(), sizeof(UINT), uintcomp);
    00927
    00928                                         for(int i = 0; i < items.GetSize(); i++)
    00929                                         {
    00930                                                 iItem = items[i];
    00931
    00932                                                 STSEntry stse = m_sts[iItem];
    00933                                                 m_sts.InsertAt(iItem+1, stse);
    00934
    00935                                                 SubTime st = m_subtimes[iItem];
    00936                                                 m_subtimes.InsertAt(iItem+1, st);
    00937
    00938                                                 CHeaderCtrl* pHeader = (CHeaderCtrl*)m_list.GetDlgItem(0);
    00939                                                 int nColumnCount = pHeader->GetItemCount();
    00940
    00941                                                 CStringArray sa;
    00942                                                 sa.SetSize(nColumnCount);
    00943                                                 for(int col = 0; col < nColumnCount; col++)
    00944                                                         sa[col] = m_list.GetItemText(iItem, col);
    00945
    00946                                                 DWORD data = m_list.GetItemData(iItem);
    00947                                                 m_list.InsertItem(iItem+1, sa[0]);
    00948                                                 m_list.SetItemData(iItem+1, data);
    00949                                                 for(int col = 1; col < nColumnCount; col++)
    00950                                                         m_list.SetItemText(iItem+1, col, sa[col]);
    00951                                         }
    00952                                 }
    00953
    00954                                 fNeedsUpdate = true;
    00955                                 break;
    00956                         case DELITEM:
    00957                                 {
    00958                                         CUIntArray items;
    00959                                         pos = m_list.GetFirstSelectedItemPosition();
    00960                                         while(pos) items.Add(m_list.GetNextSelectedItem(pos));
    00961
    00962                                         qsort(items.GetData(), items.GetSize(), sizeof(UINT), uintcomp);
    00963
    00964                                         for(int i = 0; i < items.GetSize(); i++)
    00965                                         {
    00966                                                 iItem = items[i];
    00967                                                 m_sts.RemoveAt(iItem);
    00968                                                 m_subtimes.RemoveAt(iItem);
    00969                                                 m_list.DeleteItem(iItem);
    00970                                         }
    00971
    00972                                         iItem = items[items.GetSize()-1];
    00973                                         if(iItem >= m_list.GetItemCount()) iItem = m_list.GetItemCount()-1;
    00974
    00975                                         m_list.SetSelectionMark(iItem);
    00976                                 }
    00977                                 fNeedsUpdate = true;
    00978                                 break;
    00979                         case RESETS: /*if(*/ModStart(iItem, st.orgstart, true);/*)*/ fNeedsUpdate = true; break;
    00980                         case SETOS: /*if(*/ModStart(iItem, st.orgstart);/*)*/ fNeedsUpdate = true; break;
    00981                         case SETCS: /*if(*/ModStart(iItem, (int)(m_rt/10000));/*)*/ fNeedsUpdate = true; break;
    00982                         case RESETE: /*if(*/ModEnd(iItem, st.orgend, true);/*)*/ fNeedsUpdate = true; break;
    00983                         case SETOE: /*if(*/ModEnd(iItem, st.orgend);/*)*/ fNeedsUpdate = true; break;
    00984                         case SETCE: /*if(*/ModEnd(iItem, (int)(m_rt/10000));/*)*/ fNeedsUpdate = true; break;
    00985                         default:
    00986                                 if(STYLEFIRST <= id && id <= STYLELAST)
    00987                                 {
    00988                                         CString s = styles[id - STYLEFIRST];
    00989                                         if(m_sts[iItem].style != s) fNeedsUpdate = true;
    00990                                         m_sts[iItem].style = s;
    00991                                         m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
    00992                                 }
    00993                                 else if(id == STYLEEDIT)
    00994                                 {
    00995                                         CAutoPtrArray<CPPageSubStyle> pages;
    00996                                         CArray<STSStyle*> styles;
    00997
    00998                                         STSStyle* stss = m_sts.GetStyle(iItem);
    00999                                         int iSelPage = 0;
    01000
    01001                                         POSITION pos = m_sts.m_styles.GetStartPosition();
    01002                                         for(int i = 0; pos; i++)
    01003                                         {
    01004                                                 CString key;
    01005                                                 void* val;
    01006                                                 m_sts.m_styles.GetNextAssoc(pos, key, val);
    01007
    01008                                                 CAutoPtr<CPPageSubStyle> page(new CPPageSubStyle());
    01009                                                 page->InitStyle(key, *(STSStyle*)val);
    01010                                                 pages.Add(page);
    01011                                                 styles.Add((STSStyle*)val);
    01012
    01013                                                 if(stss == (STSStyle*)val)
    01014                                                         iSelPage = i;
    01015                                         }
    01016
    01017                                         CPropertySheet dlg(_T("Styles..."), this, iSelPage);
    01018                                         for(int i = 0; i < (int)pages.GetCount(); i++) dlg.AddPage(pages[i]);
    01019
    01020                                         if(dlg.DoModal() == IDOK)
    01021                                         {
    01022                                                 for(int j = 0; j < (int)pages.GetCount(); j++)
    01023                                                 {
    01024                                                         stss = styles[j];
    01025                                                         pages[j]->GetStyle(*stss);
    01026
    01027                                                         for(int i = 0; i < m_sts.GetSize(); i++)
    01028                                                         {
    01029                                                                 if(m_sts.GetStyle(i) == stss)
    01030                                                                 {
    01031                                                                         CString str;
    01032                                                                         m_list.SetItemText(i, COL_TEXT, m_sts.GetStr(i, true));
    01033                                                                         m_list.SetItemText(i, COL_FONT, stss->fontName);
    01034                                                                         str.Format(_T("%d"), stss->charSet);
    01035                                                                         m_list.SetItemText(i, COL_CHARSET, str);
    01036                                                                         str.Format(_T("%d"), m_sts[i].layer);
    01037                                                                 }
    01038                                                         }
    01039                                                 }
    01040
    01041                                                 fNeedsUpdate = true;
    01042                                         }
    01043                                 }
    01044                                 else if(id == UNICODEYES || id == UNICODENO)
    01045                                 {
    01046                                         m_sts.ConvertUnicode(iItem, id == UNICODEYES);
    01047                                         m_list.SetItemText(iItem, COL_TEXT, m_sts.GetStr(iItem, true));
    01048                                         m_list.SetItemText(iItem, COL_UNICODE, m_sts.IsEntryUnicode(iItem) ? _T("yes") : _T("no"));
    01049                                         fNeedsUpdate = true;
    01050                                 }
    01051                                 else if(id == LAYERDEC || id == LAYERINC)
    01052                                 {
    01053                                         int d = (id == LAYERDEC) ? -1 : (id == LAYERINC) ? +1 : 0;
    01054                                         if(d != 0) fNeedsUpdate = true;
    01055                                         m_sts[iItem].layer += d;
    01056                                         CString s;
    01057                                         s.Format(_T("%d"), m_sts[iItem].layer);
    01058                                         m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
    01059                                 }
    01060                                 else if(ACTORFIRST <= id && id <= ACTORLAST)
    01061                                 {
    01062                                         CString s = actors[id - ACTORFIRST];
    01063                                         if(m_sts[iItem].actor != s) fNeedsUpdate = true;
    01064                                         m_sts[iItem].actor = s;
    01065                                         m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
    01066                                 }
    01067                                 else if(EFFECTFIRST <= id && id <= EFFECTLAST)
    01068                                 {
    01069                                         CString s = effects[id - EFFECTFIRST];
    01070                                         if(m_sts[iItem].effect != s) fNeedsUpdate = true;
    01071                                         m_sts[iItem].effect = s;
    01072                                         m_list.SetItemText(iItem, lpnmlv->iSubItem, s);
    01073                                 }
    01074                                 break;
    01075                         }
    01076                 }
    01077
    01078                 if(fNeedsUpdate)
    01079                 {
    01080                         UpdatePreview();
    01081                 }
    01082         }
    01083
    01084         *pResult = 0;
    01085 }
    01086
    01087 void CPlayerSubresyncBar::OnNMDblclkList(NMHDR* pNMHDR, LRESULT* pResult)
    01088 {
    01089         LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)pNMHDR;
    01090
    01091         if(lpnmlv->iItem >= 0 && lpnmlv->iSubItem >= 0 && (m_mode == VOBSUB || m_mode == TEXTSUB))
    01092         {
    01093                 if(CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd())
    01094                 {
    01095                         int t = 0;
    01096                         if(!ParseTime(m_list.GetItemText(lpnmlv->iItem, lpnmlv->iSubItem), t, false))
    01097                                 t = m_sts[lpnmlv->iItem].start;
    01098
    01099                         REFERENCE_TIME rt =
    01100                                 lpnmlv->iSubItem == COL_START ? ((REFERENCE_TIME)t*10000) :
    01101                                 lpnmlv->iSubItem == COL_END ? ((REFERENCE_TIME)t*10000) :
    01102                                 lpnmlv->iSubItem == COL_PREVSTART ? ((REFERENCE_TIME)t*10000) :
    01103                                 lpnmlv->iSubItem == COL_PREVEND ? ((REFERENCE_TIME)t*10000) :
    01104                                 ((REFERENCE_TIME)t*10000);
    01105
    01106                         pFrame->SeekTo(rt);
    01107                 }
    01108         }
    01109
    01110         *pResult = 0;
    01111 }
    01112
    01113 void CPlayerSubresyncBar::OnLvnKeydownList(NMHDR* pNMHDR, LRESULT* pResult)
    01114 {
    01115         LPNMLVKEYDOWN pLVKeyDown = reinterpret_cast<LPNMLVKEYDOWN>(pNMHDR);
    01116
    01117         *pResult = 0;
    01118 }
    01119
    01120 static CUIntArray m_itemGroups;
    01121 static int m_totalGroups;
    01122
    01123 void CPlayerSubresyncBar::OnCustomdrawList(NMHDR* pNMHDR, LRESULT* pResult)
    01124 {
    01125         NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
    01126
    01127         *pResult = CDRF_DODEFAULT;
    01128
    01129         if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
    01130         {
    01131                 m_itemGroups.SetSize(m_list.GetItemCount());
    01132                 m_totalGroups = 0;
    01133                 for(int i = 0, j = m_list.GetItemCount(); i < j; i++)
    01134                 {
    01135                         if(m_list.GetItemData(i)&TSEP) m_totalGroups++;
    01136                         m_itemGroups[i] = m_totalGroups;
    01137                 }
    01138
    01139                 *pResult = CDRF_NOTIFYPOSTPAINT|CDRF_NOTIFYITEMDRAW;
    01140         }
    01141         else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
    01142         {
    01143                 pLVCD->nmcd.uItemState &= ~CDIS_FOCUS;
    01144
    01145                 *pResult = CDRF_NOTIFYPOSTPAINT|CDRF_NOTIFYSUBITEMDRAW;
    01146         }
    01147         else if((CDDS_ITEMPREPAINT|CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
    01148         {
    01149                 COLORREF clrText;
    01150                 COLORREF clrTextBk;
    01151
    01152                 if((pLVCD->iSubItem == COL_START || pLVCD->iSubItem == COL_END || pLVCD->iSubItem == COL_TEXT || pLVCD->iSubItem == COL_STYLE
    01153                         || pLVCD->iSubItem == COL_LAYER || pLVCD->iSubItem == COL_ACTOR || pLVCD->iSubItem == COL_EFFECT)
    01154                         && m_mode == TEXTSUB)
    01155                 {
    01156                         clrText = 0;
    01157                 }
    01158                 else if((pLVCD->iSubItem == COL_START)
    01159                         && m_mode == VOBSUB)
    01160                 {
    01161                         clrText = 0;
    01162                 }
    01163                 else
    01164                 {
    01165                         clrText = 0x606060;
    01166                 }
    01167
    01168                 clrTextBk = 0xffffff;
    01169 //              if(m_totalGroups > 0)
    01170                         clrTextBk -= ((m_itemGroups[pLVCD->nmcd.dwItemSpec]&1) ? 0x100010 : 0x200020);
    01171
    01172                 if(m_sts[pLVCD->nmcd.dwItemSpec].start <= m_rt/10000 && m_rt/10000 < m_sts[pLVCD->nmcd.dwItemSpec].end)
    01173                 {
    01174                         clrText |= 0xFF;
    01175                 }
    01176
    01177                 int nCheck = (int)m_list.GetItemData(pLVCD->nmcd.dwItemSpec);
    01178
    01179                 if((nCheck&1) && (pLVCD->iSubItem == COL_START || pLVCD->iSubItem == COL_PREVSTART))
    01180                 {
    01181                         clrTextBk = 0xffddbb;
    01182                 }
    01183                 else if((nCheck&4) && (/*pLVCD->iSubItem == COL_START ||*/ pLVCD->iSubItem == COL_PREVSTART))
    01184                 {
    01185                         clrTextBk = 0xffeedd;
    01186                 }
    01187
    01188                 if((nCheck&2) && (pLVCD->iSubItem == COL_END || pLVCD->iSubItem == COL_PREVEND))
    01189                 {
    01190                         clrTextBk = 0xffddbb;
    01191                 }
    01192                 else if((nCheck&8) && (/*pLVCD->iSubItem == COL_END ||*/ pLVCD->iSubItem == COL_PREVEND))
    01193                 {
    01194                         clrTextBk = 0xffeedd;
    01195                 }
    01196
    01197                 pLVCD->clrText = clrText;
    01198                 pLVCD->clrTextBk = clrTextBk;
    01199
    01200                 *pResult = CDRF_NOTIFYPOSTPAINT;
    01201         }
    01202         else if((CDDS_ITEMPOSTPAINT|CDDS_SUBITEM) == pLVCD->nmcd.dwDrawStage)
    01203         {
    01204 //              *pResult = CDRF_DODEFAULT;
    01205         }
    01206         else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage)
    01207         {
    01208         int nItem = static_cast<int>(pLVCD->nmcd.dwItemSpec);
    01209
    01210                 LVITEM rItem;
    01211         ZeroMemory(&rItem, sizeof(LVITEM));
    01212         rItem.mask  = LVIF_IMAGE | LVIF_STATE;
    01213         rItem.iItem = nItem;
    01214         rItem.stateMask = LVIS_SELECTED;
    01215         m_list.GetItem(&rItem);
    01216
    01217                 {
    01218             CDC* pDC = CDC::FromHandle(pLVCD->nmcd.hdc);
    01219
    01220                         CRect rcItem;
    01221             m_list.GetItemRect(nItem, &rcItem, LVIR_BOUNDS);
    01222
    01223                         {
    01224                                 bool fSeparator = nItem < m_list.GetItemCount()-1 && (m_list.GetItemData(nItem+1)&TSEP);
    01225                                 CPen p(PS_INSIDEFRAME, 1, fSeparator ? 0x404040 : 0xe0e0e0);
    01226                                 CPen* old = pDC->SelectObject(&p);
    01227                                 pDC->MoveTo(CPoint(rcItem.left, rcItem.bottom-1));
    01228                                 pDC->LineTo(CPoint(rcItem.right, rcItem.bottom-1));
    01229                                 pDC->SelectObject(old);
    01230                         }
    01231
    01232                         {
    01233                                 CPen p(PS_INSIDEFRAME, 1, 0xe0e0e0);
    01234                                 CPen* old = pDC->SelectObject(&p);
    01235
    01236                                 CHeaderCtrl* pHeader = (CHeaderCtrl*)m_list.GetDlgItem(0);
    01237                                 int nColumnCount = pHeader->GetItemCount();
    01238
    01239                                 // Get the column offset
    01240                                 int offset = rcItem.left;
    01241                                 for(int i = 0; i < nColumnCount; i++)
    01242                                 {
    01243                                         offset += m_list.GetColumnWidth(i);
    01244                                         pDC->MoveTo(CPoint(offset, rcItem.top));
    01245                                         pDC->LineTo(CPoint(offset, rcItem.bottom));
    01246                                 }
    01247
    01248                                 pDC->SelectObject(old);
    01249                         }
    01250
    01251             *pResult = CDRF_SKIPDEFAULT;
    01252         }
    01253         }
    01254         else if(CDDS_POSTPAINT == pLVCD->nmcd.dwDrawStage)
    01255         {
    01256         }
    01257 }
    01258