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 

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