PageFirst.cpp 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650
  1. /******************************************************************************
  2. |* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. |* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. |* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. |* PARTICULAR PURPOSE.
  6. |*
  7. |* Copyright 1995-2005 Nero AG. All Rights Reserved.
  8. |*-----------------------------------------------------------------------------
  9. |* NeroSDK / NVAPIExample
  10. |*
  11. |* PROGRAM: PageFirst.cpp
  12. |*
  13. |* PURPOSE: Implementation of the first page.
  14. ******************************************************************************/
  15. #include "stdafx.h"
  16. #include "NVAPIExample.h"
  17. #include "PageFirst.h"
  18. #include "PageData.h"
  19. #include "Sheet.h"
  20. #include "NVAPIExampleDlg.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. // This is our custom message.
  27. //
  28. #define UM_QUIT_WITH_DELAY (WM_APP + 1)
  29. CPageFirst::CPageFirst(CSheet * pParent)
  30. : CPage(CPageFirst::IDD, pParent)
  31. , m_iVideoItemSequence (1)
  32. , m_iSlideshowItemSequence (1)
  33. , m_iVideoStreamSequence (1)
  34. , m_bLoadAndBurn (false)
  35. {
  36. //{{AFX_DATA_INIT(CPageFirst)
  37. m_iProjectType = 0;
  38. m_iEncodingType = 0;
  39. //}}AFX_DATA_INIT
  40. }
  41. void CPageFirst::DoDataExchange(CDataExchange* pDX)
  42. {
  43. CPage::DoDataExchange(pDX);
  44. //{{AFX_DATA_MAP(CPageFirst)
  45. DDX_Control(pDX, IDC_INSERT_AUDIOSTREAM, c_InsertAudioStream);
  46. DDX_Control(pDX, IDC_INSERT_VIDEOSTREAM, c_InsertVideoStream);
  47. DDX_Control(pDX, IDC_ENCODING_TYPE, c_EncodingType);
  48. DDX_Control(pDX, IDC_REMOVEALL, c_RemoveAll);
  49. DDX_Control(pDX, IDC_EXPORT, c_Export);
  50. DDX_Control(pDX, IDC_PREVIEW, c_Preview);
  51. DDX_Control(pDX, IDC_INSERT_AUDIO, c_InsertAudio);
  52. DDX_Control(pDX, IDC_SAVE, c_Save);
  53. DDX_Control(pDX, IDC_REMOVE, c_Remove);
  54. DDX_Control(pDX, IDC_PROJECT_TYPE, c_ProjectType);
  55. DDX_Control(pDX, IDC_LOAD, c_Load);
  56. DDX_Control(pDX, IDC_INSERT_VIDEO, c_InsertVideo);
  57. DDX_Control(pDX, IDC_INSERT_SLIDE, c_InsertSlide);
  58. DDX_Control(pDX, IDC_INSERT_IMAGE, c_InsertImage);
  59. DDX_Control(pDX, IDC_TRANSITION_TYPE, c_TransitionType);
  60. DDX_Control(pDX, IDC_CONTENT, c_Content);
  61. DDX_CBIndex(pDX, IDC_PROJECT_TYPE, m_iProjectType);
  62. DDX_CBIndex(pDX, IDC_ENCODING_TYPE, m_iEncodingType);
  63. //}}AFX_DATA_MAP
  64. }
  65. BEGIN_MESSAGE_MAP(CPageFirst, CPage)
  66. //{{AFX_MSG_MAP(CPageFirst)
  67. ON_BN_CLICKED(IDC_LOAD, OnLoad)
  68. ON_BN_CLICKED(IDC_SAVE, OnSave)
  69. ON_BN_CLICKED(IDC_INSERT_VIDEO, OnInsertVideo)
  70. ON_BN_CLICKED(IDC_REMOVE, OnRemove)
  71. ON_BN_CLICKED(IDC_INSERT_SLIDE, OnInsertSlide)
  72. ON_NOTIFY(TVN_SELCHANGED, IDC_CONTENT, OnSelchangedContent)
  73. ON_CBN_SELCHANGE(IDC_TRANSITION_TYPE, OnSelchangeTransitionType)
  74. ON_BN_CLICKED(IDC_INSERT_IMAGE, OnInsertImage)
  75. ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_CONTENT, OnBeginlabeleditContent)
  76. ON_BN_CLICKED(IDC_INSERT_AUDIO, OnInsertAudio)
  77. ON_BN_CLICKED(IDC_LOAD_AND_BURN, OnLoadAndBurn)
  78. ON_WM_DESTROY()
  79. ON_BN_CLICKED(IDC_PREVIEW, OnPreview)
  80. ON_BN_CLICKED(IDC_EXPORT, OnExport)
  81. ON_BN_CLICKED(IDC_REMOVEALL, OnRemoveall)
  82. ON_BN_CLICKED(IDC_INSERT_VIDEOSTREAM, OnInsertVideoStream)
  83. ON_BN_CLICKED(IDC_INSERT_AUDIOSTREAM, OnInsertAudioStream)
  84. //}}AFX_MSG_MAP
  85. ON_MESSAGE(UM_QUIT_WITH_DELAY, OnQuitWithDelay)
  86. END_MESSAGE_MAP()
  87. BOOL CPageFirst::OnInitDialog()
  88. {
  89. CPage::OnInitDialog();
  90. if (m_ilIcons.Create (16, 16, ILC_COLOR|ILC_MASK, 3, 1))
  91. {
  92. const static UINT uIconIDs[] = {
  93. IDI_IMAGE,
  94. IDI_SOUND,
  95. IDI_VIDEO,
  96. IDI_MAIN,
  97. };
  98. for (int i = 0; i < sizeof (uIconIDs)/sizeof (uIconIDs[0]); i ++)
  99. {
  100. HICON hIcon = (HICON) ::LoadImage (AfxGetInstanceHandle (), MAKEINTRESOURCE (uIconIDs[i]), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
  101. m_ilIcons.Add (hIcon);
  102. DestroyIcon (hIcon);
  103. }
  104. c_Content.SetImageList (&m_ilIcons, TVSIL_NORMAL);
  105. }
  106. // enum transition effects and fillin effect combobox
  107. NeroVisionAPI::IEffectEnumeratorPtr efEnum;
  108. {
  109. if (FAILED(efEnum.CreateInstance(__uuidof(NeroVisionAPI::EffectEnumerator))))
  110. {
  111. MessageBox("IEffectEnumeratorPtr CreateInstance failed");
  112. return TRUE;
  113. }
  114. int index = c_TransitionType.AddString("<none>");
  115. c_TransitionType.SetItemData(index, (DWORD)ST_NONEEFFECT);
  116. for (int i = 0; i < efEnum->GetNumEffects(); i++)
  117. {
  118. BSTR typeID, displayName;
  119. NeroVisionAPI::EffectCategory category;
  120. if (efEnum->GetEffectBaseInfo(i, &typeID, &displayName, &category))
  121. {
  122. if (category == NeroVisionAPI::EffectCategory_Transition)
  123. {
  124. _bstr_t* id = new _bstr_t(typeID, false);
  125. _bstr_t name(displayName, false);
  126. int index = c_TransitionType.AddString(name);
  127. c_TransitionType.SetItemData(index, (DWORD)id);
  128. }
  129. }
  130. }
  131. }
  132. // On the first update, set the proper state of controls.
  133. //
  134. UpdateControls ();
  135. return TRUE; // return TRUE unless you set the focus to a control
  136. // EXCEPTION: OCX Property Pages should return FALSE
  137. }
  138. void CPageFirst::OnDestroy()
  139. {
  140. for (int i = 0; i < c_TransitionType.GetCount(); i++)
  141. {
  142. _bstr_t* id = (_bstr_t*)c_TransitionType.GetItemData(i);
  143. if (id)
  144. {
  145. delete id;
  146. }
  147. }
  148. CPage::OnDestroy();
  149. }
  150. bool CPageFirst::Create (void)
  151. {
  152. // This is a CPage virtual function. Just create the dialog and return
  153. // success.
  154. //
  155. return CDialog::Create (m_lpszTemplateName, m_pParentWnd) != FALSE;
  156. }
  157. bool CPageFirst::OnNext (void)
  158. {
  159. if (m_bLoadAndBurn)
  160. {
  161. return false;
  162. }
  163. else
  164. {
  165. // This method will be called whenever a main window's Next button is
  166. // clicked. We can use it to override the default behavior by returning
  167. // true.
  168. //
  169. IXMLDOMDocumentPtr pDocument = BuildXML ();
  170. if (pDocument != NULL)
  171. {
  172. // If XML was built successfully, set it to the common page
  173. // data and let the default behavior of the button switch
  174. // to the next page.
  175. //
  176. USES_CONVERSION;
  177. GetPageData ()->m_sXML = W2CA (pDocument->xml);
  178. return false;
  179. }
  180. else
  181. {
  182. // If there was an error building XML, report it and don't
  183. // switch to the next page.
  184. //
  185. AfxMessageBox (IDS_ERROR_BUILDING_XML);
  186. return true;
  187. }
  188. }
  189. }
  190. void CPageFirst::OnChangeState (bool bActivate, bool bForward)
  191. {
  192. if (bActivate && bForward)
  193. {
  194. // If we are activated in the forward direction (normally only
  195. // once at the beginning), check if project object was
  196. // successfully created. If not, fail miserably as we can't
  197. // proceed without it. We will actually post a message to ourselves
  198. // to delay the quitting and to allow the main window to be
  199. // displayed.
  200. //
  201. if (GetPageData ()->m_pProject == NULL)
  202. {
  203. PostMessage (UM_QUIT_WITH_DELAY);
  204. }
  205. }
  206. }
  207. LRESULT CPageFirst::OnQuitWithDelay (WPARAM wParam, LPARAM lParam)
  208. {
  209. // This handler will be called if NeroVisionAPI's Project object
  210. // could not have been created. We can't do anything but quit.
  211. //
  212. AfxMessageBox (IDS_ERROR_INITIALIZING_NERO_VISION_API);
  213. PostQuitMessage (0);
  214. return 0;
  215. }
  216. void CPageFirst::OnLoad()
  217. {
  218. // This is a Load handler. Ask for a file to load.
  219. //
  220. CString sFilter;
  221. sFilter.LoadString (IDS_XML_FILES_FILTER);
  222. CFileDialog dlg (TRUE, "xml", NULL,
  223. OFN_EXPLORER|OFN_HIDEREADONLY,
  224. sFilter, this);
  225. if (IDOK == dlg.DoModal ())
  226. {
  227. // If ok was clicked, create an instance of XML document and
  228. // load the document. If loaded successfully, parse the XML file
  229. // and fill the dialog controls accordingly.
  230. //
  231. try
  232. {
  233. try
  234. {
  235. IXMLDOMDocumentPtr pDocument;
  236. // Create object instance... Try MSXML 4.0 first, if not
  237. // then 3.0. Version independent PROGID loads 3.0 even if
  238. // 4.0 is installed. We want 4.0 because it supports schema
  239. // validation.
  240. //
  241. if (FAILED (pDocument.CreateInstance ("Msxml2.DOMDocument.4.0")))
  242. {
  243. EVAL_HR (pDocument.CreateInstance ("Msxml2.DOMDocument.3.0"));
  244. }
  245. // Load the document...
  246. //
  247. VARIANT_BOOL bSuccess;
  248. bSuccess = pDocument->load ((LPCSTR) dlg.GetPathName ());
  249. if (bSuccess)
  250. {
  251. // Parse the document...
  252. //
  253. ParseXMLDocument (pDocument);
  254. }
  255. else
  256. {
  257. IXMLDOMParseErrorPtr pParseError = pDocument->parseError;
  258. CString str, sFormat;
  259. USES_CONVERSION;
  260. VERIFY (sFormat.LoadString (IDS_XML_PARSE_ERROR));
  261. str.Format (sFormat,
  262. pParseError->errorCode, pParseError->line, pParseError->linepos,
  263. W2CA (pParseError->reason), W2CA (pParseError->srcText));
  264. AfxMessageBox (str);
  265. }
  266. }
  267. catch (HRESULT hr)
  268. {
  269. throw _com_error (hr);
  270. }
  271. }
  272. catch (_com_error e)
  273. {
  274. c_Content.DeleteAllItems ();
  275. CString str;
  276. VERIFY (str.LoadString (IDS_ERROR_LOADING_XML));
  277. CString sMessage;
  278. sMessage.Format ("%s (%s)", str, e.ErrorMessage ());
  279. AfxMessageBox (sMessage);
  280. }
  281. catch (...)
  282. {
  283. // If an error occurs, delete everything and display an error.
  284. //
  285. c_Content.DeleteAllItems ();
  286. AfxMessageBox (IDS_ERROR_LOADING_XML);
  287. }
  288. // No matter if the document is loaded successfully or not,
  289. // update the controls to reflect the new state.
  290. //
  291. UpdateControls ();
  292. }
  293. }
  294. void CPageFirst::OnSave()
  295. {
  296. // This is the save XML handler.
  297. //
  298. IXMLDOMDocumentPtr pDocument;
  299. // Build the XML from the project settings.
  300. //
  301. pDocument = BuildXML ();
  302. if (pDocument == NULL)
  303. {
  304. // If ther is an error, notify the user.
  305. //
  306. AfxMessageBox (IDS_ERROR_BUILDING_XML);
  307. }
  308. else
  309. {
  310. // If no error, ask the user for a filename to save the XML to.
  311. //
  312. CString sFilter;
  313. sFilter.LoadString (IDS_XML_FILES_FILTER);
  314. CFileDialog dlg (FALSE, "xml", NULL,
  315. OFN_HIDEREADONLY|OFN_EXPLORER|OFN_OVERWRITEPROMPT,
  316. sFilter, this);
  317. if (IDOK == dlg.DoModal ())
  318. {
  319. // If filename is given, use the document's save method to save
  320. // the XML to a file.
  321. //
  322. try
  323. {
  324. EVAL_HR (pDocument->save ((LPCSTR) dlg.GetPathName ()));
  325. }
  326. catch (...)
  327. {
  328. // Display a message on error.
  329. //
  330. AfxMessageBox (IDS_ERROR_SAVING_XML);
  331. }
  332. }
  333. }
  334. }
  335. void CPageFirst::OnInsertVideo()
  336. {
  337. // This is a handler to insert video to project. Ask for a video
  338. // filename.
  339. //
  340. CString sFilter;
  341. sFilter.LoadString (IDS_VIDEO_FILES_FILTER);
  342. CFileDialog dlg (TRUE, NULL, NULL,
  343. OFN_EXPLORER|OFN_HIDEREADONLY,
  344. sFilter, this);
  345. if (IDOK == dlg.DoModal ())
  346. {
  347. // If video file is selected insert it into project.
  348. //
  349. CString sFormat;
  350. CString sVideoItemName;
  351. sFormat.LoadString (IDS_VIDEO_TITLE_FORMAT);
  352. sVideoItemName.Format (sFormat, m_iVideoItemSequence++);
  353. InsertVideo (sVideoItemName, dlg.GetPathName ());
  354. // After insertion, update the controls.
  355. //
  356. UpdateControls ();
  357. }
  358. }
  359. HTREEITEM CPageFirst::InsertVideo (LPCSTR psVideoItemName, LPCSTR psPath)
  360. {
  361. // This method inserts the video into the project (tree ctrl).
  362. //
  363. HTREEITEM hVideoItem = c_Content.InsertItem (psVideoItemName, 3, 3);
  364. if (hVideoItem != NULL)
  365. {
  366. c_Content.SetItemData (hVideoItem, CONTENTTYPE::VIDEOTITLE);
  367. HTREEITEM hVideoSubItem;
  368. hVideoSubItem = c_Content.InsertItem (psPath, 2, 2, hVideoItem);
  369. if (hVideoSubItem != NULL)
  370. {
  371. c_Content.SetItemData (hVideoSubItem, SUBITEMTYPE::ST_VIDEOPATH);
  372. }
  373. c_Content.Expand (hVideoItem, TVE_EXPAND);
  374. }
  375. return hVideoItem;
  376. }
  377. void CPageFirst::InsertAudio (HTREEITEM hVideoItem, LPCSTR psAudioPath)
  378. {
  379. HTREEITEM hPathName = c_Content.InsertItem (psAudioPath, 1, 1, hVideoItem);
  380. if (hPathName != NULL)
  381. {
  382. c_Content.SetItemData (hPathName, SUBITEMTYPE::ST_AUDIOPATH);
  383. }
  384. }
  385. void CPageFirst::OnRemove()
  386. {
  387. // This is a remove handler. First find the selected tree item.
  388. //
  389. HTREEITEM hSelectedItem = c_Content.GetSelectedItem ();
  390. // If there is one...
  391. //
  392. if (hSelectedItem != NULL)
  393. {
  394. // Find the root item of the selected item.
  395. //
  396. for (HTREEITEM hParentItem = hSelectedItem;
  397. hParentItem != NULL;
  398. hSelectedItem = hParentItem, hParentItem = c_Content.GetParentItem (hSelectedItem))
  399. ;
  400. // Now remove it...
  401. //
  402. c_Content.DeleteItem (hSelectedItem);
  403. UpdateControls ();
  404. }
  405. }
  406. void CPageFirst::OnInsertSlide()
  407. {
  408. // This method inserts an image into the project (tree ctrl) along
  409. // with the two transitions (one before and one after the image).
  410. //
  411. CString sFilter;
  412. sFilter.LoadString (IDS_IMAGE_FILES_FILTER);
  413. CFileDialog dlg (TRUE, NULL, NULL,
  414. OFN_EXPLORER|OFN_HIDEREADONLY,
  415. sFilter, this);
  416. if (IDOK == dlg.DoModal ())
  417. {
  418. CString sFormat;
  419. CString sSlideshowItemName;
  420. sFormat.LoadString (IDS_SLIDE_SHOW_FORMAT);
  421. sSlideshowItemName.Format (sFormat, m_iSlideshowItemSequence++);
  422. HTREEITEM hSlideItem = InsertSlideshow (sSlideshowItemName);
  423. // Insert an "empty" transition before and after the image.
  424. //
  425. InsertTransition (hSlideItem);
  426. InsertImage (hSlideItem, dlg.GetPathName ());
  427. InsertTransition (hSlideItem);
  428. c_Content.Expand (hSlideItem, TVE_EXPAND);
  429. UpdateControls ();
  430. }
  431. }
  432. HTREEITEM CPageFirst::InsertSlideshow (LPCSTR psSlideshowName)
  433. {
  434. // This is a helper method for inserting a slide show image.
  435. //
  436. HTREEITEM hSlideItem = c_Content.InsertItem (psSlideshowName, 3, 3);
  437. c_Content.SetItemData (hSlideItem, CONTENTTYPE::SLIDESHOW);
  438. return hSlideItem;
  439. }
  440. void CPageFirst::InsertTransition (HTREEITEM hSlideItem, const int transitionIndex)
  441. {
  442. // This is a helper method for inserting a transition.
  443. //
  444. // transition also be insert before audio
  445. HTREEITEM childItem = c_Content.GetChildItem(hSlideItem);
  446. if (childItem != NULL)
  447. {
  448. HTREEITEM nextchildItem = c_Content.GetNextSiblingItem(childItem);
  449. while (nextchildItem != NULL)
  450. {
  451. if (c_Content.GetItemData(nextchildItem) == ST_AUDIOSTREAM
  452. || c_Content.GetItemData(nextchildItem) == ST_AUDIOPATH)
  453. {
  454. HTREEITEM hTransition = c_Content.InsertItem ("", 0, 0, hSlideItem, childItem);
  455. ChangeTransition (hTransition, transitionIndex);
  456. break;
  457. }
  458. childItem = nextchildItem;
  459. nextchildItem = c_Content.GetNextSiblingItem(childItem);
  460. }
  461. if (nextchildItem == NULL)
  462. {
  463. HTREEITEM hTransition = c_Content.InsertItem ("", 0, 0, hSlideItem);
  464. ChangeTransition (hTransition, transitionIndex);
  465. }
  466. }
  467. else
  468. {
  469. HTREEITEM hTransition = c_Content.InsertItem ("", 0, 0, hSlideItem);
  470. ChangeTransition (hTransition, transitionIndex);
  471. }
  472. }
  473. void CPageFirst::OnInsertVideoStream()
  474. {
  475. // video stream is created by VideoProvider
  476. // created in pagedata.h
  477. // function in ContentProvider.cpp
  478. CString sVideoStreamName;
  479. sVideoStreamName.Format(IDS_VIDEOSTREAM_FORMAT, m_iVideoStreamSequence++);
  480. CString sVideoStreamContent = "Test counter";
  481. InsertVideoStream (sVideoStreamName, "Test counter");
  482. UpdateControls ();
  483. }
  484. HTREEITEM CPageFirst::InsertVideoStream (LPCSTR psVideoStreamName, LPCSTR psVideoStreamContent)
  485. {
  486. // This method inserts the video into the project (tree ctrl).
  487. //
  488. HTREEITEM hVideoStreamItem = c_Content.InsertItem (psVideoStreamName, 3, 3);
  489. if (hVideoStreamItem != NULL)
  490. {
  491. c_Content.SetItemData (hVideoStreamItem, CONTENTTYPE::VIDEOTITLE);
  492. HTREEITEM hVideoStreamSubItem;
  493. hVideoStreamSubItem = c_Content.InsertItem (psVideoStreamContent, 2, 2, hVideoStreamItem);
  494. if (hVideoStreamSubItem != NULL)
  495. {
  496. c_Content.SetItemData (hVideoStreamSubItem, SUBITEMTYPE::ST_VIDEOSTREAM);
  497. }
  498. c_Content.Expand (hVideoStreamItem, TVE_EXPAND);
  499. }
  500. return hVideoStreamItem;
  501. }
  502. void CPageFirst::OnInsertAudioStream()
  503. {
  504. // audio stream is created by VideoProvider
  505. // created in pagedata.h
  506. // function in ContentProvider.cpp
  507. HTREEITEM hSelectedItem = c_Content.GetSelectedItem ();
  508. if (hSelectedItem != NULL)
  509. {
  510. HTREEITEM hParentItem = c_Content.GetParentItem (hSelectedItem);
  511. if (hParentItem == NULL)
  512. {
  513. hParentItem = hSelectedItem;
  514. }
  515. InsertAudioStream(hParentItem, "Morse Message");
  516. }
  517. UpdateControls ();
  518. }
  519. void CPageFirst::InsertAudioStream (HTREEITEM hVideoItem, LPCSTR psAudioStreamName)
  520. {
  521. HTREEITEM hPathName = c_Content.InsertItem (psAudioStreamName, 1, 1, hVideoItem);
  522. if (hPathName != NULL)
  523. {
  524. c_Content.SetItemData (hPathName, SUBITEMTYPE::ST_AUDIOSTREAM);
  525. }
  526. }
  527. void CPageFirst::InsertImage (HTREEITEM hSlideItem, LPCSTR psImagePath)
  528. {
  529. // This is a helper method for inserting an image after an initial
  530. // image has been inserted into a slideshow with InsertSlideshow.
  531. //
  532. // image has to be insert before audio
  533. HTREEITEM childItem = c_Content.GetChildItem(hSlideItem);
  534. if (childItem != NULL)
  535. {
  536. HTREEITEM nextchildItem = c_Content.GetNextSiblingItem(childItem);
  537. while (nextchildItem != NULL)
  538. {
  539. if (c_Content.GetItemData(nextchildItem) == ST_AUDIOSTREAM
  540. || c_Content.GetItemData(nextchildItem) == ST_AUDIOPATH)
  541. {
  542. c_Content.InsertItem (psImagePath, 0, 0, hSlideItem, childItem);
  543. c_Content.SetItemData (hSlideItem, SUBITEMTYPE::ST_IMAGEPATH);
  544. break;
  545. }
  546. childItem = nextchildItem;
  547. nextchildItem = c_Content.GetNextSiblingItem(childItem);
  548. }
  549. if (nextchildItem == NULL)
  550. {
  551. HTREEITEM hPathName = c_Content.InsertItem (psImagePath, 0, 0, hSlideItem);
  552. c_Content.SetItemData (hPathName, SUBITEMTYPE::ST_IMAGEPATH);
  553. }
  554. }
  555. else
  556. {
  557. HTREEITEM hPathName = c_Content.InsertItem (psImagePath, 0, 0, hSlideItem);
  558. c_Content.SetItemData (hPathName, SUBITEMTYPE::ST_IMAGEPATH);
  559. }
  560. }
  561. void CPageFirst::ChangeTransition (HTREEITEM hItem, const int transitionIndex)
  562. {
  563. // This method is used for changing the transition type in the project.
  564. // First make sure the transition is valid.
  565. //
  566. ASSERT (0 <= transitionIndex && transitionIndex <= c_TransitionType.GetCount());
  567. CString str;
  568. CString sFormat;
  569. CString sTransitionName;
  570. // Get the actual transition name from the combobox. The strings should
  571. // be in the same order as the TRANSITION enums.
  572. //
  573. c_TransitionType.GetLBText (transitionIndex, sTransitionName);
  574. // Get the transition formatting string from the string table and
  575. // create the final string that we are going to set to this item.
  576. //
  577. sFormat.LoadString (IDS_TRANSITION_FORMAT);
  578. str.Format (sFormat, sTransitionName);
  579. c_Content.SetItemText (hItem, str);
  580. c_Content.SetItemData (hItem, transitionIndex);
  581. }
  582. void CPageFirst::OnSelchangedContent(NMHDR* pNMHDR, LRESULT* pResult)
  583. {
  584. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  585. // Every time the selection of tree ctrl changes, update the controls'
  586. // states.
  587. //
  588. UpdateControls ();
  589. *pResult = 0;
  590. }
  591. void CPageFirst::UpdateControls (void)
  592. {
  593. // This method updates the controls' states according to the state
  594. // of the project.
  595. //
  596. HTREEITEM hSelectedItem = c_Content.GetSelectedItem ();
  597. // Save button should be enabled if there is at least one item in
  598. // the project tree ctrl (if there is something worth saving).
  599. // Remove button should be enbled if something is selected.
  600. //
  601. BOOL enable = c_Content.GetFirstVisibleItem () != NULL;
  602. c_Save.EnableWindow (enable);
  603. c_Preview.EnableWindow (enable);
  604. c_RemoveAll.EnableWindow (enable);
  605. c_Remove.EnableWindow (hSelectedItem != NULL);
  606. // we can export only one title at one time
  607. c_Export.EnableWindow (hSelectedItem != NULL);
  608. bool bEnableTransitionType = false;
  609. bool bEnableInsertImage = false;
  610. bool bEnableInsertAudio = false;
  611. HTREEITEM hItemTopLevel = c_Content.GetParentItem (hSelectedItem);
  612. if (hItemTopLevel != NULL)
  613. {
  614. // This is the second level of items. See if the parent is a
  615. // slideshow item.
  616. //
  617. if (c_Content.GetItemData (hItemTopLevel) == CONTENTTYPE::SLIDESHOW)
  618. {
  619. // Yes it is a slideshow. Now check to see if the particular
  620. // item is a transition item.
  621. //
  622. int transition = (SUBITEMTYPE) c_Content.GetItemData (hSelectedItem);
  623. bEnableTransitionType = IsTransition (transition);
  624. if (bEnableTransitionType)
  625. {
  626. // Set the transition of the currently selected item.
  627. //
  628. c_TransitionType.SetCurSel ((int) transition);
  629. }
  630. bEnableInsertImage = true;
  631. }
  632. }
  633. else
  634. {
  635. bEnableInsertImage = hSelectedItem != NULL &&
  636. c_Content.GetItemData (hSelectedItem) == CONTENTTYPE::SLIDESHOW;
  637. hItemTopLevel = hSelectedItem;
  638. }
  639. if (hItemTopLevel != NULL)
  640. {
  641. // Look if an audio item is already present among the child items.
  642. // If not, we will enable the insert button.
  643. //
  644. HTREEITEM hChildItem = c_Content.GetChildItem (hItemTopLevel);
  645. bEnableInsertAudio = true;
  646. while (hChildItem != NULL)
  647. {
  648. DWORD dwAudioType = c_Content.GetItemData (hChildItem);
  649. if (dwAudioType == ST_AUDIOSTREAM || dwAudioType == ST_AUDIOPATH)
  650. {
  651. bEnableInsertAudio = false;
  652. break;
  653. }
  654. hChildItem = c_Content.GetNextSiblingItem (hChildItem);
  655. }
  656. }
  657. // Enable transition type combobox and insert image button according
  658. // to the conditions evaluated previously.
  659. //
  660. c_TransitionType.EnableWindow (bEnableTransitionType);
  661. c_InsertImage.EnableWindow (bEnableInsertImage);
  662. c_InsertAudio.EnableWindow (bEnableInsertAudio);
  663. c_InsertAudioStream.EnableWindow (bEnableInsertAudio);
  664. }
  665. void CPageFirst::OnSelchangeTransitionType()
  666. {
  667. // When selection changes in the transition type combo box, update the
  668. // transition type of the item in the treectrl.
  669. //
  670. HTREEITEM hSelectedItem = c_Content.GetSelectedItem ();
  671. if (hSelectedItem != NULL)
  672. {
  673. HTREEITEM hItemParent = c_Content.GetParentItem (hSelectedItem);
  674. if (hItemParent != NULL)
  675. {
  676. if (c_Content.GetItemData (hItemParent) == CONTENTTYPE::SLIDESHOW)
  677. {
  678. ChangeTransition (hSelectedItem, c_TransitionType.GetCurSel ());
  679. }
  680. }
  681. }
  682. }
  683. void CPageFirst::OnInsertImage()
  684. {
  685. // This method inserts an image into the project (tree ctrl) after an
  686. // initial slideshow has been created with InsertSlideshow.
  687. //
  688. HTREEITEM hSelectedItem = c_Content.GetSelectedItem ();
  689. if (hSelectedItem != NULL)
  690. {
  691. HTREEITEM hParentItem = c_Content.GetParentItem (hSelectedItem);
  692. if (c_Content.GetItemData (hParentItem != NULL? hParentItem: hSelectedItem) == CONTENTTYPE::SLIDESHOW)
  693. {
  694. CString sFilter;
  695. sFilter.LoadString (IDS_IMAGE_FILES_FILTER);
  696. CFileDialog dlg (TRUE, NULL, NULL,
  697. OFN_EXPLORER|OFN_HIDEREADONLY,
  698. sFilter, this);
  699. if (IDOK == dlg.DoModal ())
  700. {
  701. // If an image filename has been chosen, insert it at the
  702. // end of an existing slideshow.
  703. //
  704. HTREEITEM hSlideItem = hParentItem != NULL? hParentItem: hSelectedItem;
  705. InsertImage (hSlideItem, dlg.GetPathName ());
  706. InsertTransition (hSlideItem);
  707. c_Content.Expand (hSlideItem, TVE_EXPAND);
  708. UpdateControls ();
  709. }
  710. }
  711. }
  712. }
  713. _bstr_t CPageFirst::PrettyFormatXML (/*[in]*/ BSTR bstrInputXML)
  714. {
  715. // This method is used for pretty printing the XML file.
  716. //
  717. try
  718. {
  719. ISAXXMLReaderPtr pSAXXReader;
  720. IMXWriterPtr pMXWriter;
  721. EVAL_HR (pSAXXReader.CreateInstance ("MSXML2.SAXXMLReader.3.0"));
  722. EVAL_HR (pMXWriter.CreateInstance ("MSXML2.MXXMLWriter.3.0"));
  723. pMXWriter->indent = VARIANT_TRUE;
  724. pMXWriter->standalone = VARIANT_TRUE;
  725. ISAXContentHandlerPtr pSAXContentHandler (pMXWriter);
  726. EVAL_HR (pSAXXReader->putContentHandler (pSAXContentHandler));
  727. EVAL_HR (pSAXXReader->parse (bstrInputXML));
  728. _variant_t varOutput = pMXWriter->output;
  729. EVAL_HR (varOutput.vt == VT_BSTR? S_OK: E_INVALIDARG);
  730. _bstr_t bstrRet (varOutput.bstrVal);
  731. return bstrRet;
  732. }
  733. catch (...)
  734. {
  735. return "";
  736. }
  737. }
  738. IXMLDOMDocumentPtr CPageFirst::BuildXML (void)
  739. {
  740. // This method is used to build an XML from the project.
  741. //
  742. IXMLDOMDocumentPtr pDocument;
  743. try
  744. {
  745. EVAL_HR (pDocument.CreateInstance ("Msxml2.DOMDocument"));
  746. _bstr_t bstrTarget ("xml");
  747. _bstr_t bstrData ("version='1.0' encoding='ISO-8859-1'");
  748. IXMLDOMProcessingInstructionPtr pPI;
  749. pPI = pDocument->createProcessingInstruction (bstrTarget, bstrData);
  750. pDocument->appendChild (pPI);
  751. IXMLDOMElementPtr pNeroProjectElement;
  752. pNeroProjectElement = pDocument->createElement ("nerovision-project");
  753. pNeroProjectElement->setAttribute ("version", 1L);
  754. pNeroProjectElement->setAttribute ("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
  755. pNeroProjectElement->setAttribute ("xsi:noNamespaceSchemaLocation", _variant_t ("NeroVisionAPI.xsd"));
  756. pDocument->appendChild (pNeroProjectElement);
  757. // Get the project type string directly from the project type
  758. // combobox.
  759. //
  760. int iProjectTypeCurSel = c_ProjectType.GetCurSel ();
  761. ASSERT (iProjectTypeCurSel != -1);
  762. CString sProjectType;
  763. c_ProjectType.GetLBText (iProjectTypeCurSel, sProjectType);
  764. // Insert a project type tag with a fixed PAL encoding.
  765. //
  766. IXMLDOMElementPtr pProjectType;
  767. pProjectType = pDocument->createElement ((LPCSTR) sProjectType);
  768. int iEncodingTypeCurSel = c_EncodingType.GetCurSel();
  769. ASSERT(iEncodingTypeCurSel != -1);
  770. CString sEncodingType;
  771. c_EncodingType.GetLBText (iEncodingTypeCurSel, sEncodingType);
  772. pProjectType->setAttribute ("encoding", (LPCSTR)sEncodingType);
  773. pNeroProjectElement->appendChild (pProjectType);
  774. // Insert a hardcoded label.
  775. //
  776. IXMLDOMElementPtr pLabel;
  777. pLabel = pDocument->createElement ("label");
  778. pLabel->put_text (_bstr_t ("This is a label!"));
  779. pProjectType->appendChild (pLabel);
  780. // Start the content tag...
  781. //
  782. IXMLDOMElementPtr pContent;
  783. pContent = pDocument->createElement ("content");
  784. pProjectType->appendChild (pContent);
  785. int ITitleItemID = 1;
  786. for (HTREEITEM hTitle = c_Content.GetChildItem (NULL);
  787. hTitle != NULL;
  788. hTitle = c_Content.GetNextSiblingItem (hTitle))
  789. {
  790. IXMLDOMElementPtr pTitle;
  791. switch (c_Content.GetItemData (hTitle))
  792. {
  793. case CONTENTTYPE::VIDEOTITLE:
  794. // This is a video. Add videotitle tag with a name attribute
  795. // whose value is the tree item caption.
  796. //
  797. {
  798. pTitle = pDocument->createElement ("videotitle");
  799. pTitle->setAttribute ("name", (LPCSTR) c_Content.GetItemText (hTitle));
  800. CString sID;
  801. sID.Format ("t%d", ITitleItemID++);
  802. pTitle->setAttribute ("id", (LPCSTR) sID);
  803. pContent->appendChild (pTitle);
  804. break;
  805. }
  806. case CONTENTTYPE::SLIDESHOW:
  807. {
  808. // This is a slide show. Add a slideshow tag with a name
  809. // attribute whose value is the tree item caption.
  810. //
  811. pTitle = pDocument->createElement ("slideshow");
  812. pTitle->setAttribute ("name", (LPCSTR) c_Content.GetItemText (hTitle));
  813. CString sID;
  814. sID.Format ("t%d", ITitleItemID++);
  815. pTitle->setAttribute ("id", (LPCSTR) sID);
  816. pContent->appendChild (pTitle);
  817. break;
  818. }
  819. }
  820. // Now, iterate the children and add transitions and images.
  821. //
  822. for (HTREEITEM hChild = c_Content.GetChildItem (hTitle);
  823. hChild != NULL;
  824. hChild = c_Content.GetNextSiblingItem (hChild))
  825. {
  826. SUBITEMTYPE vt = (SUBITEMTYPE) c_Content.GetItemData (hChild);
  827. switch (vt)
  828. {
  829. case SUBITEMTYPE::ST_VIDEOPATH:
  830. {
  831. IXMLDOMElementPtr pVideo;
  832. pVideo = pDocument->createElement ("video");
  833. pVideo->setAttribute ("src", (LPCSTR) c_Content.GetItemText (hChild));
  834. pTitle->appendChild (pVideo);
  835. break;
  836. }
  837. case SUBITEMTYPE::ST_AUDIOPATH:
  838. {
  839. IXMLDOMElementPtr pAudio;
  840. pAudio = pDocument->createElement ("audio");
  841. pAudio->setAttribute ("src", (LPCSTR) c_Content.GetItemText (hChild));
  842. pTitle->appendChild (pAudio);
  843. break;
  844. }
  845. case SUBITEMTYPE::ST_VIDEOSTREAM:
  846. {
  847. // This is a video stream. Add a video stream tag with a name
  848. // attribute whose value is the tree item caption.
  849. IXMLDOMElementPtr pVideoStream;
  850. pVideoStream = pDocument->createElement ("video");
  851. CString videoStreamName;
  852. videoStreamName.Format("content-id:V:%s", c_Content.GetItemText (hChild));
  853. pVideoStream->setAttribute ("src", (LPCSTR) videoStreamName);
  854. pVideoStream->setAttribute ("start", "0");
  855. pVideoStream->setAttribute ("duration", "10");
  856. CString sVideoID;
  857. sVideoID.Format("v%d", ITitleItemID);
  858. pVideoStream->setAttribute ("id", (LPCSTR) sVideoID);
  859. pTitle->appendChild (pVideoStream);
  860. break;
  861. }
  862. case SUBITEMTYPE::ST_AUDIOSTREAM:
  863. {
  864. IXMLDOMElementPtr pAudioStream;
  865. pAudioStream = pDocument->createElement ("audio");
  866. CString sAudioStreamName;
  867. sAudioStreamName.Format("content-id:A:%s", c_Content.GetItemText (hChild));
  868. pAudioStream->setAttribute ("src", (LPCSTR) sAudioStreamName);
  869. pAudioStream->setAttribute ("start", "0");
  870. pAudioStream->setAttribute ("duration", "10");
  871. CString sAudioID;
  872. sAudioID.Format("a%d", ITitleItemID);
  873. pAudioStream->setAttribute ("id", (LPCSTR) sAudioID);
  874. pTitle->appendChild (pAudioStream);
  875. break;
  876. }
  877. case SUBITEMTYPE::ST_IMAGEPATH:
  878. {
  879. // This is an image path.
  880. //
  881. IXMLDOMElementPtr pImage;
  882. pImage = pDocument->createElement ("image");
  883. pImage->setAttribute ("src", (LPCSTR) c_Content.GetItemText (hChild));
  884. pImage->setAttribute ("duration", "5");
  885. pTitle->appendChild (pImage);
  886. break;
  887. }
  888. default:
  889. {
  890. if (IsTransition (vt) && vt != SUBITEMTYPE::ST_NONEEFFECT)
  891. {
  892. _bstr_t* sTransitionName = (_bstr_t*)c_TransitionType.GetItemData(vt);
  893. IXMLDOMElementPtr pTransition;
  894. pTransition = pDocument->createElement ("transition");
  895. pTransition->setAttribute ("type", (LPCSTR) *sTransitionName);
  896. pTitle->appendChild (pTransition);
  897. }
  898. break;
  899. }
  900. }
  901. }
  902. }
  903. IXMLDOMElementPtr pMenu;
  904. pMenu = pDocument->createElement ("menu");
  905. pMenu->setAttribute ("default-thumbnail", "FirstNonEmptyFrame");
  906. pProjectType->appendChild (pMenu);
  907. IXMLDOMElementPtr pDefaultTemplate;
  908. pDefaultTemplate = pDocument->createElement ("default-template");
  909. pDefaultTemplate->setAttribute ("id", "templ1");
  910. pDefaultTemplate->setAttribute ("name", "Island");
  911. pMenu->appendChild (pDefaultTemplate);
  912. IXMLDOMElementPtr pMainMenu;
  913. pMainMenu = pDocument->createElement ("main-menu");
  914. pMenu->appendChild (pMainMenu);
  915. for (int i = 1; i < ITitleItemID; i ++)
  916. {
  917. IXMLDOMElementPtr pChapterMenu;
  918. pChapterMenu = pDocument->createElement ("chapter-menu");
  919. CString sID;
  920. sID.Format ("t%d", i);
  921. pChapterMenu->setAttribute ("title-id", (LPCSTR) sID);
  922. pMenu->appendChild (pChapterMenu);
  923. }
  924. }
  925. catch (...)
  926. {
  927. // If an exception is caught, release the unfinished document.
  928. //
  929. pDocument = NULL;
  930. }
  931. return pDocument;
  932. }
  933. void CPageFirst::OnBeginlabeleditContent(NMHDR* pNMHDR, LRESULT* pResult)
  934. {
  935. TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
  936. // Allow label editing on the first level only! This means editing is
  937. // allowed for video and slideshow item names only. Return TRUE to
  938. // disable editing.
  939. //
  940. *pResult = c_Content.GetParentItem (pTVDispInfo->item.hItem) != NULL;
  941. }
  942. void CPageFirst::ParseXMLDocument (const IXMLDOMDocumentPtr pDocument)
  943. {
  944. // First, clear the treectrl.
  945. //
  946. c_Content.DeleteAllItems ();
  947. // Loop through all the nodes, look for elements.
  948. //
  949. for (IXMLDOMNodePtr pNode = pDocument->firstChild;
  950. pNode != NULL;
  951. pNode = pNode->nextSibling)
  952. {
  953. IXMLDOMElementPtr pElement (pNode);
  954. // If node is an element, the interface pointer will be non-NULL.
  955. //
  956. if (pElement != NULL)
  957. {
  958. // Check to see if the tag name is what we are looking for.
  959. //
  960. if (0 == wcscmp ((BSTR) pElement->tagName, L"nerovision-project"))
  961. {
  962. ParseNeroVisionProject (pElement);
  963. // Once the project tag is parsed, we need parse no more.
  964. //
  965. break;
  966. }
  967. }
  968. }
  969. }
  970. void CPageFirst::ParseNeroVisionProject (const IXMLDOMElementPtr pProject)
  971. {
  972. // Ok, we are now looking for the project type (vcd, svcd or dvd).
  973. //
  974. for (IXMLDOMNodePtr pNode = pProject->firstChild;
  975. pNode != NULL;
  976. pNode = pNode->nextSibling)
  977. {
  978. IXMLDOMElementPtr pElement (pNode);
  979. if (pElement != NULL)
  980. {
  981. USES_CONVERSION;
  982. _bstr_t tagName = pElement->tagName;
  983. LPCSTR psTagName = W2CA (tagName);
  984. // Instead of hardcoding the strings, we will now see if the
  985. // tag name matches any of the strings in the project type
  986. // combobox. We could use CComboBox::FindString but this
  987. // method uses case insensitive search and we need it to be
  988. // case sensitive.
  989. //
  990. for (int i = c_ProjectType.GetCount () - 1; i >= 0; i --)
  991. {
  992. CString sProjectType;
  993. c_ProjectType.GetLBText (i, sProjectType);
  994. if (0 == strcmp (psTagName, sProjectType))
  995. {
  996. c_ProjectType.SetCurSel (i);
  997. break;
  998. }
  999. }
  1000. // Make sure the appropriate project type was found!
  1001. //
  1002. EVAL_HR (i >= 0? S_OK: E_FAIL);
  1003. // match the encoding type string in the combobox
  1004. IXMLDOMAttributePtr pAttribute = pElement->getAttributeNode ("encoding");
  1005. _bstr_t attribute = pAttribute->value;
  1006. LPCSTR sEncodingType = W2CA (attribute);
  1007. for (i = c_EncodingType.GetCount () - 1; i >= 0; i --)
  1008. {
  1009. CString sEncodingType;
  1010. c_EncodingType.GetLBText (i, sEncodingType);
  1011. if (0 == strcmp (attribute, sEncodingType))
  1012. {
  1013. c_EncodingType.SetCurSel (i);
  1014. break;
  1015. }
  1016. }
  1017. // Make sure the appropriate encoding type was found!
  1018. //
  1019. EVAL_HR (i >= 0? S_OK: E_FAIL);
  1020. // If the subproject tag was found, parse its inner tags.
  1021. //
  1022. ParseSubproject (pElement);
  1023. // Then break as only one subproject is supported.
  1024. //
  1025. break;
  1026. }
  1027. }
  1028. }
  1029. void CPageFirst::ParseSubproject (const IXMLDOMElementPtr pSubProject)
  1030. {
  1031. // Now we are looking for the label and content tags. Actually, we
  1032. // don't care about the label as we don't have facility to neither
  1033. // display nor modify it. So, content tag is all we want. We also
  1034. // don't care about the encoding attribute as we don't use it. It is
  1035. // always PAL.
  1036. //
  1037. for (IXMLDOMNodePtr pNode = pSubProject->firstChild;
  1038. pNode != NULL;
  1039. pNode = pNode->nextSibling)
  1040. {
  1041. IXMLDOMElementPtr pElement (pNode);
  1042. if (pElement != NULL)
  1043. {
  1044. if (0 == wcscmp ((BSTR) pElement->tagName, L"content"))
  1045. {
  1046. // Once the content tag is found, parse it, then break as
  1047. // only one content tag is allowed.
  1048. //
  1049. ParseContent (pElement);
  1050. break;
  1051. }
  1052. }
  1053. }
  1054. }
  1055. void CPageFirst::ParseContent (const IXMLDOMElementPtr pContent)
  1056. {
  1057. // Here we want videotitle and slideshow tags. Any number of these
  1058. // can appear in any order.
  1059. //
  1060. for (IXMLDOMNodePtr pNode = pContent->firstChild;
  1061. pNode != NULL;
  1062. pNode = pNode->nextSibling)
  1063. {
  1064. IXMLDOMElementPtr pElement (pNode);
  1065. if (pElement != NULL)
  1066. {
  1067. if (0 == wcscmp ((BSTR) pElement->tagName, L"videotitle"))
  1068. {
  1069. ParseVideotitle (pElement);
  1070. }
  1071. else if (0 == wcscmp ((BSTR) pElement->tagName, L"slideshow"))
  1072. {
  1073. ParseSlideshow (pElement);
  1074. }
  1075. }
  1076. }
  1077. }
  1078. void CPageFirst::ParseVideotitle (const IXMLDOMElementPtr pVideotitle)
  1079. {
  1080. // Videotitle has a mandatory attribute "name". That is what we are
  1081. // after. A sub-tag "video" is also of interest to us.
  1082. //
  1083. IXMLDOMAttributePtr pNameAttr = pVideotitle->attributes->getNamedItem ("name");
  1084. if (pNameAttr != NULL)
  1085. {
  1086. HTREEITEM hVideoItem = NULL;
  1087. // Look for video tag.
  1088. //
  1089. for (IXMLDOMNodePtr pNode = pVideotitle->firstChild;
  1090. pNode != NULL;
  1091. pNode = pNode->nextSibling)
  1092. {
  1093. IXMLDOMElementPtr pElement (pNode);
  1094. if (pElement != NULL)
  1095. {
  1096. if (0 == wcscmp ((BSTR) pElement->tagName, L"video"))
  1097. {
  1098. if (hVideoItem != NULL)
  1099. {
  1100. // There can be only one video tag per videotitle.
  1101. //
  1102. throw E_FAIL;
  1103. }
  1104. // Video tag is found. Take its "src" attribute.
  1105. //
  1106. IXMLDOMAttributePtr pSrcAttr = pElement->attributes->getNamedItem ("src");
  1107. if (pSrcAttr != NULL)
  1108. {
  1109. // Once we have both name and src attributes,
  1110. // insert the video to the project.
  1111. //
  1112. USES_CONVERSION;
  1113. _bstr_t bstrName (pNameAttr->value);
  1114. _bstr_t bstrPath (pSrcAttr->value);
  1115. CString sName = pSrcAttr->value.bstrVal;
  1116. CString matchString = "content-id:V:";
  1117. if (sName.Left(matchString.GetLength()) == matchString)
  1118. {
  1119. sName = sName.Right(sName.GetLength() - matchString.GetLength());
  1120. hVideoItem = InsertVideoStream (W2CA (bstrName), sName);
  1121. }
  1122. else
  1123. {
  1124. hVideoItem = InsertVideo (W2CA (bstrName), W2CA (bstrPath));
  1125. }
  1126. }
  1127. }
  1128. else if (0 == wcscmp ((BSTR) pElement->tagName, L"audio"))
  1129. {
  1130. if (hVideoItem == NULL)
  1131. {
  1132. // There must be a video tag before audio.
  1133. //
  1134. throw E_FAIL;
  1135. }
  1136. // Audio tag is found. Take its "src" attribute.
  1137. //
  1138. IXMLDOMAttributePtr pSrcAttr = pElement->attributes->getNamedItem ("src");
  1139. if (pSrcAttr != NULL)
  1140. {
  1141. // Once we have both name and src attributes,
  1142. // insert the video to the project.
  1143. //
  1144. USES_CONVERSION;
  1145. _bstr_t bstrPath (pSrcAttr->value);
  1146. CString sName = pSrcAttr->value.bstrVal;
  1147. CString matchString = "content-id:A:";
  1148. if (IsAudioStream(sName))
  1149. {
  1150. sName = sName.Right(sName.GetLength() - matchString.GetLength());
  1151. InsertAudioStream (hVideoItem, sName);
  1152. }
  1153. else
  1154. {
  1155. InsertAudio (hVideoItem, W2CA (bstrPath));
  1156. }
  1157. // Nothing more should follow after an audio tag
  1158. // (if any) so we can break here.
  1159. //
  1160. break;
  1161. }
  1162. }
  1163. }
  1164. }
  1165. }
  1166. }
  1167. void CPageFirst::ParseSlideshow (const IXMLDOMElementPtr pSlideshow)
  1168. {
  1169. // Slideshow has a mandatory attribute "name".
  1170. //
  1171. IXMLDOMAttributePtr pNameAttr = pSlideshow->attributes->getNamedItem ("name");
  1172. if (pNameAttr != NULL)
  1173. {
  1174. // If "name" attribute is found, let's insert a slideshow into the/
  1175. // project.
  1176. //
  1177. USES_CONVERSION;
  1178. _bstr_t bstrName = pNameAttr->value;
  1179. HTREEITEM hSlideItem = InsertSlideshow (W2CA (bstrName));
  1180. // Look for transition and image tags.
  1181. //
  1182. for (IXMLDOMNodePtr pNode = pSlideshow->firstChild;
  1183. pNode != NULL;
  1184. pNode = pNode->nextSibling)
  1185. {
  1186. IXMLDOMElementPtr pElement (pNode);
  1187. if (pElement != NULL)
  1188. {
  1189. if (0 == wcscmp ((BSTR) pElement->tagName, L"transition"))
  1190. {
  1191. // A transition tag must have a "type" attribute.
  1192. //
  1193. IXMLDOMAttributePtr pTypeAttr = pElement->attributes->getNamedItem ("type");
  1194. if (pTypeAttr != NULL)
  1195. {
  1196. _bstr_t bstrTransitionType (pTypeAttr->value);
  1197. // Instead of hardcoding the strings, we will now see if the
  1198. // type attribute matches any of the strings in the transition type
  1199. // combobox.
  1200. //
  1201. for (int i = c_TransitionType.GetCount () - 1; i >= 0; i --)
  1202. {
  1203. _bstr_t* sTransitionName = (_bstr_t*)c_TransitionType.GetItemData(i);
  1204. if (0 == strcmp (bstrTransitionType, *sTransitionName))
  1205. {
  1206. // Once the transition type was found in
  1207. // the combobox, insert it into the
  1208. // project.
  1209. //
  1210. InsertTransition (hSlideItem, i);
  1211. break;
  1212. }
  1213. }
  1214. // Make sure the appropriate transition type was
  1215. // found!
  1216. //
  1217. EVAL_HR (i >= 0? S_OK: E_FAIL);
  1218. }
  1219. }
  1220. else if (0 == wcscmp ((BSTR) pElement->tagName, L"image"))
  1221. {
  1222. // When image tag is found, look for its "src"
  1223. // attribute.
  1224. //
  1225. IXMLDOMAttributePtr pSrcAttr = pElement->attributes->getNamedItem ("src");
  1226. if (pSrcAttr != NULL)
  1227. {
  1228. // When found, insert the image into the project.
  1229. //
  1230. _bstr_t bstrImagePath (pSrcAttr->value);
  1231. InsertImage (hSlideItem, W2CA (bstrImagePath));
  1232. }
  1233. }
  1234. else if (0 == wcscmp ((BSTR) pElement->tagName, L"audio"))
  1235. {
  1236. // Audio tag is found. Take its "src" attribute.
  1237. //
  1238. IXMLDOMAttributePtr pSrcAttr = pElement->attributes->getNamedItem ("src");
  1239. if (pSrcAttr != NULL)
  1240. {
  1241. // Once we have both name and src attributes,
  1242. // insert the video to the project.
  1243. //
  1244. USES_CONVERSION;
  1245. _bstr_t bstrPath (pSrcAttr->value);
  1246. CString sName = W2CA(bstrPath);
  1247. CString matchString = "content-id:A:";
  1248. if (IsAudioStream(sName))
  1249. {
  1250. sName = sName.Right(sName.GetLength() - matchString.GetLength());
  1251. InsertAudioStream (hSlideItem, sName);
  1252. }
  1253. else
  1254. InsertAudio (hSlideItem, W2CA (bstrPath));
  1255. // Nothing more should follow after an audio tag
  1256. // (if any) so we can break here.
  1257. //
  1258. break;
  1259. }
  1260. }
  1261. }
  1262. }
  1263. // When all is parsed, expand the tree item.
  1264. //
  1265. c_Content.Expand (hSlideItem, TVE_EXPAND);
  1266. }
  1267. }
  1268. void CPageFirst::OnInsertAudio()
  1269. {
  1270. // This is a handler to insert an audio file to project.
  1271. //
  1272. HTREEITEM hSelectedItem = c_Content.GetSelectedItem ();
  1273. if (hSelectedItem != NULL)
  1274. {
  1275. CString sFilter;
  1276. sFilter.LoadString (IDS_AUDIO_FILES_FILTER);
  1277. CFileDialog dlg (TRUE, NULL, NULL,
  1278. OFN_EXPLORER|OFN_HIDEREADONLY,
  1279. sFilter, this);
  1280. if (IDOK == dlg.DoModal ())
  1281. {
  1282. // Find the root item of the selected item.
  1283. //
  1284. HTREEITEM hParentItem = c_Content.GetParentItem (hSelectedItem);
  1285. if (hParentItem == NULL)
  1286. {
  1287. hParentItem = hSelectedItem;
  1288. }
  1289. InsertAudio (hParentItem, dlg.GetPathName ());
  1290. // After insertion, update the controls.
  1291. //
  1292. UpdateControls ();
  1293. }
  1294. }
  1295. }
  1296. void CPageFirst::OnLoadAndBurn()
  1297. {
  1298. // This is a Load handler. Ask for a file to load.
  1299. //
  1300. CString sFilter;
  1301. sFilter.LoadString (IDS_XML_FILES_FILTER);
  1302. CFileDialog dlg (TRUE, "xml", NULL,
  1303. OFN_EXPLORER|OFN_HIDEREADONLY,
  1304. sFilter, this);
  1305. if (IDOK == dlg.DoModal ())
  1306. {
  1307. // If ok was clicked, create an instance of XML document and
  1308. // load the document. If loaded successfully go directly to
  1309. // burning.
  1310. //
  1311. try
  1312. {
  1313. try
  1314. {
  1315. IXMLDOMDocumentPtr pDocument;
  1316. // Create object instance... Try MSXML 4.0 first, if not
  1317. // then 3.0. Version independent PROGID loads 3.0 even if
  1318. // 4.0 is installed. We want 4.0 because it supports schema
  1319. // validation.
  1320. //
  1321. if (FAILED (pDocument.CreateInstance ("Msxml2.DOMDocument.4.0")))
  1322. {
  1323. EVAL_HR (pDocument.CreateInstance ("Msxml2.DOMDocument.3.0"));
  1324. }
  1325. // Load the document...
  1326. //
  1327. VARIANT_BOOL bSuccess;
  1328. bSuccess = pDocument->load ((LPCSTR) dlg.GetPathName ());
  1329. if (bSuccess)
  1330. {
  1331. USES_CONVERSION;
  1332. GetPageData ()->m_sXML = W2CA (pDocument->xml);
  1333. m_bLoadAndBurn = true;
  1334. GetParent ()->SendMessage (WM_COMMAND, IDOK);
  1335. m_bLoadAndBurn = false;
  1336. }
  1337. else
  1338. {
  1339. IXMLDOMParseErrorPtr pParseError = pDocument->parseError;
  1340. CString str, sFormat;
  1341. USES_CONVERSION;
  1342. VERIFY (sFormat.LoadString (IDS_XML_PARSE_ERROR));
  1343. str.Format (sFormat,
  1344. pParseError->errorCode, pParseError->line, pParseError->linepos,
  1345. W2CA (pParseError->reason), W2CA (pParseError->srcText));
  1346. AfxMessageBox (str);
  1347. }
  1348. }
  1349. catch (HRESULT hr)
  1350. {
  1351. throw _com_error (hr);
  1352. }
  1353. }
  1354. catch (_com_error e)
  1355. {
  1356. CString str;
  1357. VERIFY (str.LoadString (IDS_ERROR_LOADING_XML));
  1358. CString sMessage;
  1359. sMessage.Format ("%s (%s)", str, e.ErrorMessage ());
  1360. AfxMessageBox (sMessage);
  1361. }
  1362. catch (...)
  1363. {
  1364. // If an error occurs, delete everything and display an error.
  1365. //
  1366. AfxMessageBox (IDS_ERROR_LOADING_XML);
  1367. }
  1368. }
  1369. }
  1370. void CPageFirst::OnPreview()
  1371. {
  1372. // build XML before preview, so any change user made will be show on preview page
  1373. IXMLDOMDocumentPtr pDocument = BuildXML ();
  1374. USES_CONVERSION;
  1375. GetPageData ()->m_sXML = W2CA (pDocument->xml);
  1376. // go to preview page
  1377. CNVAPIExampleDlg * pParentSheet = (CNVAPIExampleDlg *) GetParent();
  1378. if (pParentSheet)
  1379. pParentSheet->SwitchPage(3);
  1380. }
  1381. void CPageFirst::OnExport()
  1382. {
  1383. // make sure one title is selected for export
  1384. HTREEITEM hSelectedItem = c_Content.GetSelectedItem ();
  1385. if (hSelectedItem != NULL) // Find the root item of the selected item.
  1386. {
  1387. for (HTREEITEM hParentItem = hSelectedItem; hParentItem != NULL;
  1388. hSelectedItem = hParentItem, hParentItem = c_Content.GetParentItem (hSelectedItem));
  1389. int index = 0;
  1390. for (HTREEITEM hChild = c_Content.GetChildItem (NULL) ; hChild != NULL;
  1391. hChild = c_Content.GetNextSiblingItem (hChild), ++index)
  1392. {
  1393. if (hSelectedItem == hChild) {
  1394. GetPageData ()->m_selectedItemIndex = index;
  1395. break;
  1396. }
  1397. }
  1398. // build XML before export
  1399. IXMLDOMDocumentPtr pDocument = BuildXML ();
  1400. USES_CONVERSION;
  1401. GetPageData ()->m_sXML = W2CA (pDocument->xml);
  1402. // go to export page
  1403. CNVAPIExampleDlg * pParentSheet = (CNVAPIExampleDlg *) GetParent();
  1404. if (pParentSheet)
  1405. pParentSheet->SwitchPage(4);
  1406. }
  1407. }
  1408. void CPageFirst::OnRemoveall()
  1409. {
  1410. // for fast restart a project
  1411. c_Content.DeleteAllItems ();
  1412. UpdateControls ();
  1413. }
  1414. bool CPageFirst::IsAudioStream(LPCSTR psAudioPath)
  1415. {
  1416. CString sName = psAudioPath;
  1417. CString matchString = "content-id:A:";
  1418. return (sName.Left(matchString.GetLength()) == matchString);
  1419. }
  1420. bool IsVideoStream(LPCSTR psVideoPath)
  1421. {
  1422. bool bResult = false;
  1423. return bResult;
  1424. }