ConvertDlg.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 // ConvertDlg.cpp : implementation file
00023 //
00024 
00025 #include "stdafx.h"
00026 #include "mplayerc.h"
00027 #include "..\..\filters\filters.h"
00028 #include "..\..\..\include\matroska\matroska.h"
00029 #include "GraphBuilder.h"
00030 #include "ConvertPropsDlg.h"
00031 #include "ConvertResDlg.h"
00032 #include "ConvertChapDlg.h"
00033 #include "ConvertDlg.h"
00034 
00035 // TODO: subtitle source filter
00036 
00037 // CConvertDlg dialog
00038 
00039 CConvertDlg::CConvertDlg(CWnd* pParent /*=NULL*/)
00040         : CResizableDialog(CConvertDlg::IDD, pParent)
00041         , m_dwRegister(0)
00042         , m_fn(_T(""))
00043 {
00044 }
00045 
00046 CConvertDlg::~CConvertDlg()
00047 {
00048 }
00049 
00050 void CConvertDlg::AddFile(CString fn)
00051 {
00052         CPath path(fn);
00053         path.StripPath();
00054 
00055         CGraphBuilder gb(m_pGB, NULL);
00056 
00057         CComPtr<IBaseFilter> pBF;
00058         if(FAILED(gb.AddSourceFilter(fn, &pBF)))
00059                 return;
00060 
00061         int cnt = 0;
00062         while(S_OK == m_pCGB->RenderStream(NULL, NULL, pBF, NULL, m_pMux)) cnt++;
00063         if(!cnt) {MessageBeep(-1); DeleteFilter(pBF); return;}
00064 
00065         if(m_tree.GetCount() == 0)
00066         {
00067                 if(CComQIPtr<IDSMPropertyBag> pPB = m_pMux)
00068                         pPB->DelAllProperties();
00069 
00070                 if(CString(_T(".dsm")).CompareNoCase(path.GetExtension()) != 0)
00071                 {
00072                         CPath p(fn);
00073                         p.RemoveExtension();
00074                         SetOutputFile(CString((LPCTSTR)p) + _T(".dsm"));
00075                 }
00076         }
00077 
00078         CTreeItemFile* t = new CTreeItemFile(fn, pBF, m_tree, NULL);
00079 
00080         AddFilter(*t, pBF);
00081 
00082         m_tree.Expand(*t, TVE_EXPAND);
00083         m_tree.EnsureVisible(*t);
00084 }
00085 
00086 bool CConvertDlg::SetOutputFile(LPCTSTR fn)
00087 {
00088         if(!m_pGB || !m_pMux)
00089                 return false;
00090 
00091         NukeDownstream(m_pMux, m_pGB);
00092 
00093         CComPtr<IBaseFilter> pFW;
00094         CComQIPtr<IFileSinkFilter2> pFSF = m_pMux;
00095         if(pFSF) {pFW = m_pMux;}
00096         else {pFW.CoCreateInstance(CLSID_FileWriter); pFSF = pFW;}
00097 
00098         if(!pFSF
00099         || FAILED(m_pGB->AddFilter(pFW, NULL))
00100         || FAILED(pFSF->SetFileName(CStringW(fn), NULL))
00101         || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE))
00102         || FAILED(m_pCGB->RenderStream(NULL, NULL, m_pMux, NULL, pFW)))
00103         {
00104                 m_pGB->RemoveFilter(pFW);
00105                 return false;
00106         }
00107 
00108         m_fn = fn;
00109         UpdateData(FALSE);
00110 
00111         return true;
00112 }
00113 
00114 void CConvertDlg::AddFilter(HTREEITEM hTIParent, IBaseFilter* pBFParent)
00115 {
00116         BeginEnumPins(pBFParent, pEP, pPin)
00117         {
00118                 PIN_DIRECTION dir;
00119                 CComPtr<IPin> pPinTo;
00120                 CComPtr<IBaseFilter> pBF;
00121                 if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
00122                 || FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
00123                 || !(pBF = GetFilterFromPin(pPinTo)))
00124                         continue;
00125 
00126                 CTreeItem* t = NULL;
00127 
00128                 if(pBF == m_pMux)
00129                 {
00130                         t = new CTreeItemPin(pPin, m_tree, hTIParent);
00131                 }
00132                 else
00133                 {
00134                         t = new CTreeItemFilter(pBF, m_tree, hTIParent);
00135                         AddFilter(*t, pBF);
00136                 }
00137         }
00138         EndEnumPins
00139 
00140         if(CComQIPtr<IDSMPropertyBag> pPB = pBFParent)
00141         {
00142                 ULONG props;
00143                 if(FAILED(pPB->CountProperties(&props)))
00144                         props = 0;
00145 
00146                 for(ULONG i = 0; i < props; i++)
00147                 {
00148                         PROPBAG2 PropBag;
00149                         memset(&PropBag, 0, sizeof(PropBag));
00150                         ULONG cPropertiesReturned = 0;
00151                         if(FAILED(pPB->GetPropertyInfo(i, 1, &PropBag, &cPropertiesReturned)))
00152                                 continue;
00153 
00154                         HRESULT hr;
00155                         CComVariant var;
00156                         if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
00157                         {
00158                                 CComQIPtr<IDSMPropertyBag> pPBMux = m_pMux;
00159                                 CComBSTR value;
00160                                 if(pPBMux && FAILED(pPBMux->GetProperty(PropBag.pstrName, &value)))
00161                                         pPBMux->SetProperty(PropBag.pstrName, var.bstrVal);
00162                         }
00163 
00164                         CoTaskMemFree(PropBag.pstrName);
00165                 }
00166         }
00167 
00168         CTreeItem* t2 = new CTreeItemResourceFolder(m_tree, hTIParent);
00169         if(CComQIPtr<IDSMResourceBag> pRB = pBFParent)
00170         {
00171                 for(DWORD i = 0, cnt = pRB->ResGetCount(); i < cnt; i++)
00172                 {
00173                         CComBSTR name, mime, desc;
00174                         BYTE* pData = NULL;
00175                         DWORD len = 0;
00176                         if(FAILED(pRB->ResGet(i, &name, &desc, &mime, &pData, &len, NULL)))
00177                                 continue;
00178 
00179                         if(len > 0)
00180                         {
00181                                 m_pTIs.AddTail(new CTreeItemResource(CDSMResource(name, desc, mime, pData, len), m_tree, *t2));
00182                         }
00183 
00184                         CoTaskMemFree(pData);
00185                 }
00186         }
00187         m_tree.Expand(*t2, TVE_EXPAND);
00188 
00189         CTreeItem* t3 = new CTreeItemChapterFolder(m_tree, hTIParent);
00190         if(CComQIPtr<IDSMChapterBag> pCB = pBFParent)
00191         {
00192                 for(DWORD i = 0, cnt = pCB->ChapGetCount(); i < cnt; i++)
00193                 {
00194                         REFERENCE_TIME rt;
00195                         CComBSTR name;
00196                         if(FAILED(pCB->ChapGet(i, &rt, &name)))
00197                                 continue;
00198 
00199                         m_pTIs.AddTail(new CTreeItemChapter(CDSMChapter(rt, name), m_tree, *t3));
00200                 }
00201         }
00202         m_tree.Expand(*t3, TVE_EXPAND);
00203 
00204         m_tree.Expand(hTIParent, TVE_EXPAND);
00205 }
00206 
00207 void CConvertDlg::DeleteFilter(IBaseFilter* pBF)
00208 {
00209         BeginEnumPins(pBF, pEP, pPin)
00210         {
00211                 PIN_DIRECTION dir;
00212                 CComPtr<IPin> pPinTo;
00213                 CComPtr<IBaseFilter> pBF;
00214                 if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_OUTPUT
00215                 || FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
00216                 || !(pBF = GetFilterFromPin(pPinTo)))
00217                         continue;
00218 
00219                 if(pBF != m_pMux) DeleteFilter(pBF);
00220         }
00221         EndEnumPins
00222 
00223         m_pGB->RemoveFilter(pBF);
00224 }
00225 
00226 void CConvertDlg::DeleteItem(HTREEITEM hTI)
00227 {
00228         if(!hTI) return;
00229 
00230         DeleteChildren(hTI);
00231 
00232         CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
00233         if(POSITION pos = m_pTIs.Find(t)) m_pTIs.RemoveAt(pos);
00234         delete t;
00235         m_tree.DeleteItem(hTI);
00236 }
00237 
00238 void CConvertDlg::DeleteChildren(HTREEITEM hTI)
00239 {
00240         if(!hTI) return;
00241 
00242         if(m_tree.ItemHasChildren(hTI))
00243         {
00244                 HTREEITEM hChildItem = m_tree.GetChildItem(hTI);
00245 
00246                 while(hChildItem != NULL)
00247                 {
00248                         HTREEITEM hNextItem = m_tree.GetNextItem(hChildItem, TVGN_NEXT);
00249                         DeleteItem(hChildItem);
00250                         hChildItem = hNextItem;
00251                 }
00252         }
00253 }
00254 
00255 HTREEITEM CConvertDlg::HitTest(CPoint& sp, CPoint& cp)
00256 {
00257         sp = CPoint((LPARAM)GetMessagePos());
00258         cp = sp;
00259         m_tree.ScreenToClient(&cp);
00260         UINT flags = 0;
00261         HTREEITEM hTI = m_tree.HitTest(cp, &flags);
00262         return hTI && (flags&TVHT_ONITEM) ? hTI : NULL;
00263 }
00264 
00265 void CConvertDlg::ShowPopup(CPoint p)
00266 {
00267         CMenu m;
00268         m.CreatePopupMenu();
00269 
00270         int i = 1;
00271         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDFILE));
00272         m.AppendMenu(MF_SEPARATOR);
00273         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_PROPERTIES));
00274 
00275         switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
00276         {
00277         case 1:
00278                 {
00279                         CFileDialog fd(TRUE, NULL, m_fn, 
00280                                 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY, 
00281                                 _T("Media files|*.*||"), this, 0);
00282                         if(fd.DoModal() == IDOK) AddFile(fd.GetPathName());
00283                 }
00284                 break;
00285         case 2:
00286                 EditProperties(CComQIPtr<IDSMPropertyBag>(m_pMux));
00287                 break;
00288         }
00289 }
00290 
00291 void CConvertDlg::ShowFilePopup(HTREEITEM hTI, CPoint p)
00292 {
00293         CTreeItemFile* t = dynamic_cast<CTreeItemFile*>((CTreeItem*)m_tree.GetItemData(hTI));
00294         ASSERT(t);
00295 
00296         CMenu m;
00297         m.CreatePopupMenu();
00298 
00299         int i = 1;
00300         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
00301 
00302         switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
00303         {
00304         case 1:
00305                 DeleteFilter(t->m_pBF);
00306                 DeleteItem(hTI);
00307                 break;
00308         }
00309 }
00310 
00311 void CConvertDlg::ShowPinPopup(HTREEITEM hTI, CPoint p)
00312 {
00313         CTreeItemPin* t = dynamic_cast<CTreeItemPin*>((CTreeItem*)m_tree.GetItemData(hTI));
00314         ASSERT(t);
00315 
00316         if(!t->m_pPin) return;
00317 
00318         CComPtr<IPin> pPinTo;
00319         t->m_pPin->ConnectedTo(&pPinTo);
00320 
00321         CMediaType mtconn;
00322         if(pPinTo) t->m_pPin->ConnectionMediaType(&mtconn);
00323 
00324         CArray<CMediaType> mts;
00325         BeginEnumMediaTypes(t->m_pPin, pEMT, pmt)
00326                 mts.Add(*pmt);
00327         EndEnumMediaTypes(pmt)  
00328 
00329         CMenu m;
00330         m.CreatePopupMenu();
00331 
00332         int i = 1, mtbase = 1000, mti = mtbase;
00333 
00334         m.AppendMenu(MF_STRING, i++, !pPinTo ? ResStr(IDS_CONVERT_ENABLESTREAM) : ResStr(IDS_CONVERT_DISABLESTREAM));
00335 
00336         if(mts.GetCount() > 1)
00337         {
00338                 m.AppendMenu(MF_SEPARATOR);
00339                 for(int i = 0; i < mts.GetCount(); i++)
00340                         m.AppendMenu(MF_STRING | (mts[i] == mtconn ? MF_CHECKED : 0), mti++, CMediaTypeEx(mts[i]).ToString());
00341         }
00342 
00343         m.AppendMenu(MF_SEPARATOR);
00344         m.AppendMenu(MF_STRING | (!pPinTo ? MF_GRAYED : 0), i++, ResStr(IDS_CONVERT_PINPROPERTIES));
00345 
00346         switch(i = (int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
00347         {
00348         case 1:
00349                 if(pPinTo) {m_pGB->Disconnect(pPinTo); m_pGB->Disconnect(t->m_pPin);}
00350                 else if(pPinTo = GetFirstDisconnectedPin(m_pMux, PINDIR_INPUT)) m_pGB->ConnectDirect(t->m_pPin, pPinTo, NULL);
00351                 t->Update();
00352                 break;
00353         case 2:
00354                 EditProperties(CComQIPtr<IDSMPropertyBag>(pPinTo));
00355                 break;
00356         default:
00357                 i -= mtbase;
00358                 if(i >= 0 && i < mts.GetCount())
00359                 {
00360                         if(pPinTo) {m_pGB->Disconnect(pPinTo); m_pGB->Disconnect(t->m_pPin);}
00361                         else {pPinTo = GetFirstDisconnectedPin(m_pMux, PINDIR_INPUT);}
00362                         HRESULT hr = m_pGB->ConnectDirect(t->m_pPin, pPinTo, &mts[i]);
00363                         if(FAILED(hr))
00364                         {
00365                                 AfxMessageBox(_T("Reconnection attempt failed!"));
00366                                 if(mtconn.majortype != GUID_NULL) 
00367                                         hr = m_pGB->ConnectDirect(t->m_pPin, pPinTo, &mtconn);
00368                         }
00369                         t->Update();
00370                 }
00371                 break;
00372         }
00373 }
00374 
00375 void CConvertDlg::ShowResourceFolderPopup(HTREEITEM hTI, CPoint p)
00376 {
00377         CTreeItemResourceFolder* t = dynamic_cast<CTreeItemResourceFolder*>((CTreeItem*)m_tree.GetItemData(hTI));
00378         ASSERT(t);
00379 
00380         CMenu m;
00381         m.CreatePopupMenu();
00382 
00383         int i = 1;
00384         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDRESOURCE));
00385         if(m_tree.ItemHasChildren(*t))
00386         {
00387                 m.AppendMenu(MF_SEPARATOR);
00388                 m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDRESOURCE));
00389         }
00390 
00391         switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
00392         {
00393         case 1:
00394                 {
00395                         CFileDialog fd(TRUE, NULL, NULL, 
00396                                 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY, 
00397                                 _T("All files|*.*||"), this, 0);
00398                         if(fd.DoModal() == IDOK) 
00399                         {
00400                                 CString fn = fd.GetPathName();
00401                                 if(FILE* f = _tfopen(fn, _T("rb")))
00402                                 {
00403                                         CDSMResource res;
00404 
00405                                         CPath path(fn);
00406                                         path.StripPath();
00407                                         res.name = (LPCTSTR)path;
00408                                         
00409                                         CRegKey key;
00410                                         TCHAR mime[256];
00411                                         ULONG len = countof(mime);
00412                                         if(ERROR_SUCCESS == key.Open(HKEY_CLASSES_ROOT, path.GetExtension().MakeLower(), KEY_READ)
00413                                         && ERROR_SUCCESS == key.QueryStringValue(_T("Content Type"), mime, &len))
00414                                                 res.mime = mime;
00415 
00416                                         CTreeItemResource* t = new CTreeItemResource(res, m_tree, hTI);
00417                                         m_pTIs.AddTail(t);
00418 
00419                                         if(EditResource(t))
00420                                         {
00421                                                 fseek(f, 0, 2);
00422                                                 long size = ftell(f);
00423                                                 fseek(f, 0, 0);
00424                                                 t->m_res.data.SetSize(size);
00425                                                 for(BYTE* ptr = t->m_res.data.GetData(),* end = ptr + size; 
00426                                                         size > 0 && end - ptr >= size && fread(ptr, min(size, 1024), 1, f) > 0; 
00427                                                         ptr += 1024, size -= 1024);
00428                                                 fclose(f);
00429                                         }
00430                                         else
00431                                         {
00432                                                 DeleteItem(*t);
00433                                         }
00434                                 }
00435                                 else
00436                                 {
00437                                         AfxMessageBox(_T("Cannot open file!"));
00438                                 }
00439                         }
00440                 }
00441                 break;
00442         case 2:
00443                 DeleteChildren(hTI);
00444                 break;
00445         }
00446 }
00447 
00448 void CConvertDlg::ShowResourcePopup(HTREEITEM hTI, CPoint p)
00449 {
00450         CTreeItemResource* t = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_tree.GetItemData(hTI));
00451         ASSERT(t);
00452 
00453         CMenu m;
00454         m.CreatePopupMenu();
00455 
00456         int i = 1;
00457         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
00458         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_SAVEAS));
00459         if(AfxGetAppSettings().fEnableWebServer) m.AppendMenu(MF_STRING, 1000, ResStr(IDS_CONVERT_LAUNCHINBROWSER));
00460         m.AppendMenu(MF_SEPARATOR);
00461         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_RESOURCEPROPERTIES));
00462 
00463         switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
00464         {
00465         case 1:
00466                 DeleteItem(*t);
00467                 break;
00468         case 2:
00469                 {
00470                         CFileDialog fd(FALSE, NULL, CString(t->m_res.name), 
00471                                 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
00472                                 _T("All files|*.*||"), this, 0);
00473                         if(fd.DoModal() == IDOK)
00474                         {
00475                                 if(FILE* f = _tfopen(fd.GetPathName(), _T("wb")))
00476                                 {
00477                                         fwrite(t->m_res.data.GetData(), 1, t->m_res.data.GetSize(), f);
00478                                         fclose(f);
00479                                 }
00480                         }
00481                 }
00482                 break;
00483         case 3:
00484                 EditResource(t);
00485                 break;
00486         case 1000:
00487                 {
00488                         CString url;
00489                         url.Format(_T("http://localhost:%d/convres.html?id=%x"), AfxGetAppSettings().nWebServerPort, (DWORD)&t->m_res);
00490                         ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOWDEFAULT);
00491                 }
00492                 break;
00493         }
00494 }
00495 
00496 bool CConvertDlg::EditProperties(IDSMPropertyBag* pPB)
00497 {
00498         CConvertPropsDlg dlg(!!CComQIPtr<IPin>(pPB), this);
00499 
00500         ULONG props;
00501         if(FAILED(pPB->CountProperties(&props)))
00502                 props = 0;
00503 
00504         for(ULONG i = 0; i < props; i++)
00505         {
00506                 PROPBAG2 PropBag;
00507                 memset(&PropBag, 0, sizeof(PropBag));
00508                 ULONG cPropertiesReturned = 0;
00509                 if(FAILED(pPB->GetPropertyInfo(i, 1, &PropBag, &cPropertiesReturned)))
00510                         continue;
00511 
00512                 HRESULT hr;
00513                 CComVariant var;
00514                 if(SUCCEEDED(pPB->Read(1, &PropBag, NULL, &var, &hr)) && SUCCEEDED(hr))
00515                         dlg.m_props[CString(PropBag.pstrName)] = CString(var);
00516 
00517                 CoTaskMemFree(PropBag.pstrName);
00518         }
00519 
00520         if(IDOK != dlg.DoModal())
00521                 return false;
00522 
00523         pPB->DelAllProperties();
00524 
00525         POSITION pos = dlg.m_props.GetStartPosition();
00526         while(pos)
00527         {
00528                 CString key, value;
00529                 dlg.m_props.GetNextAssoc(pos, key, value);
00530                 pPB->SetProperty(CStringW(key), CStringW(value));
00531         }
00532 
00533         return true;
00534 }
00535 
00536 bool CConvertDlg::EditResource(CTreeItemResource* t)
00537 {
00538         CConvertResDlg dlg(this);
00539 
00540         dlg.m_name = t->m_res.name;
00541         dlg.m_mime = t->m_res.mime;
00542         dlg.m_desc = t->m_res.desc;
00543 
00544         if(IDOK != dlg.DoModal())
00545                 return false;
00546 
00547         t->m_res.name = dlg.m_name;
00548         t->m_res.mime = dlg.m_mime;
00549         t->m_res.desc = dlg.m_desc;
00550 
00551         t->Update();
00552 
00553         return true;
00554 }
00555 
00556 void CConvertDlg::ShowChapterFolderPopup(HTREEITEM hTI, CPoint p)
00557 {
00558         CTreeItemChapterFolder* t = dynamic_cast<CTreeItemChapterFolder*>((CTreeItem*)m_tree.GetItemData(hTI));
00559         ASSERT(t);
00560 
00561         CMenu m;
00562         m.CreatePopupMenu();
00563 
00564         int i = 1;
00565         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_ADDCHAPTER));
00566         if(m_tree.ItemHasChildren(*t))
00567         {
00568                 m.AppendMenu(MF_SEPARATOR);
00569                 m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVEALL));
00570         }
00571 
00572         switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
00573         {
00574         case 1:
00575                 {
00576                         CDSMChapter chap;
00577                         CTreeItemChapter* t = new CTreeItemChapter(CDSMChapter(0, L""), m_tree, hTI);
00578                         m_pTIs.AddTail(t);
00579                         if(!EditChapter(t)) 
00580                                 DeleteItem(*t);
00581                 }
00582                 break;
00583         case 2:
00584                 DeleteChildren(hTI);
00585                 break;
00586         }
00587 }
00588 
00589 void CConvertDlg::ShowChapterPopup(HTREEITEM hTI, CPoint p)
00590 {
00591         CTreeItemChapter* t = dynamic_cast<CTreeItemChapter*>((CTreeItem*)m_tree.GetItemData(hTI));
00592         ASSERT(t);
00593 
00594         CMenu m;
00595         m.CreatePopupMenu();
00596 
00597         int i = 1;
00598         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_REMOVE));
00599         m.AppendMenu(MF_SEPARATOR);
00600         m.AppendMenu(MF_STRING, i++, ResStr(IDS_CONVERT_CHAPTERPROPERTIES));
00601 
00602         switch((int)m.TrackPopupMenu(TPM_LEFTBUTTON|TPM_RETURNCMD, p.x, p.y, this))
00603         {
00604         case 1:
00605                 DeleteItem(hTI);
00606                 break;
00607         case 2:
00608                 EditChapter(t);
00609                 break;
00610         }
00611 }
00612 
00613 bool CConvertDlg::EditChapter(CTreeItemChapter* t)
00614 {
00615         CConvertChapDlg dlg(this);
00616 
00617         int h = (int)(t->m_chap.rt/10000000/60/60);
00618         int m = (int)(t->m_chap.rt/10000000/60%60);
00619         int s = (int)(t->m_chap.rt/10000000%60);
00620         int ms = (int)(t->m_chap.rt/10000%1000);
00621 
00622         dlg.m_name = t->m_chap.name;
00623         dlg.m_time.Format(_T("%02d:%02d:%02d.%03d"), h, m, s, ms);
00624 
00625         if(IDOK != dlg.DoModal())
00626                 return false;
00627 
00628         TCHAR c;
00629         if(_stscanf(dlg.m_time, _T("%d%c%d%c%d%c%d"), &h, &c, &m, &c, &s, &c, &ms) != 7)
00630                 return false;
00631 
00632         t->m_chap.name = dlg.m_name;
00633         t->m_chap.rt = ((((__int64)h*60+m)*60+s)*1000+ms)*10000;
00634 
00635         t->Update();
00636 
00637         return true;
00638 }
00639 
00640 void CConvertDlg::DoDataExchange(CDataExchange* pDX)
00641 {
00642         __super::DoDataExchange(pDX);
00643         DDX_Control(pDX, IDC_TREE1, m_tree);
00644         DDX_Text(pDX, IDC_EDIT1, m_fn);
00645 }
00646 
00647 BOOL CConvertDlg::PreTranslateMessage(MSG* pMsg)
00648 {
00649         if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
00650                 return TRUE;
00651 
00652         return __super::PreTranslateMessage(pMsg);
00653 }
00654 
00655 BOOL CConvertDlg::OnInitDialog()
00656 {
00657         __super::OnInitDialog();
00658 
00659         SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE);
00660         SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), FALSE);
00661 
00662         AddAnchor(IDC_TREE1, TOP_LEFT, BOTTOM_RIGHT);
00663         AddAnchor(IDC_EDIT1, BOTTOM_LEFT, BOTTOM_RIGHT);
00664         AddAnchor(IDC_BUTTON1, BOTTOM_RIGHT);
00665         AddAnchor(IDC_HLINE, BOTTOM_LEFT, BOTTOM_RIGHT);        
00666         AddAnchor(IDC_BUTTON2, BOTTOM_CENTER);
00667         AddAnchor(IDC_BUTTON3, BOTTOM_CENTER);
00668         AddAnchor(IDC_BUTTON4, BOTTOM_CENTER);
00669 
00670         CSize s(400, 200);
00671         SetMinTrackSize(s);
00672 
00673         m_streamtypesbm.LoadBitmap(IDB_STREAMTYPES);
00674         m_streamtypes.Create(16, 18, ILC_MASK|ILC_COLOR32, 0, 4);
00675         m_streamtypes.Add(&m_streamtypesbm, 0xffffff);
00676         m_tree.SetImageList(&m_streamtypes, TVSIL_NORMAL);
00677 
00678         GetWindowText(m_title);
00679         m_nIDEventStatus = SetTimer(1, 1000, NULL);
00680 
00681         HRESULT hr;
00682         m_pMux = new CDSMMuxerFilter(NULL, &hr, false, false);
00683 
00684         if(FAILED(m_pCGB.CoCreateInstance(CLSID_CaptureGraphBuilder2))
00685         || FAILED(m_pGB.CoCreateInstance(CLSID_FilterGraph))
00686         || FAILED(m_pCGB->SetFiltergraph(m_pGB))
00687         || FAILED(m_pGB->AddFilter(m_pMux, L"Mux"))
00688         || !(m_pMC = m_pGB) || !(m_pME = m_pGB) || !(m_pMS = m_pMux)
00689         || FAILED(m_pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0))) 
00690         {
00691                 MessageBeep(-1);
00692                 SendMessage(WM_CLOSE);
00693                 return TRUE;
00694         }
00695 
00696         AddToRot(m_pGB, &m_dwRegister);
00697 
00698         return TRUE;  // return TRUE unless you set the focus to a control
00699         // EXCEPTION: OCX Property Pages should return FALSE
00700 }
00701 
00702 void CConvertDlg::OnOK()
00703 {
00704 }
00705 
00706 BEGIN_MESSAGE_MAP(CConvertDlg, CResizableDialog)
00707         ON_MESSAGE(WM_GRAPHNOTIFY, OnGraphNotify)
00708         ON_WM_DROPFILES()
00709         ON_WM_CLOSE()
00710         ON_NOTIFY(NM_CLICK, IDC_TREE1, OnNMClickTree1)
00711         ON_NOTIFY(NM_RCLICK, IDC_TREE1, OnNMRclickTree1)
00712         ON_NOTIFY(NM_DBLCLK, IDC_TREE1, OnNMDblclkTree1)
00713         ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
00714         ON_UPDATE_COMMAND_UI(IDC_BUTTON1, OnUpdateButton1)
00715         ON_WM_TIMER()
00716         ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
00717         ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2)
00718         ON_BN_CLICKED(IDC_BUTTON3, OnBnClickedButton3)
00719         ON_UPDATE_COMMAND_UI(IDC_BUTTON3, OnUpdateButton3)
00720         ON_BN_CLICKED(IDC_BUTTON4, OnBnClickedButton4)
00721         ON_UPDATE_COMMAND_UI(IDC_BUTTON4, OnUpdateButton4)
00722 END_MESSAGE_MAP()
00723 
00724 // CConvertDlg message handlers
00725 
00726 LRESULT CConvertDlg::OnGraphNotify(WPARAM wParam, LPARAM lParam)
00727 {
00728     HRESULT hr = S_OK;
00729 
00730         LONG evCode, evParam1, evParam2;
00731     while(m_pME && SUCCEEDED(m_pME->GetEvent(&evCode, (LONG_PTR*)&evParam1, (LONG_PTR*)&evParam2, 0)))
00732     {
00733                 hr = m_pME->FreeEventParams(evCode, evParam1, evParam2);
00734 
00735                 bool fStop = false;
00736 
00737         if(EC_COMPLETE == evCode)
00738         {
00739                         fStop = true;
00740                 }
00741                 else if(EC_ERRORABORT == evCode)
00742                 {
00743                         fStop = true;
00744 
00745                         CString errmsg;
00746                         LPVOID lpMsgBuf;
00747                         if(FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
00748                                 NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL))
00749                         {
00750                                 errmsg = (LPCTSTR)lpMsgBuf;
00751                                 LocalFree(lpMsgBuf);
00752                         }
00753 
00754                         CString str;
00755                         str.Format(_T("Could not complete conversion, the output file is most likely unusable.\n\nError code: 0x%08x"), evParam1);
00756                         if(!errmsg.IsEmpty()) str += _T(" (") + errmsg + _T(")");
00757                         AfxMessageBox(str, MB_OK);
00758                 }
00759 
00760                 if(fStop && m_pMC)
00761                 {
00762                         m_pMC->Stop();
00763                         m_tree.EnableWindow(TRUE);
00764                 }
00765         }
00766 
00767         return hr;
00768 }
00769 
00770 void CConvertDlg::OnDropFiles(HDROP hDropInfo)
00771 {
00772         for(int i = 0, j = DragQueryFile(hDropInfo, 0xffffffff, 0, 0); i < j; i++)
00773         {
00774                 CString fn;
00775                 fn.ReleaseBufferSetLength(DragQueryFile(hDropInfo, i, fn.GetBuffer(MAX_PATH), MAX_PATH));
00776 
00777                 AddFile(fn);
00778         }
00779 
00780         __super::OnDropFiles(hDropInfo);
00781 }
00782 
00783 void CConvertDlg::OnClose()
00784 {
00785         HTREEITEM hTI = m_tree.GetRootItem();
00786         while(hTI)
00787         {
00788                 HTREEITEM hTINext = m_tree.GetNextSiblingItem(hTI);
00789                 DeleteItem(hTI);
00790                 hTI = hTINext;
00791         }
00792 
00793         if(m_dwRegister) RemoveFromRot(m_dwRegister);
00794 
00795         __super::OnClose();
00796 }
00797 
00798 void CConvertDlg::OnNMClickTree1(NMHDR* pNMHDR, LRESULT* pResult)
00799 {
00800         CPoint sp, cp;
00801         HTREEITEM hTI = HitTest(sp, cp);
00802         if(!hTI) return;
00803         m_tree.SelectItem(hTI);
00804 
00805         *pResult = 0;
00806 }
00807 
00808 void CConvertDlg::OnNMRclickTree1(NMHDR* pNMHDR, LRESULT* pResult)
00809 {
00810         CPoint sp, cp;
00811         HTREEITEM hTI = HitTest(sp, cp);
00812 
00813         if(hTI)
00814         {
00815                 m_tree.SelectItem(hTI);
00816 
00817                 CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
00818 
00819                 if(dynamic_cast<CTreeItemPin*>(t))
00820                         ShowPinPopup(hTI, sp);
00821                 else if(dynamic_cast<CTreeItemFile*>(t))
00822                         ShowFilePopup(hTI, sp);
00823                 else if(dynamic_cast<CTreeItemResourceFolder*>(t))
00824                         ShowResourceFolderPopup(hTI, sp);
00825                 else if(dynamic_cast<CTreeItemResource*>(t))
00826                         ShowResourcePopup(hTI, sp);
00827                 else if(dynamic_cast<CTreeItemChapterFolder*>(t))
00828                         ShowChapterFolderPopup(hTI, sp);
00829                 else if(dynamic_cast<CTreeItemChapter*>(t))
00830                         ShowChapterPopup(hTI, sp);
00831         }
00832         else
00833         {
00834                 ShowPopup(sp);
00835         }
00836 
00837         *pResult = 0;
00838 }
00839 
00840 void CConvertDlg::OnNMDblclkTree1(NMHDR *pNMHDR, LRESULT *pResult)
00841 {
00842         CPoint sp, cp;
00843         HTREEITEM hTI = HitTest(sp, cp);
00844 
00845         if(hTI)
00846         {
00847                 CTreeItem* t = (CTreeItem*)m_tree.GetItemData(hTI);
00848 
00849                 if(CTreeItemPin* t2 = dynamic_cast<CTreeItemPin*>(t))
00850                 {
00851                         CComPtr<IPin> pPinTo;
00852                         t2->m_pPin->ConnectedTo(&pPinTo);
00853 
00854                         if(CComQIPtr<IDSMPropertyBag> pPB = pPinTo)
00855                                 EditProperties(pPB);
00856                 }
00857                 else if(CTreeItemResource* t2 = dynamic_cast<CTreeItemResource*>(t))
00858                 {
00859                         EditResource(t2);
00860                 }
00861                 else if(CTreeItemChapter* t2 = dynamic_cast<CTreeItemChapter*>(t))
00862                 {
00863                         EditChapter(t2);
00864                 }
00865         }
00866         
00867         *pResult = 0;
00868 }
00869 
00870 void CConvertDlg::OnBnClickedButton1()
00871 {
00872         UpdateData();
00873 
00874         CFileDialog fd(FALSE, _T(".dsm"), m_fn, 
00875                 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, 
00876                 _T("DirectShow Media file|*.dsm|All files|*.*|"), this, 0);
00877 
00878         if(fd.DoModal() != IDOK) return;
00879 
00880         if(!SetOutputFile(fd.GetPathName()))
00881         {
00882                 AfxMessageBox(_T("Could not set output file"));
00883         }
00884 }
00885 
00886 void CConvertDlg::OnUpdateButton1(CCmdUI* pCmdUI)
00887 {
00888         OAFilterState fs;
00889         pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs == State_Stopped);
00890 }
00891 
00892 void CConvertDlg::OnTimer(UINT nIDEvent)
00893 {
00894         if(nIDEvent == m_nIDEventStatus && m_pMS && m_pMC)
00895         {
00896                 OAFilterState fs;
00897                 if(SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Stopped)
00898                 {
00899                         GUID tf;
00900                         m_pMS->GetTimeFormat(&tf);
00901 
00902                         REFERENCE_TIME rtCur, rtDur;
00903                         HRESULT hr = m_pMS->GetDuration(&rtDur);
00904                         m_pMS->GetCurrentPosition(&rtCur);
00905                         
00906                         CString str;
00907                         if(hr == S_OK) str.Format(_T("%.2f%%"), 1.0 * (rtCur * 100) / rtDur);
00908                         else if(tf == TIME_FORMAT_BYTE) str.Format(_T("%.2fKB"), 1.0 * rtCur / 1024);
00909                         else if(tf == TIME_FORMAT_MEDIA_TIME) str.Format(_T("%02d:%02d:%02d"), int(rtCur/3600000000)%60, int(rtCur/60000000)%60, int(rtCur/1000000)%60);
00910                         else str = _T("Please Wait");
00911                 
00912                         SetWindowText(_T("Converting - ") + str);
00913                 }
00914                 else
00915                 {
00916                         SetWindowText(m_title);
00917                 }
00918         }
00919 
00920         __super::OnTimer(nIDEvent);
00921 }
00922 
00923 void CConvertDlg::OnBnClickedButton2()
00924 {
00925         OAFilterState fs;
00926         if(FAILED(m_pMC->GetState(0, &fs)))
00927                 return;
00928 
00929         if(fs == State_Stopped)
00930         {
00931                 if(m_pMS)
00932                 {
00933                         LONGLONG pos = 0;
00934                         m_pMS->SetPositions(&pos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
00935                 }
00936 
00937                 if(CComQIPtr<IDSMPropertyBag> pPB = m_pMux)
00938                 {
00939                         pPB->SetProperty(L"APPL", L"Media Player Classic");
00940                 }
00941 
00942                 if(CComQIPtr<IDSMResourceBag> pRB = m_pMux)
00943                 {
00944                         pRB->ResRemoveAll(0);
00945                         POSITION pos = m_pTIs.GetHeadPosition();
00946                         while(pos)
00947                         {
00948                                 if(CTreeItemResource* t2 = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_pTIs.GetNext(pos)))
00949                                         pRB->ResAppend(
00950                                                 t2->m_res.name, t2->m_res.desc, t2->m_res.mime, 
00951                                                 t2->m_res.data.GetData(), t2->m_res.data.GetSize(), 
00952                                                 NULL);
00953                         }               
00954                 }
00955 
00956                 if(CComQIPtr<IDSMChapterBag> pCB = m_pMux)
00957                 {
00958                         pCB->ChapRemoveAll();
00959                         POSITION pos = m_pTIs.GetHeadPosition();
00960                         while(pos)
00961                         {
00962                                 if(CTreeItemChapter* t2 = dynamic_cast<CTreeItemChapter*>((CTreeItem*)m_pTIs.GetNext(pos)))
00963                                         pCB->ChapAppend(t2->m_chap.rt, t2->m_chap.name);
00964                         }               
00965                 }
00966         }
00967 
00968         if(m_pMC) 
00969         {
00970                 if(SUCCEEDED(m_pMC->Run()))
00971                         m_tree.EnableWindow(FALSE);
00972         }
00973 }
00974 
00975 void CConvertDlg::OnUpdateButton2(CCmdUI* pCmdUI)
00976 {
00977         int nIn, nOut, nInC, nOutC;
00978         CountPins(m_pMux, nIn, nOut, nInC, nOutC);
00979 
00980         OAFilterState fs;
00981         pCmdUI->Enable(nInC > 0 && nOutC > 0 && GetDlgItem(IDC_EDIT1)->GetWindowTextLength() > 0
00982         && m_pMS && m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Running);
00983 }
00984 
00985 void CConvertDlg::OnBnClickedButton3()
00986 {
00987         if(m_pMC) m_pMC->Pause();
00988 }
00989 
00990 void CConvertDlg::OnUpdateButton3(CCmdUI* pCmdUI)
00991 {
00992         OAFilterState fs;
00993         pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs == State_Running);
00994 }
00995 
00996 void CConvertDlg::OnBnClickedButton4()
00997 {
00998         if(m_pMC) m_pMC->Stop();
00999         m_tree.EnableWindow(TRUE);
01000 }
01001 
01002 void CConvertDlg::OnUpdateButton4(CCmdUI* pCmdUI)
01003 {
01004         OAFilterState fs;
01005         pCmdUI->Enable(m_pMC && SUCCEEDED(m_pMC->GetState(0, &fs)) && fs != State_Stopped);
01006 }
01007 
01008 //
01009 // CFilterTreeCtrl
01010 //
01011 
01012 CFilterTreeCtrl::CFilterTreeCtrl()
01013 {
01014 }
01015 
01016 void CFilterTreeCtrl::PreSubclassWindow()
01017 {
01018         EnableToolTips(TRUE);
01019 
01020         __super::PreSubclassWindow();
01021 }
01022 
01023 INT_PTR CFilterTreeCtrl::OnToolHitTest(CPoint p, TOOLINFO* pTI) const
01024 {
01025         UINT nFlags;
01026         HTREEITEM hTI = HitTest(p, &nFlags);
01027         if(nFlags & TVHT_ONITEM)
01028         {
01029                 CRect r;
01030                 GetItemRect(hTI, r, TRUE);
01031                 pTI->hwnd = m_hWnd;
01032                 pTI->uId = (UINT)hTI;
01033                 pTI->lpszText = LPSTR_TEXTCALLBACK;
01034                 pTI->rect = r;
01035                 return pTI->uId;
01036         }
01037         
01038         return -1;
01039 }
01040 
01041 BEGIN_MESSAGE_MAP(CFilterTreeCtrl, CTreeCtrl)
01042         ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
01043         ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
01044 END_MESSAGE_MAP()
01045 
01046 BOOL CFilterTreeCtrl::OnToolTipText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
01047 {
01048         TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
01049         TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
01050 
01051         UINT nID = pNMHDR->idFrom;
01052 
01053         if(nID == (UINT)m_hWnd
01054         && (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND)
01055         || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND)))
01056                 return FALSE;
01057 
01058         ::SendMessage(pNMHDR->hwndFrom, TTM_SETMAXTIPWIDTH, 0, (LPARAM)(INT)1000);
01059 
01060         HTREEITEM hTI = (HTREEITEM)nID;
01061 
01062         CString str;
01063         static CStringA m_strTipTextA;
01064         static CStringW m_strTipTextW;
01065 
01066         CConvertDlg::CTreeItem* t = (CConvertDlg::CTreeItem*)GetItemData(hTI);
01067         if(!t || !t->ToolTip(str)) return FALSE;
01068 
01069         m_strTipTextA = str;
01070         m_strTipTextW = str;
01071 
01072         if(pNMHDR->code == TTN_NEEDTEXTA) pTTTA->lpszText = (LPSTR)(LPCSTR)m_strTipTextA;
01073         else pTTTW->lpszText = (LPWSTR)(LPCWSTR)m_strTipTextW;
01074 
01075         *pResult = 0;
01076 
01077         return TRUE;    // message was handled
01078 }
01079 
01080 //
01081 // CConvertDlg::CTreeItem*
01082 //
01083 
01084 CConvertDlg::CTreeItem::CTreeItem(CTreeCtrl& tree, HTREEITEM hTIParent) 
01085         : m_tree(tree)
01086 {
01087         m_hTI = m_tree.InsertItem(_T(""), hTIParent);
01088         m_tree.SetItemData(m_hTI, (DWORD_PTR)this);
01089         Update();
01090 }
01091 
01092 CConvertDlg::CTreeItem::~CTreeItem()
01093 {
01094 }
01095 
01096 void CConvertDlg::CTreeItem::SetLabel(LPCTSTR label)
01097 {
01098         m_tree.SetItemText(m_hTI, label);
01099 }
01100 
01101 void CConvertDlg::CTreeItem::SetImage(int nImage, int nSelectedImage)
01102 {
01103         m_tree.SetItemImage(m_hTI, nImage, nSelectedImage);
01104 }
01105 
01106 // 
01107 
01108 CConvertDlg::CTreeItemFilter::CTreeItemFilter(IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent) 
01109         : CTreeItem(tree, hTIParent)
01110         , m_pBF(pBF)
01111 {
01112         Update();
01113 }
01114 
01115 void CConvertDlg::CTreeItemFilter::Update()
01116 {
01117         SetLabel(CString(GetFilterName(m_pBF)));
01118 }
01119 
01120 //
01121 
01122 CConvertDlg::CTreeItemFile::CTreeItemFile(CString fn, IBaseFilter* pBF, CTreeCtrl& tree, HTREEITEM hTIParent)
01123         : CTreeItemFilter(pBF, tree, hTIParent)
01124         , m_fn(fn)
01125 {
01126         Update();
01127 }
01128 
01129 void CConvertDlg::CTreeItemFile::Update()
01130 {
01131         CPath path = m_fn;
01132         path.StripPath();
01133         SetLabel(path);
01134 }
01135 
01136 bool CConvertDlg::CTreeItemFile::ToolTip(CString& str)
01137 {
01138         str = m_fn;
01139         return true;
01140 }
01141 
01142 //
01143 
01144 CConvertDlg::CTreeItemPin::CTreeItemPin(IPin* pPin, CTreeCtrl& tree, HTREEITEM hTIParent)
01145         : CTreeItem(tree, hTIParent)
01146         , m_pPin(pPin)
01147 {
01148         Update();
01149 }
01150 
01151 void CConvertDlg::CTreeItemPin::Update()
01152 {
01153         if(!m_pPin) {ASSERT(0); return;}
01154 
01155         CString label = GetPinName(m_pPin);
01156         if(!IsConnected()) label = _T("[D] ") + label;
01157         SetLabel(label);
01158 
01159         CMediaType mt;
01160         if(S_OK == m_pPin->ConnectionMediaType(&mt))
01161         {
01162                 if(mt.majortype == MEDIATYPE_Video) SetImage(1, 1);
01163                 else if(mt.majortype == MEDIATYPE_Audio) SetImage(2, 2);
01164                 else if(mt.majortype == MEDIATYPE_Text || mt.majortype == MEDIATYPE_Subtitle) SetImage(3, 3);
01165         }
01166 }
01167 
01168 bool CConvertDlg::CTreeItemPin::ToolTip(CString& str)
01169 {
01170         CMediaTypeEx mt;
01171         if(FAILED(m_pPin->ConnectionMediaType(&mt))) return false;
01172         str = mt.ToString(m_pPin);
01173         return true;
01174 }
01175 
01176 bool CConvertDlg::CTreeItemPin::IsConnected()
01177 {
01178         CComPtr<IPin> pPinTo;
01179         return m_pPin && SUCCEEDED(m_pPin->ConnectedTo(&pPinTo)) && pPinTo;
01180 }
01181 
01182 //
01183 
01184 CConvertDlg::CTreeItemResourceFolder::CTreeItemResourceFolder(CTreeCtrl& tree, HTREEITEM hTIParent)
01185         : CTreeItem(tree, hTIParent)
01186 {
01187         Update();
01188 }
01189 
01190 void CConvertDlg::CTreeItemResourceFolder::Update()
01191 {
01192         SetLabel(_T("Resources"));
01193 }
01194 
01195 bool CConvertDlg::CTreeItemResourceFolder::ToolTip(CString& str)
01196 {
01197         if(!m_tree.ItemHasChildren(m_hTI))
01198                 return false;
01199 
01200         int files = 0;
01201         float size = 0;
01202 
01203         HTREEITEM hChildItem = m_tree.GetChildItem(m_hTI);
01204 
01205         while(hChildItem != NULL)
01206         {
01207                 HTREEITEM hNextItem = m_tree.GetNextItem(hChildItem, TVGN_NEXT);
01208                 if(CTreeItemResource* t = dynamic_cast<CTreeItemResource*>((CTreeItem*)m_tree.GetItemData(hChildItem)))
01209                         size += t->m_res.data.GetSize(), files++;
01210                 hChildItem = hNextItem;
01211         }
01212 
01213         size /= 1024;
01214         if(size < 1024) str.Format(_T("%d file(s), %.2f KB"), files, size);
01215         else str.Format(_T("%d file(s), %.2f MB"), files, size/1024);
01216 
01217         return true;
01218 }
01219 
01220 //
01221 
01222 CConvertDlg::CTreeItemResource::CTreeItemResource(const CDSMResource& res, CTreeCtrl& tree, HTREEITEM hTIParent)
01223         : CTreeItem(tree, hTIParent)
01224 {
01225         m_res = res;
01226         Update();
01227 }
01228 
01229 CConvertDlg::CTreeItemResource::~CTreeItemResource()
01230 {
01231 }
01232 
01233 void CConvertDlg::CTreeItemResource::Update()
01234 {
01235         SetLabel(CString(m_res.name));
01236 
01237         CStringW mime = m_res.mime;
01238         mime.Trim();
01239         mime.MakeLower();
01240         if(mime == L"application/x-truetype-font") SetImage(4, 4);
01241         else if(mime.Find(L"text/") == 0) SetImage(5, 5);
01242         else SetImage(6, 6);
01243 }
01244 
01245 bool CConvertDlg::CTreeItemResource::ToolTip(CString& str)
01246 {
01247         if(!m_res.mime.IsEmpty()) str = CString(m_res.mime) + _T("\r\n\r\n");
01248         if(!m_res.desc.IsEmpty()) str += CString(m_res.desc);
01249         str.Trim();
01250         return true;
01251 }
01252 
01253 //
01254 
01255 CConvertDlg::CTreeItemChapterFolder::CTreeItemChapterFolder(CTreeCtrl& tree, HTREEITEM hTIParent)
01256         : CTreeItem(tree, hTIParent)
01257 {
01258         Update();
01259 }
01260 
01261 void CConvertDlg::CTreeItemChapterFolder::Update()
01262 {
01263         SetLabel(_T("Chapters"));
01264 }
01265 
01266 //
01267 
01268 CConvertDlg::CTreeItemChapter::CTreeItemChapter(const CDSMChapter& chap, CTreeCtrl& tree, HTREEITEM hTIParent)
01269         : CTreeItem(tree, hTIParent)
01270 {
01271         m_chap = chap;
01272         Update();
01273 }
01274 
01275 void CConvertDlg::CTreeItemChapter::Update()
01276 {
01277         REFERENCE_TIME rt = m_chap.rt;
01278         rt /= 10000;
01279         int ms = (int)(rt%1000);
01280         rt /= 1000;
01281         int s = (int)(rt%60);
01282         rt /= 60;
01283         int m = (int)(rt%60);
01284         rt /= 60;
01285         int h = (int)(rt);
01286 
01287         CString label;
01288         label.Format(_T("%02d:%02d:%02d.%03d - %s"), h, m, s, ms, CString(m_chap.name));
01289         SetLabel(label);
01290 
01291         SetImage(7, 7);
01292 }

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