- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }