2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 // PlayerSubresyncBar.cpp : implementation file
28 #include "PlayerSubresyncBar.h"
30 // CPlayerSubresyncBar
32 IMPLEMENT_DYNAMIC(CPlayerSubresyncBar
, CSizingControlBarG
)
33 CPlayerSubresyncBar::CPlayerSubresyncBar()
40 CPlayerSubresyncBar::~CPlayerSubresyncBar()
44 BOOL
CPlayerSubresyncBar::Create(CWnd
* pParentWnd
, CCritSec
* pSubLock
)
46 if(!CSizingControlBarG::Create(_T("Subresync"), pParentWnd
, 0))
49 m_pSubLock
= pSubLock
;
52 WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
,
53 WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|WS_TABSTOP
|LVS_REPORT
/*|LVS_SHOWSELALWAYS*/|LVS_AUTOARRANGE
|LVS_NOSORTHEADER
,
54 CRect(0,0,100,100), this, IDC_SUBRESYNCLIST
);
56 m_list
.SetExtendedStyle(m_list
.GetExtendedStyle()|LVS_EX_FULLROWSELECT
|LVS_EX_DOUBLEBUFFER
);
61 BOOL
CPlayerSubresyncBar::PreCreateWindow(CREATESTRUCT
& cs
)
63 if(!CSizingControlBarG::PreCreateWindow(cs
))
69 BOOL
CPlayerSubresyncBar::PreTranslateMessage(MSG
* pMsg
)
71 if(IsWindow(pMsg
->hwnd
) && IsVisible() && pMsg
->message
>= WM_KEYFIRST
&& pMsg
->message
<= WM_KEYLAST
)
73 if(IsShortCut(pMsg
) || IsDialogMessage(pMsg
))
77 return CSizingControlBarG::PreTranslateMessage(pMsg
);
80 void CPlayerSubresyncBar::SetTime(__int64 rt
)
86 if(!m_sts
.SearchSubs((int)(rt
/10000), 25, &curSegment
))
91 if(m_lastSegment
!= curSegment
) m_list
.Invalidate();
92 m_lastSegment
= curSegment
;
95 void CPlayerSubresyncBar::SetSubtitle(ISubStream
* pSubStream
, double fps
)
97 m_pSubStream
= pSubStream
;
105 if(!m_pSubStream
) return;
108 m_pSubStream
->GetClassID(&clsid
);
110 if(clsid
== __uuidof(CVobSubFile
))
112 CVobSubFile
* pVSF
= (CVobSubFile
*)(ISubStream
*)m_pSubStream
;
116 CAtlArray
<CVobSubFile::SubPos
>& sp
= pVSF
->m_langs
[pVSF
->m_iLang
].subpos
;
118 for(int i
= 0, j
= sp
.GetCount(); i
< j
; i
++)
121 str
.Format(_T("%d,%d,%d,%d"), sp
[i
].vobid
, sp
[i
].cellid
, sp
[i
].fForced
, i
);
122 m_sts
.Add(TToW(str
), false, (int)sp
[i
].start
, (int)sp
[i
].stop
);
125 m_sts
.CreateDefaultStyle(DEFAULT_CHARSET
);
127 pVSF
->m_fOnlyShowForcedSubs
= false;
129 for(int i
= 0, j
= m_list
.GetHeaderCtrl()->GetItemCount(); i
< j
; i
++) m_list
.DeleteColumn(0);
130 m_list
.InsertColumn(COL_START
, _T("Time"), LVCFMT_LEFT
, 80);
131 m_list
.InsertColumn(COL_END
, _T("End"), LVCFMT_LEFT
, 80);
132 m_list
.InsertColumn(COL_PREVSTART
, _T("Preview"), LVCFMT_LEFT
, 80);
133 m_list
.InsertColumn(COL_PREVEND
, _T("End"), LVCFMT_LEFT
, 80);
134 m_list
.InsertColumn(COL_VOBID
, _T("Vob ID"), LVCFMT_CENTER
, 60);
135 m_list
.InsertColumn(COL_CELLID
, _T("Cell ID"), LVCFMT_CENTER
, 60);
136 m_list
.InsertColumn(COL_FORCED
, _T("Forced"), LVCFMT_CENTER
, 60);
138 else if(clsid
== __uuidof(CRenderedTextSubtitle
))
140 CRenderedTextSubtitle
* pRTS
= (CRenderedTextSubtitle
*)(ISubStream
*)m_pSubStream
;
145 m_sts
.ConvertToTimeBased(fps
);
146 m_sts
.Sort(true); /*!!m_fUnlink*/
149 if(!m_sts
.IsEntryUnicode(0))
151 CFont
* f
= m_list
.GetFont();
154 lf
.lfCharSet
= m_sts
.GetCharSet(0);
155 m_font
.DeleteObject();
156 m_font
.CreateFontIndirect(&lf
);
157 m_list
.SetFont(&m_font
);
160 for(int i
= 0, j
= m_list
.GetHeaderCtrl()->GetItemCount(); i
< j
; i
++) m_list
.DeleteColumn(0);
161 m_list
.InsertColumn(COL_START
, _T("Time"), LVCFMT_LEFT
, 90);
162 m_list
.InsertColumn(COL_END
, _T("End"), LVCFMT_LEFT
, 4);
163 m_list
.InsertColumn(COL_PREVSTART
, _T("Preview"), LVCFMT_LEFT
, 80);
164 m_list
.InsertColumn(COL_PREVEND
, _T("End"), LVCFMT_LEFT
, 4);
165 m_list
.InsertColumn(COL_TEXT
, _T("Text"), LVCFMT_LEFT
, 275);
166 m_list
.InsertColumn(COL_STYLE
, _T("Style"), LVCFMT_LEFT
, 80);
167 m_list
.InsertColumn(COL_FONT
, _T("Font"), LVCFMT_LEFT
, 60);
168 m_list
.InsertColumn(COL_CHARSET
, _T("CharSet"), LVCFMT_CENTER
, 20);
169 m_list
.InsertColumn(COL_UNICODE
, _T("Unicode"), LVCFMT_CENTER
, 40);
170 m_list
.InsertColumn(COL_LAYER
, _T("Layer"), LVCFMT_CENTER
, 50);
171 m_list
.InsertColumn(COL_ACTOR
, _T("Actor"), LVCFMT_LEFT
, 80);
172 m_list
.InsertColumn(COL_EFFECT
, _T("Effect"), LVCFMT_LEFT
, 80);
175 m_subtimes
.SetCount(m_sts
.GetCount());
177 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
179 m_subtimes
[i
].orgstart
= m_sts
[i
].start
;
180 m_subtimes
[i
].orgend
= m_sts
[i
].end
;
186 void CPlayerSubresyncBar::ResetSubtitle()
188 m_list
.DeleteAllItems();
190 if(m_mode
== VOBSUB
|| m_mode
== TEXTSUB
)
194 int prevstart
= INT_MIN
;
196 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
198 m_subtimes
[i
].newstart
= m_subtimes
[i
].orgstart
;
199 m_subtimes
[i
].newend
= m_subtimes
[i
].orgend
;
201 FormatTime(i
, buff
, 0, false);
202 m_list
.InsertItem(i
, buff
, COL_START
);
203 FormatTime(i
, buff
, 0, true);
204 m_list
.SetItemText(i
, COL_END
, buff
);
206 if(prevstart
> m_subtimes
[i
].orgstart
) m_list
.SetItemData(i
, TSEP
);
207 prevstart
= m_subtimes
[i
].orgstart
;
209 SetCheck(i
, false, false);
214 m_list
.SetColumnWidth(COL_START
, LVSCW_AUTOSIZE
);
215 m_list
.SetColumnWidth(COL_PREVSTART
, LVSCW_AUTOSIZE
);
221 void CPlayerSubresyncBar::SaveSubtitle()
223 CMainFrame
* pFrame
= ((CMainFrame
*)AfxGetMainWnd());
227 m_pSubStream
->GetClassID(&clsid
);
229 if(clsid
== __uuidof(CVobSubFile
) && m_mode
== VOBSUB
)
231 CVobSubFile
* pVSF
= (CVobSubFile
*)(ISubStream
*)m_pSubStream
;
233 CAutoLock
cAutoLock(m_pSubLock
);
235 CAtlArray
<CVobSubFile::SubPos
>& sp
= pVSF
->m_langs
[pVSF
->m_iLang
].subpos
;
237 for(int i
= 0, j
= sp
.GetCount(); i
< j
; i
++)
239 sp
[i
].fValid
= false;
242 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
244 int vobid
, cellid
, forced
, spnum
, c
;
245 if(_stscanf(m_sts
.GetStr(i
), _T("%d%c%d%c%d%c%d"), &vobid
, &c
, &cellid
, &c
, &forced
, &c
, &spnum
) != 7) continue;
246 sp
[spnum
].start
= m_sts
[i
].start
;
247 sp
[spnum
].stop
= m_sts
[i
].end
;
248 sp
[spnum
].fValid
= true;
251 else if(clsid
== __uuidof(CRenderedTextSubtitle
) && m_mode
== TEXTSUB
)
253 CRenderedTextSubtitle
* pRTS
= (CRenderedTextSubtitle
*)(ISubStream
*)m_pSubStream
;
255 CAutoLock
cAutoLock(m_pSubLock
);
264 pFrame
->InvalidateSubtitle();
267 void CPlayerSubresyncBar::UpdatePreview()
269 if(m_mode
== VOBSUB
|| m_mode
== TEXTSUB
)
273 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
275 bool fStartMod
, fEndMod
, fStartAdj
, fEndAdj
;
276 GetCheck(i
, fStartMod
, fEndMod
, fStartAdj
, fEndAdj
);
277 m_sts
[i
].start
= (fStartMod
||fStartAdj
) ? m_subtimes
[i
].newstart
: m_subtimes
[i
].orgstart
;
278 m_sts
[i
].end
= (fEndMod
||fEndAdj
) ? m_subtimes
[i
].newend
: m_subtimes
[i
].orgend
;
285 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
;)
291 for(end
= i
; end
< j
; end
++)
293 int data
= (int)m_list
.GetItemData(end
);
294 if((data
&TSEP
) && end
> i
) break;
295 if(data
&(TSMOD
|TSADJ
))
299 if(schk
.GetCount() == 0)
301 for(; start
< end
; start
++)
303 m_sts
[start
].start
= m_subtimes
[start
].orgstart
;
304 m_sts
[start
].end
= m_subtimes
[start
].orgend
;
307 else if(schk
.GetCount() == 1)
310 int dt
= m_subtimes
[k
].newstart
- m_subtimes
[k
].orgstart
;
311 for(; start
< end
; start
++)
313 m_sts
[start
].start
= m_subtimes
[start
].orgstart
+ dt
;
314 m_sts
[start
].end
= (m_list
.GetItemData(start
)&TEMOD
)
315 ? m_subtimes
[start
].newend
316 : (m_subtimes
[start
].orgend
+ dt
);
319 else if(schk
.GetCount() >= 2)
324 for(int k
= 0, l
= schk
.GetCount()-1; k
< l
; k
++)
329 ti0
= m_subtimes
[i0
].orgstart
;
330 ds
= m_subtimes
[i1
].orgstart
- ti0
;
334 for(; start
< i1
; start
++)
336 m_sts
[start
].start
= ti0
;
337 m_sts
[start
].end
= (m_list
.GetItemData(start
)&TEMOD
)
338 ? m_subtimes
[start
].newend
339 : (ti0
+ m_subtimes
[start
].orgend
- m_subtimes
[start
].orgstart
);
344 m
= double(m_subtimes
[i1
].newstart
- m_subtimes
[i0
].newstart
) / ds
;
346 for(; start
< i1
; start
++)
348 m_sts
[start
].start
= int((m_subtimes
[start
].orgstart
- ti0
)*m
+ m_subtimes
[i0
].newstart
);
349 m_sts
[start
].end
= (m_list
.GetItemData(start
)&TEMOD
)
350 ? m_subtimes
[start
].newend
352 ? (m_sts
[start
].start
+ m_subtimes
[start
].orgend
- m_subtimes
[start
].orgstart
)
353 : (m_sts
[start
].start
+ int((m_subtimes
[start
].orgend
- m_subtimes
[start
].orgstart
)*m
));
360 for(; start
< end
; start
++)
362 m_sts
[start
].start
= ti0
;
363 m_sts
[start
].end
= (m_list
.GetItemData(start
)&TEMOD
)
364 ? m_subtimes
[start
].newend
365 : (ti0
+ (m_subtimes
[start
].orgend
- m_subtimes
[start
].orgstart
));
370 for(; start
< end
; start
++)
372 m_sts
[start
].start
= int((m_subtimes
[start
].orgstart
- ti0
)*m
+ m_subtimes
[i0
].newstart
);
373 m_sts
[start
].end
= (m_list
.GetItemData(start
)&TEMOD
)
374 ? m_subtimes
[start
].newend
376 ? (m_sts
[start
].start
+ m_subtimes
[start
].orgend
- m_subtimes
[start
].orgstart
)
377 : (m_sts
[start
].start
+ int((m_subtimes
[start
].orgend
- m_subtimes
[start
].orgstart
)*m
));
386 m_sts
.CreateSegments();
388 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
391 FormatTime(i
, buff
, 2, false);
392 m_list
.SetItemText(i
, COL_PREVSTART
, buff
);
393 FormatTime(i
, buff
, 2, true);
394 m_list
.SetItemText(i
, COL_PREVEND
, buff
);
397 if(IsWindowVisible())
404 void CPlayerSubresyncBar::UpdateStrings()
408 if(m_mode
== TEXTSUB
)
410 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
413 m_sts
.GetStyle(i
, stss
);
415 m_list
.SetItemText(i
, COL_TEXT
, m_sts
.GetStr(i
, true));
416 m_list
.SetItemText(i
, COL_STYLE
, m_sts
[i
].style
);
417 m_list
.SetItemText(i
, COL_FONT
, stss
.fontName
);
418 str
.Format(_T("%d"), stss
.charSet
);
419 m_list
.SetItemText(i
, COL_CHARSET
, str
);
420 m_list
.SetItemText(i
, COL_UNICODE
, m_sts
.IsEntryUnicode(i
) ? _T("yes") : _T("no"));
421 str
.Format(_T("%d"), m_sts
[i
].layer
);
422 m_list
.SetItemText(i
, COL_LAYER
, str
);
423 m_list
.SetItemText(i
, COL_ACTOR
, m_sts
[i
].actor
);
424 m_list
.SetItemText(i
, COL_EFFECT
, m_sts
[i
].effect
);
427 else if(m_mode
== VOBSUB
)
429 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
431 int vobid
, cellid
, forced
, c
;
432 if(_stscanf(m_sts
.GetStr(i
), _T("%d%c%d%c%d"), &vobid
, &c
, &cellid
, &c
, &forced
) != 5) continue;
433 if(vobid
< 0) str
= _T("-");
434 else str
.Format(_T("%d"), vobid
);
435 m_list
.SetItemText(i
, COL_VOBID
, str
);
436 if(cellid
< 0) str
= _T("-");
437 else str
.Format(_T("%d"), cellid
);
438 m_list
.SetItemText(i
, COL_CELLID
, str
);
439 str
= forced
?_T("Yes"):_T("");
440 m_list
.SetItemText(i
, COL_FORCED
, str
);
445 void CPlayerSubresyncBar::GetCheck(int iItem
, bool& fStartMod
, bool& fEndMod
, bool& fStartAdj
, bool& fEndAdj
)
447 if(0 <= iItem
&& iItem
< m_sts
.GetCount())
449 int nCheck
= (int)m_list
.GetItemData(iItem
);
450 fStartMod
= !!(nCheck
&TSMOD
);
451 fEndMod
= !!(nCheck
&TEMOD
);
452 fStartAdj
= !!(nCheck
&TSADJ
);
453 fEndAdj
= !!(nCheck
&TEADJ
);
457 void CPlayerSubresyncBar::SetCheck(int iItem
, bool fStart
, bool fEnd
)
459 if(0 <= iItem
&& iItem
< m_sts
.GetCount())
461 SubTime
& st
= m_subtimes
[iItem
];
463 int nCheck
= (int)m_list
.GetItemData(iItem
) & TSEP
;
465 if(fStart
) nCheck
|= TSMOD
;
466 else if(abs(st
.orgstart
-st
.newstart
)) nCheck
|= TSADJ
;
467 if(fEnd
) nCheck
|= TEMOD
;
468 else if(abs(st
.orgend
-st
.newend
)) nCheck
|= TEADJ
;
470 m_list
.SetItemData(iItem
, (DWORD
)nCheck
);
473 FormatTime(iItem
, buff
, fStart
, false);
474 m_list
.SetItemText(iItem
, COL_START
, buff
);
475 FormatTime(iItem
, buff
, fEnd
, true);
476 m_list
.SetItemText(iItem
, COL_END
, buff
);
480 bool CPlayerSubresyncBar::ModStart(int iItem
, int t
, bool fReset
)
484 bool fStartMod
, fEndMod
, fStartAdj
, fEndAdj
;
485 GetCheck(iItem
, fStartMod
, fEndMod
, fStartAdj
, fEndAdj
);
487 SubTime
& st
= m_subtimes
[iItem
];
489 // if(fStartMod || fStartAdj || st.orgstart != t || fReset)
491 fRet
= (st
.newstart
!= t
);
494 if(!fEndMod
) st
.newend
= st
.newstart
+ (st
.orgend
- st
.orgstart
);
495 else if(fReset
) st
.newstart
= st
.newend
- (st
.orgend
- st
.orgstart
);
497 SetCheck(iItem
, !fReset
, fEndMod
);
503 bool CPlayerSubresyncBar::ModEnd(int iItem
, int t
, bool fReset
)
507 bool fStartMod
, fEndMod
, fStartAdj
, fEndAdj
;
508 GetCheck(iItem
, fStartMod
, fEndMod
, fStartAdj
, fEndAdj
);
510 SubTime
& st
= m_subtimes
[iItem
];
512 // if(fEndMod || fEndAdj || st.orgend != t || fReset)
514 fRet
= (st
.newend
!= t
);
517 if(!fStartMod
) st
.newstart
= st
.newend
- (st
.orgend
- st
.orgstart
);
518 else if(fReset
) st
.newend
= st
.newstart
+ (st
.orgend
- st
.orgstart
);
520 SetCheck(iItem
, fStartMod
, !fReset
);
526 void CPlayerSubresyncBar::FormatTime(int iItem
, TCHAR
* buff
, int time
, bool fEnd
)
529 ?(time
== 2 ? m_sts
[iItem
].start
530 : time
== 1 ? m_subtimes
[iItem
].newstart
531 : m_subtimes
[iItem
].orgstart
)
532 : (time
== 2 ? m_sts
[iItem
].end
533 : time
== 1 ? m_subtimes
[iItem
].newend
534 : m_subtimes
[iItem
].orgend
);
536 _stprintf(buff
, t
>= 0
537 ? _T("%02d:%02d:%02d.%03d")
538 : _T("-%02d:%02d:%02d.%03d"),
546 BEGIN_MESSAGE_MAP(CPlayerSubresyncBar
, CSizingControlBarG
)
548 ON_NOTIFY(LVN_BEGINLABELEDIT
, IDC_SUBRESYNCLIST
, OnBeginlabeleditList
)
549 ON_NOTIFY(LVN_DOLABELEDIT
, IDC_SUBRESYNCLIST
, OnDolabeleditList
)
550 ON_NOTIFY(LVN_ENDLABELEDIT
, IDC_SUBRESYNCLIST
, OnEndlabeleditList
)
551 ON_NOTIFY(NM_RCLICK
, IDC_SUBRESYNCLIST
, OnRclickList
)
552 ON_NOTIFY(NM_DBLCLK
, IDC_SUBRESYNCLIST
, OnNMDblclkList
)
553 ON_NOTIFY(LVN_KEYDOWN
, IDC_SUBRESYNCLIST
, OnLvnKeydownList
)
554 ON_NOTIFY(NM_CUSTOMDRAW
, IDC_SUBRESYNCLIST
, OnCustomdrawList
)
558 // CPlayerSubresyncBar message handlers
560 void CPlayerSubresyncBar::OnSize(UINT nType
, int cx
, int cy
)
562 CSizingControlBarG::OnSize(nType
, cx
, cy
);
564 if(::IsWindow(m_list
.m_hWnd
))
569 m_list
.MoveWindow(r
);
573 static bool ParseTime(CString str
, int& ret
, bool fWarn
= true)
575 int sign
= 1, h
, m
, s
, ms
;
579 if(str
.GetLength() > 0 && str
[0] == '-') sign
= -1;
581 int n
= _stscanf(str
, _T("%d%c%d%c%d%c%d"), &h
, &c
, &m
, &c
, &s
, &c
, &ms
);
589 && 0 <= ms
&& ms
< 1000)
591 ret
= sign
*(h
*60*60*1000+m
*60*1000+s
*1000+ms
);
595 if(fWarn
) AfxMessageBox(_T("The correct time format is [-]hh:mm:ss.ms\n(e.g. 01:23:45.678)"));
599 void CPlayerSubresyncBar::OnBeginlabeleditList(NMHDR
* pNMHDR
, LRESULT
* pResult
)
601 LV_DISPINFO
* pDispInfo
= (LV_DISPINFO
*)pNMHDR
;
602 LV_ITEM
* pItem
= &pDispInfo
->item
;
606 if(pItem
->iItem
>= 0)
608 if((pItem
->iSubItem
== COL_START
|| pItem
->iSubItem
== COL_END
|| pItem
->iSubItem
== COL_TEXT
609 || pItem
->iSubItem
== COL_STYLE
|| pItem
->iSubItem
== COL_LAYER
610 || pItem
->iSubItem
== COL_ACTOR
|| pItem
->iSubItem
== COL_EFFECT
)
611 && m_mode
== TEXTSUB
)
615 else if((pItem
->iSubItem
== COL_START
)
623 void CPlayerSubresyncBar::OnDolabeleditList(NMHDR
* pNMHDR
, LRESULT
* pResult
)
625 LV_DISPINFO
* pDispInfo
= (LV_DISPINFO
*)pNMHDR
;
626 LV_ITEM
* pItem
= &pDispInfo
->item
;
630 if(pItem
->iItem
>= 0)
632 if((pItem
->iSubItem
== COL_START
|| pItem
->iSubItem
== COL_END
|| pItem
->iSubItem
== COL_TEXT
633 || pItem
->iSubItem
== COL_STYLE
|| pItem
->iSubItem
== COL_LAYER
634 || pItem
->iSubItem
== COL_ACTOR
|| pItem
->iSubItem
== COL_EFFECT
)
635 && m_mode
== TEXTSUB
)
637 m_list
.ShowInPlaceEdit(pItem
->iItem
, pItem
->iSubItem
);
640 else if((pItem
->iSubItem
== COL_START
)
643 m_list
.ShowInPlaceEdit(pItem
->iItem
, pItem
->iSubItem
);
649 void CPlayerSubresyncBar::OnEndlabeleditList(NMHDR
* pNMHDR
, LRESULT
* pResult
)
651 LV_DISPINFO
* pDispInfo
= (LV_DISPINFO
*)pNMHDR
;
652 LV_ITEM
* pItem
= &pDispInfo
->item
;
656 if(!m_list
.m_fInPlaceDirty
)
659 bool fNeedsUpdate
= false;
661 if(pItem
->iItem
>= 0 && pItem
->pszText
&& (m_mode
== VOBSUB
|| m_mode
== TEXTSUB
))
663 if(pItem
->iSubItem
== COL_START
)
666 if(ParseTime(pItem
->pszText
, t
))
668 fNeedsUpdate
= ModStart(pItem
->iItem
, t
);
673 else if(pItem
->iSubItem
== COL_END
&& m_mode
== TEXTSUB
)
676 if(ParseTime(pItem
->pszText
, t
))
678 fNeedsUpdate
= ModEnd(pItem
->iItem
, t
);
683 else if(pItem
->iSubItem
== COL_TEXT
&& m_mode
== TEXTSUB
)
685 CString str
= m_sts
.GetStr(pItem
->iItem
, true);
687 if(str
!= pItem
->pszText
)
690 m_sts
.SetStr(pItem
->iItem
, CString(pItem
->pszText
), true);
691 m_list
.SetItemText(pItem
->iItem
, pItem
->iSubItem
, m_sts
.GetStr(pItem
->iItem
, true));
694 else if(pItem
->iSubItem
== COL_STYLE
&& m_mode
== TEXTSUB
)
696 CString
str(pItem
->pszText
);
699 if(!str
.IsEmpty() && m_sts
[pItem
->iItem
].style
!= str
)
703 if(!m_sts
.m_styles
.Lookup(str
))
704 m_sts
.AddStyle(str
, new STSStyle());
706 m_sts
[pItem
->iItem
].style
= str
;
708 m_list
.SetItemText(pItem
->iItem
, pItem
->iSubItem
, pItem
->pszText
);
711 else if(pItem
->iSubItem
== COL_LAYER
&& m_mode
== TEXTSUB
)
714 if(_stscanf(pItem
->pszText
, _T("%d"), &l
) == 1)
717 m_sts
[pItem
->iItem
].layer
= l
;
719 str
.Format(_T("%d"), l
);
720 m_list
.SetItemText(pItem
->iItem
, pItem
->iSubItem
, str
);
723 else if(pItem
->iSubItem
== COL_ACTOR
&& m_mode
== TEXTSUB
)
725 CString
str(pItem
->pszText
);
730 m_sts
[pItem
->iItem
].actor
= str
;
731 m_list
.SetItemText(pItem
->iItem
, pItem
->iSubItem
, str
);
734 else if(pItem
->iSubItem
== COL_EFFECT
&& m_mode
== TEXTSUB
)
736 CString
str(pItem
->pszText
);
741 m_sts
[pItem
->iItem
].effect
= str
;
742 m_list
.SetItemText(pItem
->iItem
, pItem
->iSubItem
, str
);
753 static int uintcomp(const void* i1
, const void* i2
)
755 return(*((UINT
*)i2
) - *((UINT
*)i1
));
758 void CPlayerSubresyncBar::OnRclickList(NMHDR
* pNMHDR
, LRESULT
* pResult
)
760 LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)pNMHDR
;
762 if(lpnmlv
->iItem
>= 0 && lpnmlv
->iSubItem
>= 0)
768 RESETS
, SETOS
, SETCS
, RESETE
, SETOE
, SETCE
,
769 STYLEFIRST
, STYLELAST
=STYLEFIRST
+1000, STYLEEDIT
,
770 UNICODEYES
, UNICODENO
,
772 ACTORFIRST
, ACTORLAST
=ACTORFIRST
+1000,
773 EFFECTFIRST
, EFFECTLAST
=EFFECTFIRST
+1000
778 CStringArray effects
;
783 if(m_mode
== VOBSUB
|| m_mode
== TEXTSUB
)
785 m
.AppendMenu(MF_STRING
|MF_ENABLED
, TOGSEP
, ResStr(IDS_SUBRESYNC_SEPARATOR
));
786 m
.AppendMenu(MF_SEPARATOR
);
787 if(m_mode
== TEXTSUB
) m
.AppendMenu(MF_STRING
|MF_ENABLED
, DUPITEM
, ResStr(IDS_SUBRESYNC_DUPLICATE
));
788 m
.AppendMenu(MF_STRING
|MF_ENABLED
, DELITEM
, ResStr(IDS_SUBRESYNC_DELETE
));
791 if(lpnmlv
->iSubItem
== COL_START
&& (m_mode
== VOBSUB
|| m_mode
== TEXTSUB
))
793 m
.AppendMenu(MF_SEPARATOR
);
794 m
.AppendMenu(MF_STRING
|MF_ENABLED
, RESETS
, ResStr(IDS_SUBRESYNC_RESET
) + _T("\tF1"));
795 m
.AppendMenu(MF_STRING
|MF_ENABLED
, SETOS
, ResStr(IDS_SUBRESYNC_ORIGINAL
) + _T("\tF3"));
796 m
.AppendMenu(MF_STRING
|MF_ENABLED
, SETCS
, ResStr(IDS_SUBRESYNC_CURRENT
) + _T("\tF5"));
798 else if(lpnmlv
->iSubItem
== COL_END
&& m_mode
== TEXTSUB
)
800 m
.AppendMenu(MF_SEPARATOR
);
801 m
.AppendMenu(MF_STRING
|MF_ENABLED
, RESETE
, ResStr(IDS_SUBRESYNC_RESET
) + _T("\tF2"));
802 m
.AppendMenu(MF_STRING
|MF_ENABLED
, SETOE
, ResStr(IDS_SUBRESYNC_ORIGINAL
) + _T("\tF4"));
803 m
.AppendMenu(MF_STRING
|MF_ENABLED
, SETCE
, ResStr(IDS_SUBRESYNC_CURRENT
) + _T("\tF6"));
805 else if(lpnmlv
->iSubItem
== COL_STYLE
&& m_mode
== TEXTSUB
)
807 m
.AppendMenu(MF_SEPARATOR
);
811 POSITION pos
= m_sts
.m_styles
.GetStartPosition();
812 while(pos
&& id
<= STYLELAST
)
816 m_sts
.m_styles
.GetNextAssoc(pos
, key
, val
);
818 m
.AppendMenu(MF_STRING
|MF_ENABLED
, id
++, key
);
821 if(id
> STYLEFIRST
&& m_list
.GetSelectedCount() == 1)
823 m
.AppendMenu(MF_SEPARATOR
);
824 m
.AppendMenu(MF_STRING
|MF_ENABLED
, STYLEEDIT
, ResStr(IDS_SUBRESYNC_EDIT
));
827 else if(lpnmlv
->iSubItem
== COL_UNICODE
&& m_mode
== TEXTSUB
)
829 m
.AppendMenu(MF_SEPARATOR
);
830 m
.AppendMenu(MF_STRING
|MF_ENABLED
, UNICODEYES
, ResStr(IDS_SUBRESYNC_YES
));
831 m
.AppendMenu(MF_STRING
|MF_ENABLED
, UNICODENO
, ResStr(IDS_SUBRESYNC_NO
));
833 else if(lpnmlv
->iSubItem
== COL_LAYER
&& m_mode
== TEXTSUB
)
835 m
.AppendMenu(MF_SEPARATOR
);
836 m
.AppendMenu(MF_STRING
|MF_ENABLED
, LAYERDEC
, ResStr(IDS_SUBRESYNC_DECREASE
));
837 m
.AppendMenu(MF_STRING
|MF_ENABLED
, LAYERINC
, ResStr(IDS_SUBRESYNC_INCREASE
));
839 else if(lpnmlv
->iSubItem
== COL_ACTOR
&& m_mode
== TEXTSUB
)
841 CMapStringToPtr actormap
;
843 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
844 actormap
[m_sts
[i
].actor
] = NULL
;
846 actormap
.RemoveKey(_T(""));
848 if(actormap
.GetCount() > 0)
850 m
.AppendMenu(MF_SEPARATOR
);
854 POSITION pos
= actormap
.GetStartPosition();
855 while(pos
&& id
<= ACTORLAST
)
859 actormap
.GetNextAssoc(pos
, key
, val
);
863 m
.AppendMenu(MF_STRING
|MF_ENABLED
, id
++, key
);
867 else if(lpnmlv
->iSubItem
== COL_EFFECT
&& m_mode
== TEXTSUB
)
869 CMapStringToPtr effectmap
;
871 for(int i
= 0, j
= m_sts
.GetCount(); i
< j
; i
++)
872 effectmap
[m_sts
[i
].effect
] = NULL
;
874 effectmap
.RemoveKey(_T(""));
876 if(effectmap
.GetCount() > 0)
878 m
.AppendMenu(MF_SEPARATOR
);
880 int id
= EFFECTFIRST
;
882 POSITION pos
= effectmap
.GetStartPosition();
883 while(pos
&& id
<= EFFECTLAST
)
887 effectmap
.GetNextAssoc(pos
, key
, val
);
891 m
.AppendMenu(MF_STRING
|MF_ENABLED
, id
++, key
);
896 CPoint p
= lpnmlv
->ptAction
;
897 ::MapWindowPoints(pNMHDR
->hwndFrom
, HWND_DESKTOP
, &p
, 1);
899 UINT id
= m
.TrackPopupMenu(TPM_LEFTBUTTON
|TPM_RETURNCMD
, p
.x
, p
.y
, this);
901 bool fNeedsUpdate
= false;
903 POSITION pos
= m_list
.GetFirstSelectedItemPosition();
906 int iItem
= m_list
.GetNextSelectedItem(pos
);
908 SubTime
& st
= m_subtimes
[iItem
];
913 m_list
.SetItemData(iItem
, m_list
.GetItemData(iItem
)^TSEP
);
920 pos
= m_list
.GetFirstSelectedItemPosition();
921 while(pos
) items
.Add(m_list
.GetNextSelectedItem(pos
));
923 qsort(items
.GetData(), items
.GetCount(), sizeof(UINT
), uintcomp
);
925 for(int i
= 0; i
< items
.GetCount(); i
++)
929 STSEntry stse
= m_sts
[iItem
];
930 m_sts
.InsertAt(iItem
+1, stse
);
932 SubTime st
= m_subtimes
[iItem
];
933 m_subtimes
.InsertAt(iItem
+1, st
);
935 CHeaderCtrl
* pHeader
= (CHeaderCtrl
*)m_list
.GetDlgItem(0);
936 int nColumnCount
= pHeader
->GetItemCount();
939 sa
.SetSize(nColumnCount
);
940 for(int col
= 0; col
< nColumnCount
; col
++)
941 sa
[col
] = m_list
.GetItemText(iItem
, col
);
943 DWORD data
= m_list
.GetItemData(iItem
);
944 m_list
.InsertItem(iItem
+1, sa
[0]);
945 m_list
.SetItemData(iItem
+1, data
);
946 for(int col
= 1; col
< nColumnCount
; col
++)
947 m_list
.SetItemText(iItem
+1, col
, sa
[col
]);
956 pos
= m_list
.GetFirstSelectedItemPosition();
957 while(pos
) items
.Add(m_list
.GetNextSelectedItem(pos
));
959 qsort(items
.GetData(), items
.GetCount(), sizeof(UINT
), uintcomp
);
961 for(int i
= 0; i
< items
.GetCount(); i
++)
964 m_sts
.RemoveAt(iItem
);
965 m_subtimes
.RemoveAt(iItem
);
966 m_list
.DeleteItem(iItem
);
969 iItem
= items
[items
.GetCount()-1];
970 if(iItem
>= m_list
.GetItemCount()) iItem
= m_list
.GetItemCount()-1;
972 m_list
.SetSelectionMark(iItem
);
976 case RESETS
: /*if(*/ModStart(iItem
, st
.orgstart
, true);/*)*/ fNeedsUpdate
= true; break;
977 case SETOS
: /*if(*/ModStart(iItem
, st
.orgstart
);/*)*/ fNeedsUpdate
= true; break;
978 case SETCS
: /*if(*/ModStart(iItem
, (int)(m_rt
/10000));/*)*/ fNeedsUpdate
= true; break;
979 case RESETE
: /*if(*/ModEnd(iItem
, st
.orgend
, true);/*)*/ fNeedsUpdate
= true; break;
980 case SETOE
: /*if(*/ModEnd(iItem
, st
.orgend
);/*)*/ fNeedsUpdate
= true; break;
981 case SETCE
: /*if(*/ModEnd(iItem
, (int)(m_rt
/10000));/*)*/ fNeedsUpdate
= true; break;
983 if(STYLEFIRST
<= id
&& id
<= STYLELAST
)
985 CString s
= styles
[id
- STYLEFIRST
];
986 if(m_sts
[iItem
].style
!= s
) fNeedsUpdate
= true;
987 m_sts
[iItem
].style
= s
;
988 m_list
.SetItemText(iItem
, lpnmlv
->iSubItem
, s
);
990 else if(id
== STYLEEDIT
)
992 CAutoPtrArray
<CPPageSubStyle
> pages
;
993 CAtlArray
<STSStyle
*> styles
;
995 STSStyle
* stss
= m_sts
.GetStyle(iItem
);
998 POSITION pos
= m_sts
.m_styles
.GetStartPosition();
999 for(int i
= 0; pos
; i
++)
1003 m_sts
.m_styles
.GetNextAssoc(pos
, key
, val
);
1005 CAutoPtr
<CPPageSubStyle
> page(new CPPageSubStyle());
1006 page
->InitStyle(key
, *val
);
1014 CPropertySheet
dlg(_T("Styles..."), this, iSelPage
);
1015 for(int i
= 0; i
< (int)pages
.GetCount(); i
++) dlg
.AddPage(pages
[i
]);
1017 if(dlg
.DoModal() == IDOK
)
1019 for(int j
= 0; j
< (int)pages
.GetCount(); j
++)
1022 pages
[j
]->GetStyle(*stss
);
1024 for(int i
= 0; i
< m_sts
.GetCount(); i
++)
1026 if(m_sts
.GetStyle(i
) == stss
)
1029 m_list
.SetItemText(i
, COL_TEXT
, m_sts
.GetStr(i
, true));
1030 m_list
.SetItemText(i
, COL_FONT
, stss
->fontName
);
1031 str
.Format(_T("%d"), stss
->charSet
);
1032 m_list
.SetItemText(i
, COL_CHARSET
, str
);
1033 str
.Format(_T("%d"), m_sts
[i
].layer
);
1038 fNeedsUpdate
= true;
1041 else if(id
== UNICODEYES
|| id
== UNICODENO
)
1043 m_sts
.ConvertUnicode(iItem
, id
== UNICODEYES
);
1044 m_list
.SetItemText(iItem
, COL_TEXT
, m_sts
.GetStr(iItem
, true));
1045 m_list
.SetItemText(iItem
, COL_UNICODE
, m_sts
.IsEntryUnicode(iItem
) ? _T("yes") : _T("no"));
1046 fNeedsUpdate
= true;
1048 else if(id
== LAYERDEC
|| id
== LAYERINC
)
1050 int d
= (id
== LAYERDEC
) ? -1 : (id
== LAYERINC
) ? +1 : 0;
1051 if(d
!= 0) fNeedsUpdate
= true;
1052 m_sts
[iItem
].layer
+= d
;
1054 s
.Format(_T("%d"), m_sts
[iItem
].layer
);
1055 m_list
.SetItemText(iItem
, lpnmlv
->iSubItem
, s
);
1057 else if(ACTORFIRST
<= id
&& id
<= ACTORLAST
)
1059 CString s
= actors
[id
- ACTORFIRST
];
1060 if(m_sts
[iItem
].actor
!= s
) fNeedsUpdate
= true;
1061 m_sts
[iItem
].actor
= s
;
1062 m_list
.SetItemText(iItem
, lpnmlv
->iSubItem
, s
);
1064 else if(EFFECTFIRST
<= id
&& id
<= EFFECTLAST
)
1066 CString s
= effects
[id
- EFFECTFIRST
];
1067 if(m_sts
[iItem
].effect
!= s
) fNeedsUpdate
= true;
1068 m_sts
[iItem
].effect
= s
;
1069 m_list
.SetItemText(iItem
, lpnmlv
->iSubItem
, s
);
1084 void CPlayerSubresyncBar::OnNMDblclkList(NMHDR
* pNMHDR
, LRESULT
* pResult
)
1086 LPNMLISTVIEW lpnmlv
= (LPNMLISTVIEW
)pNMHDR
;
1088 if(lpnmlv
->iItem
>= 0 && lpnmlv
->iSubItem
>= 0 && (m_mode
== VOBSUB
|| m_mode
== TEXTSUB
))
1090 if(CMainFrame
* pFrame
= (CMainFrame
*)AfxGetMainWnd())
1093 if(!ParseTime(m_list
.GetItemText(lpnmlv
->iItem
, lpnmlv
->iSubItem
), t
, false))
1094 t
= m_sts
[lpnmlv
->iItem
].start
;
1097 lpnmlv
->iSubItem
== COL_START
? ((REFERENCE_TIME
)t
*10000) :
1098 lpnmlv
->iSubItem
== COL_END
? ((REFERENCE_TIME
)t
*10000) :
1099 lpnmlv
->iSubItem
== COL_PREVSTART
? ((REFERENCE_TIME
)t
*10000) :
1100 lpnmlv
->iSubItem
== COL_PREVEND
? ((REFERENCE_TIME
)t
*10000) :
1101 ((REFERENCE_TIME
)t
*10000);
1110 void CPlayerSubresyncBar::OnLvnKeydownList(NMHDR
* pNMHDR
, LRESULT
* pResult
)
1112 LPNMLVKEYDOWN pLVKeyDown
= reinterpret_cast<LPNMLVKEYDOWN
>(pNMHDR
);
1117 static CUIntArray m_itemGroups
;
1118 static int m_totalGroups
;
1120 void CPlayerSubresyncBar::OnCustomdrawList(NMHDR
* pNMHDR
, LRESULT
* pResult
)
1122 NMLVCUSTOMDRAW
* pLVCD
= reinterpret_cast<NMLVCUSTOMDRAW
*>(pNMHDR
);
1124 *pResult
= CDRF_DODEFAULT
;
1126 if(CDDS_PREPAINT
== pLVCD
->nmcd
.dwDrawStage
)
1128 m_itemGroups
.SetSize(m_list
.GetItemCount());
1130 for(int i
= 0, j
= m_list
.GetItemCount(); i
< j
; i
++)
1132 if(m_list
.GetItemData(i
)&TSEP
) m_totalGroups
++;
1133 m_itemGroups
[i
] = m_totalGroups
;
1136 *pResult
= CDRF_NOTIFYPOSTPAINT
|CDRF_NOTIFYITEMDRAW
;
1138 else if(CDDS_ITEMPREPAINT
== pLVCD
->nmcd
.dwDrawStage
)
1140 pLVCD
->nmcd
.uItemState
&= ~CDIS_FOCUS
;
1142 *pResult
= CDRF_NOTIFYPOSTPAINT
|CDRF_NOTIFYSUBITEMDRAW
;
1144 else if((CDDS_ITEMPREPAINT
|CDDS_SUBITEM
) == pLVCD
->nmcd
.dwDrawStage
)
1149 if((pLVCD
->iSubItem
== COL_START
|| pLVCD
->iSubItem
== COL_END
|| pLVCD
->iSubItem
== COL_TEXT
|| pLVCD
->iSubItem
== COL_STYLE
1150 || pLVCD
->iSubItem
== COL_LAYER
|| pLVCD
->iSubItem
== COL_ACTOR
|| pLVCD
->iSubItem
== COL_EFFECT
)
1151 && m_mode
== TEXTSUB
)
1155 else if((pLVCD
->iSubItem
== COL_START
)
1156 && m_mode
== VOBSUB
)
1165 clrTextBk
= 0xffffff;
1166 // if(m_totalGroups > 0)
1167 clrTextBk
-= ((m_itemGroups
[pLVCD
->nmcd
.dwItemSpec
]&1) ? 0x100010 : 0x200020);
1169 if(m_sts
[pLVCD
->nmcd
.dwItemSpec
].start
<= m_rt
/10000 && m_rt
/10000 < m_sts
[pLVCD
->nmcd
.dwItemSpec
].end
)
1174 int nCheck
= (int)m_list
.GetItemData(pLVCD
->nmcd
.dwItemSpec
);
1176 if((nCheck
&1) && (pLVCD
->iSubItem
== COL_START
|| pLVCD
->iSubItem
== COL_PREVSTART
))
1178 clrTextBk
= 0xffddbb;
1180 else if((nCheck
&4) && (/*pLVCD->iSubItem == COL_START ||*/ pLVCD
->iSubItem
== COL_PREVSTART
))
1182 clrTextBk
= 0xffeedd;
1185 if((nCheck
&2) && (pLVCD
->iSubItem
== COL_END
|| pLVCD
->iSubItem
== COL_PREVEND
))
1187 clrTextBk
= 0xffddbb;
1189 else if((nCheck
&8) && (/*pLVCD->iSubItem == COL_END ||*/ pLVCD
->iSubItem
== COL_PREVEND
))
1191 clrTextBk
= 0xffeedd;
1194 pLVCD
->clrText
= clrText
;
1195 pLVCD
->clrTextBk
= clrTextBk
;
1197 *pResult
= CDRF_NOTIFYPOSTPAINT
;
1199 else if((CDDS_ITEMPOSTPAINT
|CDDS_SUBITEM
) == pLVCD
->nmcd
.dwDrawStage
)
1201 // *pResult = CDRF_DODEFAULT;
1203 else if(CDDS_ITEMPOSTPAINT
== pLVCD
->nmcd
.dwDrawStage
)
1205 int nItem
= static_cast<int>(pLVCD
->nmcd
.dwItemSpec
);
1208 ZeroMemory(&rItem
, sizeof(LVITEM
));
1209 rItem
.mask
= LVIF_IMAGE
| LVIF_STATE
;
1210 rItem
.iItem
= nItem
;
1211 rItem
.stateMask
= LVIS_SELECTED
;
1212 m_list
.GetItem(&rItem
);
1215 CDC
* pDC
= CDC::FromHandle(pLVCD
->nmcd
.hdc
);
1218 m_list
.GetItemRect(nItem
, &rcItem
, LVIR_BOUNDS
);
1221 bool fSeparator
= nItem
< m_list
.GetItemCount()-1 && (m_list
.GetItemData(nItem
+1)&TSEP
);
1222 CPen
p(PS_INSIDEFRAME
, 1, fSeparator
? 0x404040 : 0xe0e0e0);
1223 CPen
* old
= pDC
->SelectObject(&p
);
1224 pDC
->MoveTo(CPoint(rcItem
.left
, rcItem
.bottom
-1));
1225 pDC
->LineTo(CPoint(rcItem
.right
, rcItem
.bottom
-1));
1226 pDC
->SelectObject(old
);
1230 CPen
p(PS_INSIDEFRAME
, 1, 0xe0e0e0);
1231 CPen
* old
= pDC
->SelectObject(&p
);
1233 CHeaderCtrl
* pHeader
= (CHeaderCtrl
*)m_list
.GetDlgItem(0);
1234 int nColumnCount
= pHeader
->GetItemCount();
1236 // Get the column offset
1237 int offset
= rcItem
.left
;
1238 for(int i
= 0; i
< nColumnCount
; i
++)
1240 offset
+= m_list
.GetColumnWidth(i
);
1241 pDC
->MoveTo(CPoint(offset
, rcItem
.top
));
1242 pDC
->LineTo(CPoint(offset
, rcItem
.bottom
));
1245 pDC
->SelectObject(old
);
1248 *pResult
= CDRF_SKIPDEFAULT
;
1251 else if(CDDS_POSTPAINT
== pLVCD
->nmcd
.dwDrawStage
)
1257 bool CPlayerSubresyncBar::IsShortCut(MSG
* pMsg
)
1259 if(pMsg
->message
== WM_KEYDOWN
&& VK_F1
<= pMsg
->wParam
&& pMsg
->wParam
<= VK_F6
)
1263 bool fNeedsUpdate
= false;
1266 POSITION pos
= m_list
.GetFirstSelectedItemPosition();
1269 iItem
= m_list
.GetNextSelectedItem(pos
);
1271 SubTime
& st
= m_subtimes
[iItem
];
1273 switch(pMsg
->wParam
)
1275 case VK_F1
: /*if(*/ModStart(iItem
, st
.orgstart
, true);/*)*/ fNeedsUpdate
= true; break;
1276 case VK_F3
: /*if(*/ModStart(iItem
, st
.orgstart
);/*)*/ fNeedsUpdate
= true; break;
1277 case VK_F5
: /*if(*/ModStart(iItem
, (int)(m_rt
/10000));/*)*/ fNeedsUpdate
= true; break;
1278 case VK_F2
: /*if(*/ModEnd(iItem
, st
.orgend
, true);/*)*/ fNeedsUpdate
= true; break;
1279 case VK_F4
: /*if(*/ModEnd(iItem
, st
.orgend
);/*)*/ fNeedsUpdate
= true; break;
1280 case VK_F6
: /*if(*/ModEnd(iItem
, (int)(m_rt
/10000));/*)*/ fNeedsUpdate
= fStep
= true; break;
1286 if(fStep
&& m_list
.GetSelectedCount() == 1 && iItem
< m_list
.GetItemCount()-1)
1288 m_list
.SetItemState(iItem
, 0, LVIS_SELECTED
);
1289 m_list
.SetItemState(iItem
+1, LVIS_SELECTED
, LVIS_SELECTED
);
1290 m_list
.SetSelectionMark(iItem
+1);
1291 m_list
.EnsureVisible(iItem
+1, false);