WMCDRecorder.Mod 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258
  1. MODULE WMCDRecorder;
  2. IMPORT
  3. WMWindowManager, WMComponents, WMStandardComponents, WMGrids, WMStringGrids, WMMessages, WMDialogs,
  4. WMEvents, Objects, Kernel, WMProperties, WMGraphics, WMEditors, WMTrees, WMRectangles, WMPopups, WMDropTarget,
  5. Modules, Disks, XMLObjects, Files, Strings, CDRecord, Lib := CDRecordLib, MakeIsoImages, Utils := CDRecordUtils;
  6. CONST
  7. Title = "CD Recording Tool";
  8. White = 0FFFFFFFFH;
  9. Black = 0000000FFH;
  10. LightGray = 0C8C8C8FFH;
  11. DarkGray = 0A0A0A0FFH;
  12. Blue = 00000FFFFH;
  13. MaxLen = 256;
  14. ResOk=0; ResErr=1;
  15. DefaultImageLocation = "AOS:Image.Iso";
  16. DefaultWaveLocation = "AOS:"; (* temporary location for converted mp3 files *)
  17. BBMinISOSize = 512; (* the minimum size in sectors of an iso image to be mountable in Bluebottle *)
  18. BBMultisessionCapable = FALSE; (* no multisession support in bluebottle *)
  19. (* Data Session *)
  20. NoMultisession = 0;
  21. StartMultisession = 1;
  22. ContinueMultisession = 2;
  23. FinishMultisession = 3;
  24. BootSession = 4;
  25. (* Tools *)
  26. OpenIsoTool = 0;
  27. CopyIsoTool = 1;
  28. BlankTool = 2;
  29. DiscInfo = 3;
  30. TYPE
  31. KillerMsg = OBJECT END KillerMsg;
  32. Directory = MakeIsoImages.Directory;
  33. Window* = OBJECT (WMComponents.FormWindow)
  34. VAR
  35. workPanel, mainPanel, toolPanel, filePanel,leftPanel, statusBar: WMStandardComponents.Panel;
  36. projectPanel: ProjectPanel;
  37. audioBtn, dataBtn, burnBtn, toolBtn, refreshBtn: WMStandardComponents.Button;
  38. explorer: Utils.ExplorerPanel;
  39. sizeLabel: WMStandardComponents.Label;
  40. overheadLabel: WMStandardComponents.Label;
  41. burnPanel: BurnPanel;
  42. onStatusChanged : WMEvents.EventSource;
  43. PROCEDURE &New*;
  44. VAR
  45. vc: WMComponents.VisualComponent;
  46. BEGIN
  47. IncCount();
  48. vc := CreateForm();
  49. Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE);
  50. SetContent(vc);
  51. SetTitle(Strings.NewString(Title));
  52. SetIcon(WMGraphics.LoadImage("WMIcons.tar://WMCDRecorder.png", TRUE));
  53. WMWindowManager.DefaultAddWindow(SELF);
  54. NEW(onStatusChanged, SELF, NIL, NIL, NIL);
  55. onStatusChanged.Add(StatusChanged);
  56. END New;
  57. PROCEDURE ShowBurnPanel;
  58. BEGIN
  59. workPanel.visible.Set(FALSE);
  60. burnPanel.visible.Set(TRUE);
  61. burnPanel.ResetAll();
  62. EnableWindow(FALSE);
  63. END ShowBurnPanel;
  64. PROCEDURE ShowWorkPanel;
  65. BEGIN
  66. burnPanel.visible.Set(FALSE);
  67. workPanel.visible.Set(TRUE);
  68. EnableWindow(TRUE);
  69. END ShowWorkPanel;
  70. PROCEDURE CreateForm(): WMComponents.VisualComponent;
  71. VAR
  72. resizer: WMStandardComponents.Resizer;
  73. label: WMStandardComponents.Label;
  74. BEGIN
  75. NEW(mainPanel);
  76. mainPanel.bounds.SetExtents(600, 400);
  77. mainPanel.fillColor.Set(White);
  78. NEW(toolPanel);
  79. toolPanel.bounds.SetHeight(20);
  80. toolPanel.fillColor.Set(LightGray);
  81. toolPanel.alignment.Set(WMComponents.AlignTop);
  82. mainPanel.AddContent(toolPanel);
  83. NEW(statusBar);
  84. statusBar.bounds.SetHeight(20);
  85. statusBar.fillColor.Set(LightGray);
  86. statusBar.alignment.Set(WMComponents.AlignBottom);
  87. mainPanel.AddContent(statusBar);
  88. NEW(label);
  89. label.bounds.SetWidth(40);
  90. label.alignment.Set(WMComponents.AlignLeft);
  91. label.caption.SetAOC("Size:");
  92. label.textColor.Set(Black);
  93. statusBar.AddContent(label);
  94. NEW(sizeLabel);
  95. sizeLabel.bounds.SetWidth(200);
  96. sizeLabel.alignment.Set(WMComponents.AlignLeft);
  97. sizeLabel.textColor.Set(Black);
  98. statusBar.AddContent(sizeLabel);
  99. NEW(audioBtn);
  100. audioBtn.bounds.SetWidth(100);
  101. audioBtn.alignment.Set(WMComponents.AlignLeft);
  102. audioBtn.caption.SetAOC("Audio Project");
  103. audioBtn.onClick.Add(ProjectHandler);
  104. toolPanel.AddContent(audioBtn);
  105. NEW(dataBtn);
  106. dataBtn.bounds.SetWidth(100);
  107. dataBtn.alignment.Set(WMComponents.AlignLeft);
  108. dataBtn.caption.SetAOC("Data Project");
  109. dataBtn.onClick.Add(ProjectHandler);
  110. toolPanel.AddContent(dataBtn);
  111. NEW(burnBtn);
  112. burnBtn.bounds.SetWidth(100);
  113. burnBtn.alignment.Set(WMComponents.AlignLeft);
  114. burnBtn.caption.SetAOC("Burn");
  115. burnBtn.onClick.Add(BurnHandler);
  116. toolPanel.AddContent(burnBtn);
  117. NEW(refreshBtn);
  118. refreshBtn.bounds.SetWidth(100);
  119. refreshBtn.alignment.Set(WMComponents.AlignRight);
  120. refreshBtn.caption.SetAOC("Refresh FS");
  121. refreshBtn.onClick.Add(RefreshHandler);
  122. toolPanel.AddContent(refreshBtn);
  123. NEW(toolBtn);
  124. toolBtn.bounds.SetWidth(100);
  125. toolBtn.alignment.Set(WMComponents.AlignRight);
  126. toolBtn.caption.SetAOC("Tools");
  127. toolBtn.onClick.Add(ToolHandler);
  128. toolPanel.AddContent(toolBtn);
  129. NEW(resizer);
  130. resizer.alignment.Set(WMComponents.AlignLeft);
  131. resizer.bounds.SetWidth(8);
  132. NEW(workPanel);
  133. workPanel.alignment.Set(WMComponents.AlignClient);
  134. mainPanel.AddContent(workPanel);
  135. NEW(burnPanel);
  136. burnPanel.alignment.Set(WMComponents.AlignClient);
  137. burnPanel.fillColor.Set(DarkGray);
  138. burnPanel.visible.Set(FALSE);
  139. mainPanel.AddContent(burnPanel);
  140. NEW(filePanel);
  141. filePanel.alignment.Set(WMComponents.AlignRight);
  142. filePanel.bounds.SetWidth(300);
  143. workPanel.AddContent(filePanel);
  144. NEW(resizer);
  145. resizer.alignment.Set(WMComponents.AlignLeft);
  146. resizer.bounds.SetWidth(4);
  147. filePanel.AddContent(resizer);
  148. NEW(explorer);
  149. explorer.alignment.Set(WMComponents.AlignClient);
  150. explorer.fillColor.Set(White);
  151. filePanel.AddContent(explorer);
  152. NEW(leftPanel);
  153. leftPanel.alignment.Set(WMComponents.AlignClient);
  154. leftPanel.fillColor.Set(White);
  155. workPanel.AddContent(leftPanel);
  156. RETURN mainPanel;
  157. END CreateForm;
  158. PROCEDURE EnableWindow(enable: BOOLEAN);
  159. BEGIN
  160. EnableComponents(toolPanel, enable);
  161. END EnableWindow;
  162. PROCEDURE EnableComponents(component: WMComponents.Component; enable: BOOLEAN);
  163. VAR
  164. enum: XMLObjects.Enumerator;
  165. p: ANY;
  166. BEGIN
  167. enum := component.GetContents();
  168. WHILE enum.HasMoreElements() DO
  169. p := enum.GetNext();
  170. IF p IS WMComponents.Component THEN
  171. EnableComponents(p(WMComponents.Component), enable);
  172. p(WMComponents.Component).enabled.Set(enable);
  173. END;
  174. END;
  175. END EnableComponents;
  176. PROCEDURE Resized(width, height: LONGINT);
  177. VAR
  178. oldWidth: LONGINT;
  179. factor: REAL;
  180. BEGIN
  181. oldWidth := leftPanel.bounds.GetWidth() + filePanel.bounds.GetWidth();
  182. factor := width / oldWidth;
  183. filePanel.bounds.SetWidth(ENTIER(factor * filePanel.bounds.GetWidth()));
  184. Resized^(width, height);
  185. END Resized;
  186. PROCEDURE UpdateSize(size, overhead: LONGINT);
  187. VAR
  188. text, tmp: ARRAY 16 OF CHAR;
  189. total: LONGINT;
  190. BEGIN
  191. total := (size + 1024 - 1) DIV 1024;
  192. Strings.IntToStr(total, text);
  193. IF overhead > 0 THEN
  194. Strings.Append(text, " (");
  195. overhead := (overhead + 1024 + 1) DIV 1024;
  196. Strings.IntToStr(overhead , tmp);
  197. Strings.Append(text, tmp);
  198. Strings.Append(text, ")");
  199. END;
  200. Strings.Append(text, " KB");
  201. sizeLabel.caption.SetAOC(text);
  202. END UpdateSize;
  203. PROCEDURE IdentifyRecorders(): WORD;
  204. VAR
  205. res: WORD;
  206. dlg: WaitDialog;
  207. ticks : LONGINT;
  208. BEGIN
  209. NEW(dlg, Strings.NewString("Waiting"), bounds, 200, 100, TRUE);
  210. dlg.SetText("Identifying recorders");
  211. dlg.ShowNonModal;
  212. ticks := Kernel.GetTicks ();
  213. res := CDRecord.IdentifyRecorders(recorders);
  214. WHILE (res # ResOk) & (dlg.result # WMDialogs.ResAbort) & (Kernel.GetTicks () < ticks + 8000) DO
  215. Objects.Yield();
  216. res := CDRecord.IdentifyRecorders(recorders);
  217. END;
  218. IF (dlg # NIL) & (dlg.result # WMDialogs.ResAbort) THEN
  219. dlg.Close();
  220. END;
  221. IF recorders[0] = NIL THEN res := ResErr END;
  222. IF res # ResOk THEN
  223. WMDialogs.Error("", "No recorder found");
  224. END;
  225. RETURN res;
  226. END IdentifyRecorders;
  227. PROCEDURE ToolHandler(sender, data: ANY);
  228. VAR
  229. dlg: ToolDialog;
  230. handler: Handler;
  231. BEGIN
  232. NEW(dlg, Strings.NewString("Tools"), bounds, 300, 200);
  233. dlg.Show();
  234. IF dlg.result = WMDialogs.ResOk THEN
  235. CASE dlg.tool OF
  236. OpenIsoTool: NEW(handler, OpenHandler, data);
  237. | CopyIsoTool: NEW(handler, CopyHandler, data);
  238. | BlankTool: NEW(handler, BlankHandler, data);
  239. | DiscInfo: InfoHandler(SELF, NIL);
  240. END;
  241. END;
  242. END ToolHandler;
  243. PROCEDURE InfoHandler(sender, data: ANY);
  244. VAR
  245. recDlg: RecorderDialog;
  246. infoDlg: InfoDialog;
  247. recorder: CDRecord.CDRecorder;
  248. disc: CDRecord.Disc; discEx: CDRecord.DiscEx;
  249. BEGIN
  250. IF IdentifyRecorders() # ResOk THEN RETURN END;
  251. NEW(recDlg, Strings.NewString("Blank"), bounds, 300, 200);
  252. recDlg.Show();
  253. IF recDlg.result # ResOk THEN RETURN END;
  254. recorder := recDlg.recorder;
  255. IF WaitOnDisc(recorder) # ResOk THEN RETURN END;
  256. NEW(disc); NEW(discEx);
  257. IF recorder.GetDiscInfo(disc) # ResOk THEN
  258. WMDialogs.Error(Title, "Could not read disc information");
  259. RETURN;
  260. ELSIF recorder.GetDiscInfoEx(discEx) = ResOk THEN
  261. disc := discEx;
  262. END;
  263. NEW(infoDlg, Strings.NewString("Blank"), bounds, 300, 200, disc);
  264. infoDlg.Show();
  265. END InfoHandler;
  266. PROCEDURE CopyHandler(sender, data: ANY);
  267. VAR
  268. copyDlg: CopyDialog;
  269. waitDlg: WaitDialog;
  270. recorder: CDRecord.CDRecorder;
  271. disc: CDRecord.Disc;
  272. compilation: CDRecord.Compilation;
  273. res, tmp: WORD; startsec, size, freeSpace: LONGINT;
  274. toc: Lib.TocDescriptor;
  275. dest: String;
  276. pvd: MakeIsoImages.PSVolumeDescriptor;
  277. readOnly: BOOLEAN;
  278. msg: ARRAY MaxLen OF CHAR;
  279. BEGIN
  280. IF IdentifyRecorders() # ResOk THEN RETURN END;
  281. NEW(copyDlg, Strings.NewString("Copy"), bounds, 300, 400);
  282. copyDlg.Show();
  283. IF copyDlg.result # WMDialogs.ResOk THEN RETURN END;
  284. dest := copyDlg.sourcePage.location.Get();
  285. RemoveSpecialChars(dest^);
  286. recorder := copyDlg.sourcePage.recorder;
  287. IF WaitOnDisc(recorder) # ResOk THEN RETURN END;
  288. NEW(disc);
  289. IF recorder.GetDiscInfo(disc) # ResOk THEN
  290. WMDialogs.Error(Title, "Could not read disc information");
  291. RETURN;
  292. END;
  293. IF disc.status # Lib.DSComplete THEN
  294. WMDialogs.Error(Title, "Only finalized discs can be copied");
  295. RETURN;
  296. ELSIF disc.nofSessions # 1 THEN
  297. WMDialogs.Error(Title, "Only single session discs can be copied");
  298. RETURN;
  299. END;
  300. (* check if disc contains digital data *)
  301. IF Lib.GetTrackDescriptor(recorder.dev, 1, toc) # ResOk THEN
  302. WMDialogs.Error(Title, "Cannot read toc");
  303. RETURN;
  304. END;
  305. IF ~Lib.CheckBit(CHR(Lib.GetField(toc.Byte1, Lib.TCControlMask, Lib.TCControlOfs)), Lib.QCDataTrack) THEN
  306. WMDialogs.Error(Title, "Not a Data Disc");
  307. RETURN;
  308. END;
  309. startsec := Utils.ConvertBE32Int(toc.TrackStartAdr);
  310. recorder.UpdateCapacity();
  311. IF MakeIsoImages.GetVolumeDescriptor(recorder.dev, startsec, pvd, MakeIsoImages.Primary) # ResOk THEN RETURN END;
  312. size := Utils.ConvertLE32Int(pvd.VolSpaceSize);
  313. IF (Utils.IsReadOnly(dest^, readOnly) # ResOk) OR (Utils.GetFreeSpace(dest^, freeSpace) # ResOk) THEN
  314. COPY(dest^, msg); Strings.Append(msg, " seems to be invalid");
  315. WMDialogs.Error(Title, msg);
  316. RETURN;
  317. END;
  318. IF readOnly THEN
  319. WMDialogs.Error(Title, "Destination volume is read only");
  320. RETURN;
  321. ELSIF ((size * MakeIsoImages.SectorSize) DIV 1024) > freeSpace THEN
  322. WMDialogs.Error(Title, "Not enough Space for image");
  323. RETURN;
  324. END;
  325. UpdateSize(disc.usedBlocks*MakeIsoImages.SectorSize, 0);
  326. ShowBurnPanel();
  327. burnPanel.SetTitle0(Strings.NewString("Reading source"));
  328. burnPanel.progress0.SetRange(0, (size * MakeIsoImages.SectorSize) DIV 1024 );
  329. burnPanel.progress0.SetPos(0);
  330. IF MakeIsoImages.SaveImage(recorder.dev, startsec, dest^, UpdateStatus) # ResOk THEN
  331. burnPanel.Terminate(TRUE);
  332. ShowWorkPanel();
  333. RETURN;
  334. END;
  335. res := recorder.dev.MediaEject(FALSE, FALSE);
  336. IF WMDialogs.Message(WMDialogs.TInformation, "Record", "Insert Empty Medium", {WMDialogs.ResAbort, WMDialogs.ResYes}) = WMDialogs.ResAbort THEN
  337. burnPanel.Terminate(TRUE);
  338. ShowWorkPanel();
  339. RETURN;
  340. END;
  341. NEW(compilation);
  342. res := compilation.AddTrack(dest, CDRecord.DataTrack, FALSE);
  343. IF res # ResOk THEN
  344. burnPanel.Terminate(TRUE);
  345. ShowWorkPanel();
  346. RETURN;
  347. END;
  348. compilation.Finish();
  349. burnPanel.progress1.SetRange(0, compilation.GetSize(FALSE, TRUE));
  350. res := Record(compilation, copyDlg.burnPage.recorder,copyDlg. burnPage.settings);
  351. (* delete the image if desired *)
  352. IF copyDlg.sourcePage.remove.Get() & FileExists(dest^) THEN
  353. NEW(waitDlg, Strings.NewString("Please Wait"), bounds, 200, 100, FALSE);
  354. waitDlg.SetText("Removing iso image");
  355. waitDlg.ShowNonModal;
  356. Files.Delete(dest^, tmp);
  357. waitDlg.Close();
  358. END;
  359. IF res = ResOk THEN
  360. burnPanel.Terminate(FALSE);
  361. ELSE
  362. burnPanel.Terminate(TRUE);
  363. END;
  364. ShowWorkPanel();
  365. END CopyHandler;
  366. PROCEDURE BlankHandler(sender, data: ANY);
  367. VAR
  368. recDlg: RecorderDialog;
  369. typeDlg: BlankTypeDialog;
  370. disc: CDRecord.Disc;
  371. recorder: CDRecord.CDRecorder;
  372. res: WORD;
  373. waitDlg: WaitDialog;
  374. BEGIN
  375. IF IdentifyRecorders() # ResOk THEN RETURN END;
  376. NEW(recDlg, Strings.NewString("Blank"), bounds, 300, 200);
  377. recDlg.Show();
  378. IF recDlg.result # ResOk THEN RETURN END;
  379. recorder := recDlg.recorder;
  380. IF WaitOnDisc(recorder) # ResOk THEN RETURN END;
  381. NEW(disc);
  382. IF recorder.GetDiscInfo(disc) # ResOk THEN
  383. WMDialogs.Error(Title, "Could not read disc information");
  384. RETURN;
  385. END;
  386. IF ~disc.erasable THEN
  387. WMDialogs.Error(Title, "Inserted disc is not eraseble");
  388. RETURN;
  389. END;
  390. NEW(typeDlg, Strings.NewString("Blank Type"), bounds, 300, 200);
  391. typeDlg.Show();
  392. IF typeDlg.result # ResOk THEN RETURN END;
  393. NEW(waitDlg, Strings.NewString("Waiting"), bounds, 200, 100, FALSE);
  394. waitDlg.SetText("Erasing. Please Wait.");
  395. waitDlg.abort.visible.Set(FALSE);
  396. waitDlg.ShowNonModal();
  397. res := Lib.Blank(recorder.dev, TRUE, typeDlg.type, Lib.Ignore);
  398. IF res # ResOk THEN
  399. WMDialogs.Error(Title, "An error occured during erase operation");
  400. RETURN;
  401. END;
  402. recorder.WaitUntilFinished();
  403. waitDlg.Close();
  404. WMDialogs.Information(Title, "Disc successfully erased");
  405. END BlankHandler;
  406. PROCEDURE OpenHandler(sender, data: ANY);
  407. VAR
  408. imageDlg: ImageDialog;
  409. file: Files.File;
  410. info: MakeIsoImages.ISOInfo;
  411. compilation: CDRecord.Compilation;
  412. image: String;
  413. res : WORD;
  414. BEGIN
  415. IF IdentifyRecorders() = ResErr THEN RETURN END;
  416. NEW(imageDlg, Strings.NewString("Burn"), bounds, 300, 400);
  417. imageDlg.Show();
  418. IF imageDlg.result = WMDialogs.ResOk THEN
  419. burnPanel.progress0.visible.Set(FALSE);
  420. ShowBurnPanel();
  421. image := imageDlg.imagePage.location.Get();
  422. file := Files.Old(image^);
  423. IF file # NIL THEN
  424. NEW(info);
  425. IF info.Open(image) = ResOk THEN
  426. NEW(compilation);
  427. res := compilation.AddTrack(image, CDRecord.DataTrack, FALSE);
  428. compilation.Finish();
  429. UpdateSize(compilation.GetSize(FALSE, FALSE), 0);
  430. burnPanel.progress1.SetRange(0, compilation.GetSize(FALSE, TRUE));
  431. res := Record(compilation, imageDlg.burnPage.recorder, imageDlg.burnPage.settings);
  432. ELSE
  433. res := ResErr;
  434. WMDialogs.Error(Title, "not an iso file");
  435. END;
  436. ELSE
  437. res := ResErr;
  438. WMDialogs.Error(Title, "image not found");
  439. END;
  440. IF res = ResOk THEN
  441. burnPanel.Terminate(FALSE);
  442. ELSE
  443. burnPanel.Terminate(TRUE);
  444. END;
  445. ShowWorkPanel();
  446. END;
  447. END OpenHandler;
  448. PROCEDURE ProjectHandler(sender, data: ANY);
  449. VAR
  450. audioPanel: AudioPanel;
  451. dataPanel: DataPanel;
  452. sessDlg: SessionDialog;
  453. bootDlg: BootDialog;
  454. res: WORD;
  455. audioProject: AudioProject;
  456. dataProject: DataProject;
  457. BEGIN
  458. IF projectPanel # NIL THEN
  459. leftPanel.RemoveContent(projectPanel);
  460. projectPanel := NIL;
  461. END;
  462. IF sender = audioBtn THEN
  463. NEW(audioProject);
  464. NEW(audioPanel, audioProject);
  465. projectPanel := audioPanel;
  466. UpdateSize(0, 0);
  467. ELSIF sender = dataBtn THEN
  468. NEW(dataProject);
  469. NEW(sessDlg, Strings.NewString("Burn"), bounds, 300, 200);
  470. sessDlg.Show();
  471. IF sessDlg.result # WMDialogs.ResOk THEN RETURN END;
  472. dataProject.session := sessDlg.session;
  473. IF ((sessDlg.session = StartMultisession) OR (sessDlg.session = ContinueMultisession)) & ~BBMultisessionCapable THEN
  474. res := WMDialogs.Message(WMDialogs.TQuestion, Title, "Multisession discs are not yet supported in Bluebottle. Only first session will be readable. Continue?" , {WMDialogs.ResYes, WMDialogs.ResNo});
  475. IF res = WMDialogs.ResNo THEN RETURN END;
  476. END;
  477. IF (sessDlg.session = ContinueMultisession) OR (sessDlg.session = FinishMultisession) THEN
  478. IF ReadSessionData(dataProject) # ResOk THEN RETURN END;
  479. ELSIF sessDlg.session = BootSession THEN
  480. NEW(bootDlg, Strings.NewString("Boot"), bounds, 300, 400);
  481. bootDlg.Show();
  482. IF bootDlg.result # ResOk THEN RETURN END;
  483. IF bootDlg.bootCatalog = NIL THEN
  484. WMDialogs.Error(Title, "Boot Image not found");
  485. RETURN;
  486. END;
  487. dataProject.bootCatalog := bootDlg.bootCatalog;
  488. dataProject.totalSize := bootDlg.imageSize;
  489. END;
  490. NEW(dataPanel, dataProject);
  491. projectPanel := dataPanel;
  492. UpdateSize(dataProject.totalSize, dataProject.overhead);
  493. END;
  494. projectPanel.owner := SELF;
  495. projectPanel.alignment.Set(WMComponents.AlignClient);
  496. leftPanel.AddContent(projectPanel);
  497. projectPanel.Reset(NIL, NIL);
  498. projectPanel.Invalidate();
  499. leftPanel.Resized();
  500. END ProjectHandler;
  501. PROCEDURE ReadSessionData(project: DataProject): LONGINT;
  502. VAR
  503. adr, startSec: LONGINT;
  504. recDlg: RecorderDialog;
  505. recorder: CDRecord.CDRecorder;
  506. info:Lib.SessionInfo;
  507. reader: MakeIsoImages.ISOReader;
  508. BEGIN
  509. IF IdentifyRecorders() # ResOk THEN RETURN ResErr END;
  510. NEW(recDlg, Strings.NewString("Multisession"), bounds, 300, 200);
  511. recDlg.Show();
  512. IF recDlg.result # ResOk THEN RETURN ResErr END;
  513. recorder := recDlg.recorder;
  514. (* first check if recorder is multisession capable *)
  515. IF ~(CDRecord.MFMultisession IN recorder.cap.mediaFunc) THEN
  516. WMDialogs.Error(Title, "Selected Recorder does not support Multisession");
  517. RETURN ResErr;
  518. END;
  519. IF WaitOnDisc(recorder) # ResOk THEN RETURN ResErr END;
  520. IF Lib.ReadSessionInfo(recorder.dev, info) # ResOk THEN
  521. WMDialogs.Error(Title, "Cannot read session info");
  522. RETURN ResErr;
  523. END;
  524. IF Lib.GetNextAddress(recorder.dev, adr) # ResOk THEN
  525. WMDialogs.Error(Title, "medium is full or finalized");
  526. RETURN ResErr;
  527. END;
  528. project.isoOfs := adr;
  529. startSec := Utils.ConvertBE32Int(info.StartAdrFirstTrack);
  530. NEW(reader, recorder.dev);
  531. recorder.UpdateCapacity();
  532. IF reader.Read(startSec) # ResOk THEN
  533. RETURN ResErr;
  534. END;
  535. project.root := reader.tree.root;
  536. project.totalSize := reader.tree.sizeFiles;
  537. project.oldSize := project.totalSize;
  538. project.overhead := adr*MakeIsoImages.SectorSize-project.oldSize;
  539. RETURN ResOk;
  540. END ReadSessionData;
  541. PROCEDURE WaitOnDisc(recorder: CDRecord.CDRecorder): LONGINT;
  542. VAR
  543. res: WORD;
  544. waitDlg: WaitDialog;
  545. BEGIN
  546. NEW(waitDlg, Strings.NewString("Waiting"), bounds, 200, 100, TRUE);
  547. REPEAT
  548. waitDlg.SetText("Recorder not ready. Please Wait.");
  549. waitDlg.ShowNonModal();
  550. REPEAT
  551. Objects.Yield();
  552. res := recorder.dev.RequestSense();
  553. IF recorder.CheckNoMediumPresent() THEN res := 3008 END;
  554. UNTIL recorder.IsReady() OR (res = 3008) OR (waitDlg.result = WMDialogs.ResAbort);
  555. IF waitDlg.result = WMDialogs.ResAbort THEN
  556. RETURN ResErr;
  557. ELSE
  558. waitDlg.Close();
  559. END;
  560. IF res = 3008 THEN
  561. IF WMDialogs.Message(WMDialogs.TAction, "Not Ready", "No Medium present" , {WMDialogs.ResOk, WMDialogs.ResAbort}) = WMDialogs.ResAbort THEN
  562. RETURN ResErr;
  563. END;
  564. END;
  565. UNTIL recorder.IsReady();
  566. RETURN ResOk;
  567. END WaitOnDisc;
  568. PROCEDURE BurnHandler(sender, data: ANY);
  569. VAR handler: Handler;
  570. BEGIN
  571. IF projectPanel = NIL THEN
  572. WMDialogs.Error(Title, "Please create a project first");
  573. RETURN;
  574. ELSE
  575. IF projectPanel.project.totalSize <= 0 THEN
  576. WMDialogs.Error(Title, "Project is empty");
  577. RETURN;
  578. END;
  579. IF (projectPanel IS DataPanel) & (projectPanel.project.totalSize - projectPanel.project(DataProject).oldSize <=0) THEN
  580. WMDialogs.Error(Title, "No New Data Added");
  581. RETURN;
  582. END;
  583. IF projectPanel IS AudioPanel THEN
  584. NEW(handler, BurnAudioHandler, data);
  585. ELSIF projectPanel IS DataPanel THEN
  586. NEW(handler, BurnDataHandler, data);
  587. END;
  588. END;
  589. END BurnHandler;
  590. PROCEDURE BurnAudioHandler(sender, data: ANY);
  591. VAR
  592. audioDlg: AudioDialog;
  593. waitDlg: WaitDialog;
  594. tmp, res: WORD; freeSpace, wavSpace: LONGINT;
  595. dest:String;
  596. cur: Node;
  597. project: AudioProject;
  598. compilation: CDRecord.Compilation;
  599. msg: ARRAY MaxLen OF CHAR;
  600. readOnly: BOOLEAN;
  601. BEGIN
  602. project := projectPanel.project(AudioProject);
  603. IF IdentifyRecorders() = ResErr THEN RETURN END;
  604. NEW(audioDlg, Strings.NewString("Burn"), bounds, 300, 400);
  605. audioDlg.Show();
  606. IF audioDlg.result = WMDialogs.ResOk THEN
  607. dest := audioDlg.audioPage.location.Get();
  608. IF (Utils.IsReadOnly(dest^, readOnly) # ResOk) OR (Utils.GetFreeSpace(dest^, freeSpace) # ResOk) THEN
  609. COPY(dest^, msg); Strings.Append(msg, " seems to be invalid");
  610. WMDialogs.Error(Title, msg);
  611. RETURN;
  612. END;
  613. wavSpace := GetWavSpace(project);
  614. IF wavSpace > 0 THEN
  615. IF readOnly THEN
  616. WMDialogs.Error(Title, "Destination volume is read only");
  617. RETURN;
  618. ELSIF (wavSpace DIV 1024) > freeSpace THEN
  619. WMDialogs.Error(Title, "Not enough Space for wav Files");
  620. RETURN;
  621. END;
  622. END;
  623. burnPanel.progress0.visible.Set(FALSE);
  624. ShowBurnPanel();
  625. res := Convert(project, dest);
  626. IF res = ResErr THEN
  627. WMDialogs.Error(Title, "an error occured during the conversion");
  628. ELSE
  629. NEW(compilation);
  630. cur := project.root(Node);
  631. WHILE (cur # NIL) & (res = ResOk) DO
  632. res := compilation.AddTrack(cur.convName, CDRecord.AudioTrack, FALSE);
  633. cur := cur.next;
  634. END;
  635. IF res = ResOk THEN
  636. compilation.Finish();
  637. burnPanel.progress1.SetRange(0, compilation.GetSize(FALSE, TRUE));
  638. res := Record(compilation, audioDlg.burnPage.recorder, audioDlg.burnPage.settings);
  639. END;
  640. END;
  641. (* delete the converted if desired *)
  642. IF audioDlg.audioPage.remove.Get() THEN
  643. NEW(waitDlg, Strings.NewString("Please Wait"), bounds, 200, 100, FALSE);
  644. waitDlg.SetText("Removing iso image");
  645. waitDlg.ShowNonModal;
  646. cur := project.root(Node);
  647. WHILE cur # NIL DO
  648. IF cur.mp3 & FileExists(cur.convName^) THEN
  649. Files.Delete(cur.convName^, tmp);
  650. END;
  651. cur := cur.next;
  652. END;
  653. waitDlg.Close();
  654. END;
  655. IF res = ResOk THEN
  656. burnPanel.Terminate(FALSE);
  657. ELSE
  658. burnPanel.Terminate(TRUE);
  659. END;
  660. ShowWorkPanel();
  661. END;
  662. END BurnAudioHandler;
  663. (* returns the number of bytes needed for conversion of wav files *)
  664. PROCEDURE GetWavSpace(project: AudioProject): LONGINT;
  665. VAR
  666. node: Node;
  667. size: LONGINT;
  668. BEGIN
  669. node := project.root(Node);
  670. WHILE node # NIL DO
  671. IF node.mp3 THEN INC(size, node.size) END;
  672. node := node.next;
  673. END;
  674. RETURN size;
  675. END GetWavSpace;
  676. PROCEDURE Convert(project: AudioProject; dest: String): LONGINT;
  677. VAR
  678. no: LONGINT; res: WORD;
  679. cur: Node;
  680. filename, path, tmp: ARRAY MaxLen OF CHAR;
  681. BEGIN
  682. cur := project.root(Node);
  683. no := 0;
  684. WHILE cur # NIL DO
  685. IF cur.mp3 THEN
  686. filename := "TRACK";
  687. Strings.IntToStr(no, tmp);
  688. Strings.Append(filename, tmp);
  689. Strings.Append(filename, ".WAV");
  690. INC(no);
  691. Files.JoinPath(dest^, filename, path);
  692. cur.convName := Strings.NewString(path);
  693. IF FileExists(path) THEN
  694. IF WMDialogs.Confirmation("Confirm overwriting", path) = WMDialogs.ResNo THEN
  695. RETURN ResErr;
  696. END;
  697. END;
  698. Files.SplitPath(cur.fullpath^, tmp, filename);
  699. burnPanel.progress0.visible.Set(TRUE);
  700. burnPanel.SetTitle0(Strings.NewString("Converting mp3 Files"));
  701. burnPanel.SetCaption0(Strings.NewString(filename));
  702. burnPanel.progress0.SetRange(0, cur.size DIV 1024);
  703. burnPanel.progress0.SetPos(0);
  704. res := Utils.Mp3ToWave(cur.fullpath, cur.convName, UpdateStatus);
  705. IF res # ResOk THEN
  706. RETURN ResErr;
  707. END;
  708. ELSE (* no conversion needed *)
  709. cur.convName := cur.fullpath;
  710. END;
  711. cur := cur.next;
  712. END;
  713. RETURN ResOk;
  714. END Convert;
  715. PROCEDURE UpdateStatus(status: Utils.Status);
  716. BEGIN
  717. (* schedule event and return immedately *)
  718. (* it doesn't matter if one status notifcation is skipped *)
  719. onStatusChanged.Call(status);
  720. END UpdateStatus;
  721. PROCEDURE StatusChanged(sender, data: ANY);
  722. VAR
  723. filename, path: ARRAY MaxLen OF CHAR;
  724. tmp: ARRAY MaxLen OF CHAR;
  725. percent: LONGINT;
  726. recStatus: CDRecord.RecordingStatus;
  727. writeStatus: MakeIsoImages.WritingStatus;
  728. convStatus: Utils.ConvertingStatus;
  729. BEGIN
  730. IF ~sequencer.IsCallFromSequencer() THEN
  731. sequencer.ScheduleEvent(SELF.StatusChanged, sender, data);
  732. ELSE
  733. IF data IS Utils.ConvertingStatus THEN
  734. convStatus := data(Utils.ConvertingStatus);
  735. burnPanel.progress0.SetPos(convStatus.bytesEncoded DIV 1024);
  736. ELSIF data IS CDRecord.RecordingStatus THEN
  737. recStatus := data(CDRecord.RecordingStatus);
  738. IF recStatus.operation = CDRecord.Verifying THEN
  739. burnPanel.progress1.SetPos(recStatus.secsVerified);
  740. ELSE
  741. burnPanel.progress1.SetPos(recStatus.secsTransferred);
  742. END;
  743. IF recStatus.bufferSize > 0 THEN
  744. percent :=100* (recStatus.bufferSize - recStatus.freeBuffer) DIV recStatus.bufferSize;
  745. ELSE
  746. percent := 0;
  747. END;
  748. Strings.IntToStr(percent, tmp);
  749. Strings.Append(tmp, "%");
  750. burnPanel.SetLevel(Strings.NewString(tmp));
  751. Strings.IntToStr(recStatus.currentSpeed, tmp);
  752. Strings.Append(tmp, " KB/s");
  753. burnPanel.SetSpeed(Strings.NewString(tmp));
  754. CASE recStatus.operation OF
  755. CDRecord.Calibrating: tmp := "Calibrating";
  756. | CDRecord.Writing: tmp := "Writing";
  757. | CDRecord.ClosingTrack: tmp := "Closing Track";
  758. | CDRecord.ClosingSession: tmp := "Closing Session";
  759. | CDRecord.SendingCueSheet: tmp := "Sending Cue Sheet";
  760. | CDRecord.FillingFifo: tmp := "Filling Fifo";
  761. | CDRecord.FlushingCache: tmp := "Flushing Cache";
  762. | CDRecord.Verifying: tmp := "Verifying Written Data";
  763. ELSE tmp := "";
  764. END;
  765. burnPanel.SetOp(Strings.NewString(tmp));
  766. ELSIF data IS MakeIsoImages.WritingStatus THEN
  767. writeStatus := data(MakeIsoImages.WritingStatus);
  768. IF writeStatus.fileName # NIL THEN
  769. Files.SplitPath(writeStatus.fileName^, path, filename);
  770. burnPanel.SetCaption0(Strings.NewString(filename));
  771. END;
  772. burnPanel.progress0.SetPos(writeStatus.bytesWritten DIV 1024);
  773. END;
  774. END;
  775. END StatusChanged;
  776. PROCEDURE RefreshHandler(sender, data: ANY);
  777. BEGIN
  778. explorer.tree.Refresh();
  779. END RefreshHandler;
  780. PROCEDURE BurnDataHandler(sender, data: ANY);
  781. VAR
  782. dataDlg: DataDialog;
  783. res, tmp: WORD;
  784. root: ANY;
  785. dest: String;
  786. compilation: CDRecord.Compilation;
  787. isoSettings: MakeIsoImages.IsoSettings;
  788. project: DataProject;
  789. burnSettings: CDRecord.BurnSettings;
  790. waitDlg: WaitDialog;
  791. msg, str: ARRAY MaxLen OF CHAR;
  792. BEGIN
  793. project := projectPanel.project(DataProject);
  794. IF IdentifyRecorders() = ResErr THEN RETURN END;
  795. NEW(dataDlg, Strings.NewString("Burn"), bounds, 300, 400);
  796. dataDlg.Show();
  797. IF dataDlg.result = WMDialogs.ResOk THEN
  798. root :=project.root;
  799. burnSettings := dataDlg.burnPage.settings;
  800. burnSettings.multisession := (project.session = ContinueMultisession) OR (project.session = StartMultisession);
  801. burnSettings.append := (project.session = ContinueMultisession) OR (project.session = FinishMultisession);
  802. isoSettings := dataDlg.isoPage.settings;
  803. dest := dataDlg.isoPage.location.Get();
  804. IF FileExists(dest^) THEN
  805. IF WMDialogs.Confirmation("Confirm overwriting", dest^) = WMDialogs.ResNo THEN
  806. RETURN;
  807. ELSE
  808. (* delete the file in order to adjust free space *)
  809. Files.Delete(dest^, tmp);
  810. END;
  811. END;
  812. ShowBurnPanel();
  813. burnPanel.SetTitle0(Strings.NewString("Generating ISO Image"));
  814. burnPanel.progress0.SetRange(0, (project.totalSize - project.oldSize) DIV 1024 );
  815. burnPanel.progress0.SetPos(0);
  816. isoSettings.bootCatalog := project.bootCatalog;
  817. isoSettings.startLba := project.isoOfs;
  818. IF (project.totalSize - project.oldSize) DIV MakeIsoImages.SectorSize < BBMinISOSize THEN
  819. msg := "This image is too small to be mountable on Bluebottle. Do you want the image be padded to the minimal size of ";
  820. Strings.IntToStr(BBMinISOSize, str); Strings.Append(msg, str); Strings.Append(msg, " Sectors?");
  821. res := WMDialogs.Message(WMDialogs.TQuestion, "Info", msg , {WMDialogs.ResYes, WMDialogs.ResNo, WMDialogs.ResAbort});
  822. IF res = WMDialogs.ResYes THEN
  823. isoSettings.padToSize := BBMinISOSize;
  824. ELSIF res = WMDialogs.ResAbort THEN
  825. burnPanel.Terminate(TRUE);
  826. ShowWorkPanel();
  827. RETURN;
  828. END;
  829. END;
  830. res := MakeIsoImages.MakeImageFromTree(project.root(Directory),dest, isoSettings, UpdateStatus);
  831. IF res # ResOk THEN
  832. CASE res OF
  833. MakeIsoImages.ErrNotEnoughSpace: msg := "Not enough Space for Image";
  834. | MakeIsoImages.ErrDestinationInvalid: msg := "Destination is invalid";
  835. | MakeIsoImages.ErrDestinationReadOnly: msg := "Destination is read only";
  836. | MakeIsoImages.ErrFileNotFound: msg := "an error occured during of ISO Image: File not found";
  837. ELSE msg := "an error occured during generation of ISO Image";
  838. END;
  839. WMDialogs.Error(Title, msg);
  840. burnPanel.Terminate(TRUE);
  841. ShowWorkPanel();
  842. RETURN;
  843. ELSE
  844. NEW(compilation);
  845. res := compilation.AddTrack(dest, CDRecord.DataTrack, FALSE);
  846. IF res = ResOk THEN
  847. compilation.Finish();
  848. burnPanel.progress1.SetRange(0, compilation.GetSize(FALSE, TRUE));
  849. res := Record(compilation, dataDlg.burnPage.recorder, burnSettings);
  850. ELSE
  851. WMDialogs.Error(Title, "Track could not be added");
  852. burnPanel.Terminate(TRUE);
  853. ShowWorkPanel();
  854. RETURN;
  855. END;
  856. END;
  857. (* delete the image if desired *)
  858. IF dataDlg.isoPage.remove.Get() & FileExists(dest^) THEN
  859. NEW(waitDlg, Strings.NewString("Please Wait"), bounds, 200, 100, FALSE);
  860. waitDlg.SetText("Removing iso image");
  861. waitDlg.ShowNonModal;
  862. Files.Delete(dest^, tmp);
  863. waitDlg.Close();
  864. END;
  865. IF res = ResOk THEN
  866. burnPanel.Terminate(FALSE);
  867. ELSE
  868. burnPanel.Terminate(TRUE);
  869. END;
  870. ShowWorkPanel();
  871. END;
  872. END BurnDataHandler;
  873. PROCEDURE Record(compilation: CDRecord.Compilation; recorder: CDRecord.CDRecorder; settings: CDRecord.BurnSettings): WORD;
  874. VAR
  875. res, tmp : WORD;
  876. msg, str : ARRAY MaxLen OF CHAR;
  877. waitDlg: WaitDialog;
  878. timer: Timer;
  879. BEGIN
  880. IF CheckController(compilation, recorder, str) THEN
  881. msg := "source ("; Strings.Append(msg, str); Strings.Append(msg, ") and recorder (");
  882. Strings.Append(msg, recorder.dev.name);
  883. Strings.Append(msg, ") are connected to the same controller. This decreases performance of buffer!");
  884. WMDialogs.Information(Title, msg);
  885. END;
  886. IF recorder.dev.openCount > 0 THEN
  887. msg := "OpenCount of device (";
  888. Strings.Append(msg, recorder.dev.desc);
  889. Strings.Append(msg, ") is not zero. Unmount any partition first.");
  890. WMDialogs.Error(Title, msg);
  891. RETURN ResErr;
  892. END;
  893. NEW(timer); timer.interval.Set(500);
  894. timer.onUpdate.Add(TimeHandler);
  895. NEW(waitDlg, Strings.NewString("Waiting"), bounds, 200, 100, TRUE);
  896. LOOP
  897. timer.Start(SELF, NIL);
  898. res := recorder.Record(compilation, settings, UpdateStatus);
  899. timer.Stop(SELF, NIL); burnPanel.SetTime(Strings.NewString(""));
  900. IF res = CDRecord.ErrDriveNotReady THEN
  901. msg := "Recorder not ready. Please Wait";
  902. waitDlg.SetText(msg);
  903. waitDlg.ShowNonModal();
  904. REPEAT
  905. Objects.Yield();
  906. res := recorder.dev.RequestSense();
  907. IF recorder.CheckNoMediumPresent() THEN res := CDRecord.ErrNoMediumPresent END;
  908. UNTIL recorder.IsReady() OR (res = CDRecord.ErrNoMediumPresent) OR (waitDlg.result = WMDialogs.ResAbort);
  909. IF waitDlg.result = WMDialogs.ResAbort THEN
  910. RETURN ResErr;
  911. ELSE
  912. waitDlg.Close();
  913. END;
  914. ELSIF res = CDRecord.ErrSendingCueSheet THEN
  915. IF settings.multisession THEN
  916. msg := "Drive does not support SAO with multisession disc. Do you want to burn it in TAO mode instead?";
  917. ELSE
  918. msg := "Cue sheet could not be sent.Do you want to burn in TAO mode instead?";
  919. END;
  920. IF WMDialogs.Message(WMDialogs.TAction, "Not Ready", msg , {WMDialogs.ResOk, WMDialogs.ResAbort}) = WMDialogs.ResAbort THEN
  921. RETURN ResErr;
  922. ELSE
  923. settings.writeType := CDRecord.TrackAtOnce;
  924. END;
  925. ELSIF (res = CDRecord.ErrCDRWNotEmpty) OR (res = CDRecord.ErrCDRWNotAppendable) THEN
  926. msg :=" CDRW is not empty. Do you want to blank it now?";
  927. tmp := WMDialogs.Message(WMDialogs.TAction, "Not Ready", msg , {WMDialogs.ResAbort, WMDialogs.ResNo, WMDialogs.ResYes});
  928. IF tmp = WMDialogs.ResAbort THEN
  929. RETURN ResErr;
  930. ELSIF tmp = WMDialogs.ResYes THEN
  931. BlankHandler(SELF, NIL);
  932. END;
  933. ELSIF res = CDRecord.ErrWriting THEN
  934. msg := "An error occured during writing.";
  935. IF recorder.locked THEN
  936. Strings.Append(msg, " Drive could not be unlocked.");
  937. END;
  938. WMDialogs.Error(Title, msg);
  939. RETURN ResErr;
  940. ELSIF res = CDRecord.ErrVerificationFailed THEN
  941. msg := "Verification failed";
  942. WMDialogs.Error(Title, msg );
  943. RETURN ResErr
  944. ELSE
  945. CASE res OF
  946. CDRecord.ErrDiscNotEmpty: msg := "Disc is not empty";
  947. | CDRecord.ErrNotEnoughFreeSpace: msg := "Data does not fit on inserted Disk";
  948. | CDRecord.ErrNoMediumPresent: msg := "No Medium present";
  949. | CDRecord.ErrDiscNotAppendable: msg := "Inserted Disc is finalized";
  950. | CDRecord.ErrIncompatibleMedium: msg := "Inserted disc is incompatible";
  951. ELSE EXIT;
  952. END;
  953. IF WMDialogs.Message(WMDialogs.TAction, "Not Ready", msg , {WMDialogs.ResOk, WMDialogs.ResAbort}) = WMDialogs.ResAbort THEN
  954. RETURN ResErr;
  955. END;
  956. END;
  957. END;
  958. IF res = ResOk THEN
  959. msg := "Recording was successful. ";
  960. IF recorder.recStatus.empty >= 0 THEN
  961. Strings.Append(msg, "SW Buffer was ");
  962. Strings.IntToStr(recorder.recStatus.empty, str); Strings.Append(msg, str); Strings.Append(msg, " times empty. ");
  963. END;
  964. Strings.Append(msg, "Eject Disc?");
  965. IF WMDialogs.Message(WMDialogs.TQuestion, "Finished", msg , {WMDialogs.ResNo, WMDialogs.ResYes}) = WMDialogs.ResYes THEN
  966. tmp := recorder.dev.MediaEject(FALSE, FALSE);
  967. END;
  968. END;
  969. tmp := recorder.dev.RequestSense();
  970. RETURN res;
  971. END Record;
  972. PROCEDURE TimeHandler(sender, data: ANY);
  973. VAR
  974. time: Time;
  975. timeStr: ARRAY MaxLen OF CHAR;
  976. BEGIN
  977. time := data(Time);
  978. time.Format(timeStr);
  979. burnPanel.SetTime(Strings.NewString(timeStr));
  980. END TimeHandler;
  981. PROCEDURE Close;
  982. BEGIN
  983. Close^();
  984. DecCount();
  985. END Close;
  986. END Window;
  987. SessionDialog = OBJECT(Utils.StandardDialog);
  988. VAR
  989. session: LONGINT;
  990. sessionList: Utils.ListBox;
  991. PROCEDURE CreateDialog;
  992. VAR
  993. bearing: WMRectangles.Rectangle;
  994. BEGIN
  995. CreateDialog^;
  996. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  997. NEW(sessionList); sessionList.bearing.Set(bearing); sessionList.bounds.SetHeight(120); sessionList.alignment.Set(WMComponents.AlignTop);
  998. sessionList.caption.Set(Strings.NewString("Session"));
  999. sessionList.Add(Strings.NewString("No Multisession"), NIL);
  1000. sessionList.Add(Strings.NewString("Start Multisession"), NIL);
  1001. sessionList.Add(Strings.NewString("Continue Multisession"), NIL);
  1002. sessionList.Add(Strings.NewString("Finish Multisession"), NIL);
  1003. sessionList.Add(Strings.NewString("Boot"), NIL);
  1004. content.AddContent(sessionList);
  1005. END CreateDialog;
  1006. PROCEDURE Ok(sender, data: ANY);
  1007. BEGIN
  1008. CASE sessionList.selected.Get() OF
  1009. 0: session := NoMultisession;
  1010. | 1: session := StartMultisession;
  1011. | 2: session := ContinueMultisession;
  1012. | 3: session := FinishMultisession;
  1013. | 4: session := BootSession;
  1014. END;
  1015. Ok^(sender, data);
  1016. END Ok;
  1017. END SessionDialog;
  1018. ToolDialog = OBJECT(Utils.StandardDialog);
  1019. VAR
  1020. tool: LONGINT;
  1021. toolList: Utils.ListBox;
  1022. PROCEDURE CreateDialog;
  1023. VAR
  1024. bearing: WMRectangles.Rectangle;
  1025. BEGIN
  1026. CreateDialog^;
  1027. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1028. NEW(toolList); toolList.bearing.Set(bearing); toolList.bounds.SetHeight(100); toolList.alignment.Set(WMComponents.AlignTop);
  1029. toolList.caption.Set(Strings.NewString("Tool"));
  1030. toolList.Add(Strings.NewString("Burn Iso Image"), NIL);
  1031. toolList.Add(Strings.NewString("Copy Data CD"), NIL);
  1032. toolList.Add(Strings.NewString("Blank CDRW"), NIL);
  1033. toolList.Add(Strings.NewString("Disc Information"), NIL);
  1034. content.AddContent(toolList);
  1035. END CreateDialog;
  1036. PROCEDURE Ok(sender, data: ANY);
  1037. BEGIN
  1038. CASE toolList.selected.Get() OF
  1039. 0: tool := OpenIsoTool;
  1040. | 1: tool := CopyIsoTool;
  1041. | 2: tool := BlankTool;
  1042. | 3: tool := DiscInfo;
  1043. END;
  1044. Ok^(sender, data);
  1045. END Ok;
  1046. END ToolDialog;
  1047. InfoDialog = OBJECT(Utils.StandardDialog);
  1048. VAR
  1049. disc: CDRecord.Disc;
  1050. grid: WMStringGrids.StringGrid;
  1051. PROCEDURE CreateDialog;
  1052. VAR
  1053. bearing: WMRectangles.Rectangle;
  1054. BEGIN
  1055. CreateDialog^;
  1056. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1057. NEW(grid);
  1058. grid.alignment.Set(WMComponents.AlignClient);
  1059. content.AddContent(grid);
  1060. grid.model.Acquire;
  1061. grid.alwaysShowScrollY.Set(FALSE);
  1062. grid.model.SetNofCols(2);
  1063. grid.SetSelectionMode(WMGrids.GridSelectNone);
  1064. grid.model.Release
  1065. END CreateDialog;
  1066. PROCEDURE Show;
  1067. VAR
  1068. tmp: ARRAY MaxLen OF CHAR;
  1069. colWidths: WMGrids.Spacings;
  1070. BEGIN
  1071. NEW(colWidths, 2);
  1072. colWidths[0] := width DIV 2;
  1073. colWidths[1] := width DIV 2;
  1074. grid.SetColSpacings(colWidths);
  1075. grid.model.Acquire;
  1076. grid.model.SetNofRows(7);
  1077. grid.model.SetCellText(0, 0, Strings.NewString("type:"));
  1078. grid.model.SetCellText(0, 1, Strings.NewString("status:"));
  1079. grid.model.SetCellText(0, 2, Strings.NewString("used space:"));
  1080. grid.model.SetCellText(0, 3, Strings.NewString("free space:"));
  1081. grid.model.SetCellText(0, 4, Strings.NewString("sessions: "));
  1082. grid.model.SetCellText(0, 5, Strings.NewString("last session: "));
  1083. grid.model.SetCellText(0, 6, Strings.NewString("max wr. speed: "));
  1084. IF disc # NIL THEN
  1085. IF disc.erasable & (disc IS CDRecord.DiscEx) THEN
  1086. CASE disc(CDRecord.DiscEx).subtype OF
  1087. Lib.ATCdRwStandardSpeed: tmp := "CDRW Standard Speed";
  1088. | Lib.ATCdRwHighSpeed: tmp := "CDRW High Speed";
  1089. | Lib.ATCdRwUltraHighSpeed, Lib.ATCdRwUltraHighSpeedPlus: tmp := "CDRW Ultra High Speed";
  1090. ELSE tmp := "Unknown";
  1091. END;
  1092. ELSIF disc IS CDRecord.DiscEx THEN
  1093. tmp := "CDR";
  1094. ELSE
  1095. CASE disc.type OF
  1096. Lib.DTCdDACdRom: tmp := "CD-DA / CD-Rom (Not recordable)"; (* TODO: Read Toc to find out wheter DA or CD-ROM*)
  1097. | Lib.DTCdI: tmp := "CD-I";
  1098. | Lib.DTCdRomXA: tmp := "CD-Rom XA";
  1099. | Lib.DTUndefined: tmp := "Undefined";
  1100. ELSE tmp := "Unknown";
  1101. END;
  1102. END;
  1103. grid.model.SetCellText(1, 0, Strings.NewString(tmp));
  1104. CASE disc.status OF
  1105. Lib.DSEmpty: tmp := "Empty Disc";
  1106. | Lib.DSAppendable: tmp := "Incomplete Disc (Appendable)";
  1107. | Lib.DSComplete: tmp := "Complete Disc";
  1108. | Lib.DSOtherStatus: tmp := "Unknown Status";
  1109. END;
  1110. grid.model.SetCellText(1, 1, Strings.NewString(tmp));
  1111. Strings.IntToStr(disc.usedBlocks, tmp); Strings.Append(tmp, " sectors");
  1112. grid.model.SetCellText(1, 2, Strings.NewString(tmp));
  1113. Strings.IntToStr(disc.freeBlocks, tmp); Strings.Append(tmp, " sectors");
  1114. grid.model.SetCellText(1, 3, Strings.NewString(tmp));
  1115. Strings.IntToStr(disc.nofSessions, tmp);
  1116. grid.model.SetCellText(1, 4, Strings.NewString(tmp));
  1117. CASE disc.statusLastSession OF
  1118. Lib.LSSEmpty: tmp := "Empty";
  1119. | Lib.LSSIncomplete: tmp := "Incomplete";
  1120. | Lib.LSSComplete: tmp := "Complete";
  1121. END;
  1122. grid.model.SetCellText(1, 5, Strings.NewString(tmp));
  1123. IF (disc IS CDRecord.DiscEx) & (disc(CDRecord.DiscEx).maxSpeed > 0) THEN
  1124. Strings.IntToStr(disc(CDRecord.DiscEx).maxSpeed, tmp); Strings.Append(tmp, " x");
  1125. ELSE
  1126. tmp := "Not available";
  1127. END;
  1128. grid.model.SetCellText(1, 6, Strings.NewString(tmp));
  1129. END;
  1130. grid.model.Release;
  1131. Show^();
  1132. END Show;
  1133. PROCEDURE &Create*(title: String; bounds: WMRectangles.Rectangle; width, height: LONGINT; disc: CDRecord.Disc);
  1134. BEGIN
  1135. SELF.disc := disc;
  1136. New(title, bounds, width, height);
  1137. END Create;
  1138. END InfoDialog;
  1139. BlankTypeDialog = OBJECT(Utils.StandardDialog);
  1140. VAR
  1141. type: LONGINT;
  1142. typeList: Utils.ListBox;
  1143. PROCEDURE CreateDialog;
  1144. VAR
  1145. bearing: WMRectangles.Rectangle;
  1146. BEGIN
  1147. CreateDialog^;
  1148. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1149. NEW(typeList); typeList.bearing.Set(bearing); typeList.bounds.SetHeight(100); typeList.alignment.Set(WMComponents.AlignTop);
  1150. typeList.caption.Set(Strings.NewString("Type"));
  1151. typeList.Add(Strings.NewString("Quick"), NIL);
  1152. typeList.Add(Strings.NewString("Complete"), NIL);
  1153. content.AddContent(typeList);
  1154. END CreateDialog;
  1155. PROCEDURE Ok(sender, data: ANY);
  1156. BEGIN
  1157. CASE typeList.selected.Get() OF
  1158. 0: type := Lib.BDQuick;
  1159. | 1: type := Lib.BDEntire;
  1160. END;
  1161. Ok^(sender, data);
  1162. END Ok;
  1163. END BlankTypeDialog;
  1164. RecorderDialog = OBJECT(Utils.StandardDialog);
  1165. VAR
  1166. recorder: CDRecord.CDRecorder;
  1167. recList: Utils.ListBox;
  1168. PROCEDURE CreateDialog;
  1169. VAR
  1170. bearing: WMRectangles.Rectangle;
  1171. label: WMStandardComponents.Label;
  1172. i: LONGINT;
  1173. BEGIN
  1174. CreateDialog^;
  1175. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1176. NEW(label);
  1177. label.bearing.Set(bearing); label.bounds.SetHeight(60); label.alignment.Set(WMComponents.AlignTop); label.caption.SetAOC("Please choose desired Recorder and insert disc");
  1178. content.AddContent(label);
  1179. NEW(recList); recList.bearing.Set(bearing); recList.bounds.SetHeight(60); recList.alignment.Set(WMComponents.AlignTop);
  1180. recList.caption.Set(Strings.NewString("Drive"));
  1181. i := 0;
  1182. WHILE (i < LEN(recorders)) & (recorders[i] # NIL) DO
  1183. recList.Add(Strings.NewString(recorders[i].name), NIL);
  1184. INC(i);
  1185. END;
  1186. content.AddContent(recList);
  1187. END CreateDialog;
  1188. PROCEDURE Ok(sender, data: ANY);
  1189. BEGIN
  1190. recorder := recorders[recList.selected.Get()];
  1191. Ok^(sender, data);
  1192. END Ok;
  1193. END RecorderDialog;
  1194. WaitDialog = OBJECT(Utils.StandardDialog);
  1195. VAR
  1196. label: WMStandardComponents.Label;
  1197. PROCEDURE CreateDialog;
  1198. VAR
  1199. bearing: WMRectangles.Rectangle;
  1200. BEGIN
  1201. CreateDialog^;
  1202. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1203. buttonPanel.RemoveContent(ok);
  1204. NEW(label);
  1205. label.bearing.Set(bearing); label.alignment.Set(WMComponents.AlignClient);
  1206. content.AddContent(label);
  1207. END CreateDialog;
  1208. PROCEDURE &Create*(title: String; bounds: WMRectangles.Rectangle; width, height: LONGINT; abortable: BOOLEAN);
  1209. BEGIN
  1210. New(title, bounds, width, height);
  1211. IF ~abortable THEN content.RemoveContent(abort) END;
  1212. END Create;
  1213. PROCEDURE Abort(sender, data: ANY);
  1214. BEGIN
  1215. IF result < 0 THEN
  1216. manager.Remove(SELF);
  1217. END;
  1218. result := WMDialogs.ResAbort;
  1219. END Abort;
  1220. PROCEDURE Close;
  1221. BEGIN
  1222. Abort(SELF, NIL);
  1223. END Close;
  1224. PROCEDURE SetText(CONST str: ARRAY OF CHAR);
  1225. BEGIN
  1226. label.caption.Set(Strings.NewString(str));
  1227. END SetText;
  1228. END WaitDialog;
  1229. BurnPanel = OBJECT(WMComponents.VisualComponent);
  1230. VAR
  1231. bearing: WMRectangles.Rectangle;
  1232. endBtn: WMStandardComponents.Button;
  1233. progress0, progress1: Utils.ProgressBar;
  1234. result: LONGINT;
  1235. prepareLabel, titleLabel0, titleLabel1, opLabel, bufLabel, speedLabel, timeLabel: WMStandardComponents.Label;
  1236. PROCEDURE &Init*;
  1237. VAR
  1238. preparePanel, burnPanel, bufPanel, speedPanel, opPanel, timePanel, buttonPanel: WMStandardComponents.Panel;
  1239. label0, label1, label2, label3 : WMStandardComponents.Label;
  1240. BEGIN
  1241. Init^();
  1242. NEW(buttonPanel);
  1243. result := -1;
  1244. buttonPanel.alignment.Set(WMComponents.AlignBottom);
  1245. buttonPanel.bounds.SetHeight(30);
  1246. AddContent(buttonPanel);
  1247. NEW(endBtn);
  1248. endBtn.bounds.SetExtents(60,30);
  1249. endBtn.alignment.Set(WMComponents.AlignRight);
  1250. endBtn.visible.Set(FALSE);
  1251. endBtn.onClick.Add(EndHandler);
  1252. buttonPanel.AddContent(endBtn);
  1253. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1254. NEW(preparePanel);
  1255. preparePanel.bounds.SetHeight(100); preparePanel.alignment.Set(WMComponents.AlignTop);
  1256. AddContent(preparePanel);
  1257. NEW(titleLabel0);
  1258. titleLabel0.bearing.Set(bearing); titleLabel0.bounds.SetHeight(30); titleLabel0.alignment.Set(WMComponents.AlignTop);
  1259. preparePanel.AddContent(titleLabel0);
  1260. NEW(prepareLabel); prepareLabel.bearing.Set(bearing); prepareLabel.bounds.SetHeight(20); prepareLabel.alignment.Set(WMComponents.AlignTop);
  1261. preparePanel.AddContent(prepareLabel);
  1262. NEW(progress0); progress0.bearing.Set(bearing); progress0.bounds.SetHeight(20); progress0.alignment.Set(WMComponents.AlignTop); progress0.color.Set(Blue);
  1263. progress0.borderColor.Set(Black); progress0.fillColor.Set(White);
  1264. preparePanel.AddContent(progress0);
  1265. NEW(burnPanel);
  1266. burnPanel.alignment.Set(WMComponents.AlignClient);
  1267. AddContent(burnPanel);
  1268. NEW(titleLabel1);
  1269. titleLabel1.bearing.Set(bearing); titleLabel1.bounds.SetHeight(30); titleLabel1.alignment.Set(WMComponents.AlignTop); titleLabel1.caption.SetAOC("Recording");
  1270. burnPanel.AddContent(titleLabel1);
  1271. NEW(opPanel);
  1272. opPanel.bounds.SetHeight(20); opPanel.bearing.Set(bearing); opPanel.alignment.Set(WMComponents.AlignTop);
  1273. burnPanel.AddContent(opPanel);
  1274. NEW(label2);
  1275. label2.bounds.SetWidth(60); label2.alignment.Set(WMComponents.AlignLeft); label2.caption.SetAOC("operation: ");
  1276. opPanel.AddContent(label2);
  1277. NEW(opLabel);
  1278. opLabel.bounds.SetWidth(140); opLabel.alignment.Set(WMComponents.AlignLeft);
  1279. opPanel.AddContent(opLabel);
  1280. NEW(progress1); progress1.bearing.Set(bearing);progress1.alignment.Set(WMComponents.AlignTop); progress1.SetRange(0,20); progress1.color.Set(Blue);
  1281. progress1.borderColor.Set(Black); progress1.fillColor.Set(White); progress1.bounds.SetHeight(20);
  1282. burnPanel.AddContent(progress1);
  1283. NEW(bufPanel);
  1284. bufPanel.bounds.SetHeight(20); bufPanel.bearing.Set(bearing); bufPanel.alignment.Set(WMComponents.AlignTop);
  1285. burnPanel.AddContent(bufPanel);
  1286. NEW(label0);
  1287. label0.bounds.SetWidth(80); label0.alignment.Set(WMComponents.AlignLeft); label0.caption.SetAOC("buffer level: ");
  1288. bufPanel.AddContent(label0);
  1289. NEW(bufLabel);
  1290. bufLabel.bounds.SetWidth(80); bufLabel.alignment.Set(WMComponents.AlignLeft);
  1291. bufPanel.AddContent(bufLabel);
  1292. NEW(speedPanel);
  1293. speedPanel.bounds.SetHeight(20); speedPanel.bearing.Set(bearing); speedPanel.alignment.Set(WMComponents.AlignTop);
  1294. burnPanel.AddContent(speedPanel);
  1295. NEW(label1);
  1296. label1.bounds.SetWidth(80); label1.alignment.Set(WMComponents.AlignLeft); label1.caption.SetAOC("speed: ");
  1297. speedPanel.AddContent(label1);
  1298. NEW(speedLabel);
  1299. speedLabel.bounds.SetWidth(80); speedLabel.alignment.Set(WMComponents.AlignLeft);
  1300. speedPanel.AddContent(speedLabel);
  1301. NEW(timePanel);
  1302. timePanel.bounds.SetHeight(20); timePanel.bearing.Set(bearing); timePanel.alignment.Set(WMComponents.AlignTop);
  1303. burnPanel.AddContent(timePanel);
  1304. NEW(label3);
  1305. label3.bounds.SetWidth(80); label3.alignment.Set(WMComponents.AlignLeft); label3.caption.SetAOC("elapsed time: ");
  1306. timePanel.AddContent(label3);
  1307. NEW(timeLabel);
  1308. timeLabel.bounds.SetWidth(80); timeLabel.alignment.Set(WMComponents.AlignLeft);
  1309. timePanel.AddContent(timeLabel);
  1310. END Init;
  1311. PROCEDURE ResetAll;
  1312. BEGIN
  1313. progress0.SetPos(0);
  1314. progress1.SetPos(0);
  1315. titleLabel0.caption.Set(Strings.NewString(""));
  1316. prepareLabel.caption.Set(Strings.NewString(""));
  1317. bufLabel.caption.Set(Strings.NewString(""));
  1318. speedLabel.caption.Set(Strings.NewString(""));
  1319. opLabel.caption.Set(Strings.NewString(""));
  1320. timeLabel.caption.Set(Strings.NewString(""));
  1321. result := -1;
  1322. endBtn.visible.Set(FALSE);
  1323. END ResetAll;
  1324. PROCEDURE SetTitle0(str: String);
  1325. BEGIN
  1326. titleLabel0.caption.Set(str);
  1327. END SetTitle0;
  1328. PROCEDURE SetCaption0(str: String);
  1329. BEGIN
  1330. prepareLabel.caption.Set(str);
  1331. END SetCaption0;
  1332. PROCEDURE SetTime(str: String);
  1333. BEGIN
  1334. timeLabel.caption.Set(str);
  1335. END SetTime;
  1336. PROCEDURE SetLevel(str: String);
  1337. BEGIN
  1338. bufLabel.caption.Set(str);
  1339. END SetLevel;
  1340. PROCEDURE SetSpeed(str: String);
  1341. BEGIN
  1342. speedLabel.caption.Set(str);
  1343. END SetSpeed;
  1344. PROCEDURE SetOp(str: String);
  1345. BEGIN
  1346. opLabel.caption.Set(str);
  1347. END SetOp;
  1348. PROCEDURE Terminate(error: BOOLEAN);
  1349. BEGIN
  1350. IF error THEN
  1351. endBtn.caption.SetAOC("Failed");
  1352. ELSE
  1353. endBtn.caption.SetAOC("Done");
  1354. END;
  1355. endBtn.visible.Set(TRUE);
  1356. endBtn.Reset(NIL, NIL);
  1357. endBtn.Invalidate();
  1358. BEGIN {EXCLUSIVE}
  1359. AWAIT(result >= 0);
  1360. END;
  1361. END Terminate;
  1362. PROCEDURE EndHandler(sender, data: ANY);
  1363. BEGIN {EXCLUSIVE}
  1364. result := 1;
  1365. END EndHandler;
  1366. END BurnPanel;
  1367. CopyDialog = OBJECT(Utils.PropertySheet);
  1368. VAR
  1369. sourcePage: SourcePage;
  1370. burnPage: BurnPage;
  1371. PROCEDURE CreateDialog;
  1372. BEGIN
  1373. CreateDialog^;
  1374. NEW(sourcePage);
  1375. sourcePage.alignment.Set(WMComponents.AlignClient);
  1376. sourcePage.remove.Set(TRUE);
  1377. sourcePage.location.Set(Strings.NewString(DefaultImageLocation));
  1378. sourcePage.UpdateData(FALSE);
  1379. AddPage(sourcePage, Strings.NewString("Source"));
  1380. SelectPage(sourcePage);
  1381. NEW(burnPage);
  1382. burnPage.alignment.Set(WMComponents.AlignClient);
  1383. AddPage(burnPage, Strings.NewString("Burn"));
  1384. END CreateDialog;
  1385. PROCEDURE Ok(sender, data: ANY);
  1386. BEGIN
  1387. sourcePage.UpdateData(TRUE);
  1388. burnPage.UpdateData(TRUE);
  1389. Ok^(sender, data);
  1390. END Ok;
  1391. END CopyDialog;
  1392. AudioDialog = OBJECT(Utils.PropertySheet);
  1393. VAR
  1394. audioPage: AudioPage;
  1395. burnPage: BurnPage;
  1396. PROCEDURE CreateDialog;
  1397. BEGIN
  1398. CreateDialog^;
  1399. NEW(audioPage);
  1400. audioPage.alignment.Set(WMComponents.AlignClient);
  1401. audioPage.remove.Set(TRUE);
  1402. audioPage.location.Set(Strings.NewString(DefaultWaveLocation));
  1403. audioPage.UpdateData(FALSE);
  1404. AddPage(audioPage, Strings.NewString("Audio"));
  1405. SelectPage(audioPage);
  1406. NEW(burnPage);
  1407. burnPage.alignment.Set(WMComponents.AlignClient);
  1408. burnPage.RemoveContent(burnPage.verifyChk);
  1409. AddPage(burnPage, Strings.NewString("Burn"));
  1410. END CreateDialog;
  1411. PROCEDURE Ok(sender, data: ANY);
  1412. BEGIN
  1413. audioPage.UpdateData(TRUE);
  1414. burnPage.UpdateData(TRUE);
  1415. Ok^(sender, data);
  1416. END Ok;
  1417. END AudioDialog;
  1418. DataDialog = OBJECT(Utils.PropertySheet);
  1419. VAR
  1420. isoPage: IsoPage;
  1421. burnPage: BurnPage;
  1422. PROCEDURE CreateDialog;
  1423. BEGIN
  1424. CreateDialog^;
  1425. NEW(isoPage);
  1426. isoPage.alignment.Set(WMComponents.AlignClient);
  1427. isoPage.settings.joliet := TRUE;
  1428. isoPage.remove.Set(TRUE);
  1429. isoPage.location.Set(Strings.NewString(DefaultImageLocation));
  1430. isoPage.settings.isoLevel := MakeIsoImages.IsoLevel1;
  1431. isoPage.UpdateData(FALSE);
  1432. AddPage(isoPage, Strings.NewString("ISO"));
  1433. SelectPage(isoPage);
  1434. NEW(burnPage);
  1435. burnPage.alignment.Set(WMComponents.AlignClient);
  1436. AddPage(burnPage, Strings.NewString("Burn"));
  1437. burnPage.recorder := recorders[0];
  1438. burnPage.UpdateData(FALSE);
  1439. END CreateDialog;
  1440. PROCEDURE Ok(sender, data: ANY);
  1441. BEGIN
  1442. isoPage.UpdateData(TRUE);
  1443. burnPage.UpdateData(TRUE);
  1444. Ok^(sender, data);
  1445. END Ok;
  1446. END DataDialog;
  1447. ImageDialog = OBJECT(Utils.PropertySheet);
  1448. VAR
  1449. imagePage: ImagePage;
  1450. burnPage: BurnPage;
  1451. PROCEDURE CreateDialog;
  1452. BEGIN
  1453. CreateDialog^;
  1454. NEW(imagePage);
  1455. imagePage.alignment.Set(WMComponents.AlignClient);
  1456. imagePage.UpdateData(FALSE);
  1457. AddPage(imagePage, Strings.NewString("Image"));
  1458. SelectPage(imagePage);
  1459. NEW(burnPage);
  1460. burnPage.alignment.Set(WMComponents.AlignClient);
  1461. AddPage(burnPage, Strings.NewString("Burn"));
  1462. burnPage.recorder := recorders[0];
  1463. burnPage.UpdateData(FALSE)
  1464. END CreateDialog;
  1465. PROCEDURE Ok(sender, data: ANY);
  1466. BEGIN
  1467. imagePage.UpdateData(TRUE);
  1468. burnPage.UpdateData(TRUE);
  1469. Ok^(sender, data);
  1470. END Ok;
  1471. END ImageDialog;
  1472. BootDialog = OBJECT(Utils.StandardDialog);
  1473. VAR
  1474. bootCatalog: MakeIsoImages.BootCatalog;
  1475. locationEdit, idEdit: WMEditors.Editor;
  1476. platformList, emulList: Utils.ListBox;
  1477. imageSize: LONGINT;
  1478. PROCEDURE CreateDialog;
  1479. VAR
  1480. label1, label2: WMStandardComponents.Label;
  1481. bearing: WMRectangles.Rectangle;
  1482. locationPanel: WMStandardComponents.Panel;
  1483. browseBtn: WMStandardComponents.Button;
  1484. BEGIN
  1485. CreateDialog^();
  1486. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1487. NEW(label1); label1.bearing.Set(bearing); label1.alignment.Set(WMComponents.AlignTop); label1.bounds.SetHeight(20); label1.caption.SetAOC("location of boot image");
  1488. content.AddContent(label1);
  1489. NEW(locationPanel); locationPanel.alignment.Set(WMComponents.AlignTop); locationPanel.bounds.SetHeight(26);
  1490. content.AddContent(locationPanel);
  1491. NEW(locationEdit); locationEdit.bearing.Set(bearing); locationEdit.alignment.Set(WMComponents.AlignClient); locationEdit.bounds.SetHeight(20); locationEdit.multiLine.Set(FALSE);
  1492. locationEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  1493. locationEdit.fillColor.Set(White); locationEdit.tv.showBorder.Set(TRUE);
  1494. locationPanel.AddContent(locationEdit);
  1495. NEW(browseBtn); browseBtn.alignment.Set(WMComponents.AlignRight); browseBtn.bounds.SetWidth(60); browseBtn.caption.SetAOC("Browse...");
  1496. locationPanel.AddContent(browseBtn); browseBtn.onClick.Add(OnBrowse);
  1497. NEW(label2); label2.bearing.Set(bearing); label2.alignment.Set(WMComponents.AlignTop); label2.bounds.SetHeight(20); label2.caption.SetAOC("id String");
  1498. content.AddContent(label2);
  1499. NEW(idEdit); idEdit.bearing.Set(bearing); idEdit.alignment.Set(WMComponents.AlignTop); idEdit.bounds.SetHeight(20); idEdit.multiLine.Set(FALSE);
  1500. idEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  1501. idEdit.fillColor.Set(White); idEdit.tv.showBorder.Set(TRUE);
  1502. content.AddContent(idEdit);
  1503. NEW(emulList); emulList.bearing.Set(bearing); emulList.bounds.SetHeight(140); emulList.alignment.Set(WMComponents.AlignTop);
  1504. emulList.caption.Set(Strings.NewString("Emulation"));
  1505. emulList.Add(Strings.NewString("None"), NIL);
  1506. emulList.Add(Strings.NewString("1.2MB Floppy"), NIL);
  1507. emulList.Add(Strings.NewString("1.44MB Floppy"), NIL);
  1508. emulList.Add(Strings.NewString("2.88MB Floppy"), NIL);
  1509. emulList.Add(Strings.NewString("Harddisc"), NIL);
  1510. content.AddContent(emulList);
  1511. NEW(platformList); platformList.bearing.Set(bearing); platformList.bounds.SetHeight(80); platformList.alignment.Set(WMComponents.AlignTop);
  1512. platformList.caption.Set(Strings.NewString("Platform"));
  1513. platformList.Add(Strings.NewString("80x86"), NIL);
  1514. platformList.Add(Strings.NewString("PowerPC"), NIL);
  1515. platformList.Add(Strings.NewString("Mac"), NIL);
  1516. content.AddContent(platformList);
  1517. END CreateDialog;
  1518. PROCEDURE OnBrowse(sender, data: ANY);
  1519. VAR
  1520. dlg: Utils.FileDialog;
  1521. path: String;
  1522. BEGIN
  1523. NEW(dlg, Strings.NewString("Boot File"), bounds, 400, 200);
  1524. dlg.Show();
  1525. IF dlg.result = WMDialogs.ResOk THEN
  1526. path := dlg.path.Get();
  1527. locationEdit.SetAsString(path^);
  1528. END;
  1529. END OnBrowse;
  1530. PROCEDURE Ok(sender, data: ANY);
  1531. VAR
  1532. image, id: ARRAY MaxLen OF CHAR;
  1533. emulation, platform: CHAR;
  1534. BEGIN
  1535. bootCatalog := NIL;
  1536. locationEdit.GetAsString(image); RemoveSpecialChars(image);
  1537. IF (image # "") & FileExists(image) THEN
  1538. imageSize := GetFileSize(image);
  1539. CASE platformList.selected.Get() OF
  1540. 0: platform := MakeIsoImages.Platform80x86;
  1541. | 1: platform := MakeIsoImages.PlatformPowerPC;
  1542. | 2: platform := MakeIsoImages.PlatformMac;
  1543. END;
  1544. CASE emulList.selected.Get() OF
  1545. 0: emulation := MakeIsoImages.EmulationNone;
  1546. | 1: emulation := MakeIsoImages.Emulation12Floppy;
  1547. | 2: emulation := MakeIsoImages.Emulation144Floppy;
  1548. | 3: emulation := MakeIsoImages.Emulation288Floppy;
  1549. | 4: emulation := MakeIsoImages.EmulationHDD;
  1550. END;
  1551. idEdit.GetAsString(id);
  1552. NEW(bootCatalog);
  1553. bootCatalog.AddDefaultEntry(Strings.NewString(image), Strings.NewString(id), TRUE, platform, emulation);
  1554. END;
  1555. Ok^(sender, data);
  1556. END Ok;
  1557. END BootDialog;
  1558. AudioPage = OBJECT(Utils.PropertyPage)
  1559. VAR
  1560. remove: WMProperties.BooleanProperty;
  1561. removeChk: WMStandardComponents.Checkbox;
  1562. location: WMProperties.StringProperty;
  1563. locationEdit: WMEditors.Editor;
  1564. PROCEDURE &Init*;
  1565. VAR
  1566. label: WMStandardComponents.Label;
  1567. bearing: WMRectangles.Rectangle;
  1568. BEGIN
  1569. Init^();
  1570. NEW(location, NIL, NIL, NIL); NEW(remove, NIL, NIL, NIL);
  1571. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1572. NEW(label); label.bearing.Set(bearing); label.alignment.Set(WMComponents.AlignTop); label.bounds.SetHeight(20); label.caption.SetAOC("location for converted mp3 files ");
  1573. AddContent(label);
  1574. NEW(locationEdit); locationEdit.bearing.Set(bearing); locationEdit.alignment.Set(WMComponents.AlignTop); locationEdit.bounds.SetHeight(20); locationEdit.multiLine.Set(FALSE);
  1575. locationEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  1576. locationEdit.fillColor.Set(White); locationEdit.tv.showBorder.Set(TRUE);
  1577. AddContent(locationEdit);
  1578. NEW(removeChk); removeChk.bearing.Set(bearing); removeChk.bounds.SetExtents(100, 14); removeChk.alignment.Set(WMComponents.AlignTop);
  1579. removeChk.caption.Set(Strings.NewString("Remove converted wav files after writing"));
  1580. AddContent(removeChk);
  1581. END Init;
  1582. PROCEDURE UpdateData(save: BOOLEAN);
  1583. VAR
  1584. str: ARRAY MaxLen OF CHAR;
  1585. string: String;
  1586. BEGIN
  1587. IF save THEN
  1588. IF removeChk.state.Get() = 0 THEN remove.Set(FALSE); ELSE remove.Set(TRUE); END;
  1589. locationEdit.GetAsString(str); RemoveSpecialChars(str); location.Set(Strings.NewString(str));
  1590. ELSE
  1591. IF remove.Get() THEN removeChk.state.Set(1); ELSE removeChk.state.Set(0); END;
  1592. string := location.Get();
  1593. IF string # NIL THEN
  1594. locationEdit.SetAsString(string^);
  1595. END;
  1596. RecacheProperties();
  1597. END;
  1598. END UpdateData;
  1599. END AudioPage;
  1600. SourcePage = OBJECT(Utils.PropertyPage)
  1601. VAR
  1602. remove: WMProperties.BooleanProperty;
  1603. removeChk: WMStandardComponents.Checkbox;
  1604. location: WMProperties.StringProperty;
  1605. locationEdit: WMEditors.Editor;
  1606. recList: Utils.ListBox;
  1607. recorder: CDRecord.CDRecorder;
  1608. PROCEDURE &Init*;
  1609. VAR
  1610. label: WMStandardComponents.Label;
  1611. bearing: WMRectangles.Rectangle;
  1612. i: LONGINT;
  1613. BEGIN
  1614. Init^();
  1615. NEW(location, NIL, NIL, NIL); NEW(remove, NIL, NIL, NIL);
  1616. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1617. NEW(recList); recList.bearing.Set(bearing); recList.bounds.SetHeight(60); recList.alignment.Set(WMComponents.AlignTop);
  1618. recList.caption.Set(Strings.NewString("Drive"));
  1619. i := 0;
  1620. WHILE (i < LEN(recorders)) & (recorders[i] # NIL) DO
  1621. recList.Add(Strings.NewString(recorders[i].name), NIL);
  1622. INC(i);
  1623. END;
  1624. AddContent(recList);
  1625. NEW(label); label.bearing.Set(bearing); label.alignment.Set(WMComponents.AlignTop); label.bounds.SetHeight(20); label.caption.SetAOC("location for image");
  1626. AddContent(label);
  1627. NEW(locationEdit); locationEdit.bearing.Set(bearing); locationEdit.alignment.Set(WMComponents.AlignTop); locationEdit.bounds.SetHeight(20); locationEdit.multiLine.Set(FALSE);
  1628. locationEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  1629. locationEdit.fillColor.Set(White); locationEdit.tv.showBorder.Set(TRUE);
  1630. AddContent(locationEdit);
  1631. NEW(removeChk); removeChk.bearing.Set(bearing); removeChk.bounds.SetExtents(100, 14); removeChk.alignment.Set(WMComponents.AlignTop);
  1632. removeChk.caption.Set(Strings.NewString("Remove image after writing"));
  1633. AddContent(removeChk);
  1634. END Init;
  1635. PROCEDURE UpdateData(save: BOOLEAN);
  1636. VAR
  1637. str: ARRAY MaxLen OF CHAR;
  1638. string: String;
  1639. BEGIN
  1640. IF save THEN
  1641. IF removeChk.state.Get() = 0 THEN remove.Set(FALSE); ELSE remove.Set(TRUE); END;
  1642. locationEdit.GetAsString(str); RemoveSpecialChars(str);
  1643. location.Set(Strings.NewString(str));
  1644. recorder := recorders[recList.selected.Get()];
  1645. ELSE
  1646. IF remove.Get() THEN removeChk.state.Set(1); ELSE removeChk.state.Set(0); END;
  1647. string := location.Get();
  1648. IF string # NIL THEN
  1649. locationEdit.SetAsString(string^);
  1650. END;
  1651. RecacheProperties();
  1652. END;
  1653. END UpdateData;
  1654. END SourcePage;
  1655. ImagePage = OBJECT(Utils.PropertyPage)
  1656. VAR
  1657. location: WMProperties.StringProperty;
  1658. locationEdit: WMEditors.Editor;
  1659. PROCEDURE &Init*;
  1660. VAR
  1661. label: WMStandardComponents.Label;
  1662. bearing: WMRectangles.Rectangle;
  1663. locationPanel: WMStandardComponents.Panel;
  1664. browseBtn: WMStandardComponents.Button;
  1665. BEGIN
  1666. Init^();
  1667. NEW(location, NIL, NIL, NIL);
  1668. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1669. NEW(label); label.bearing.Set(bearing); label.alignment.Set(WMComponents.AlignTop); label.bounds.SetHeight(20); label.caption.SetAOC("location of image");
  1670. AddContent(label);
  1671. NEW(locationPanel); locationPanel.alignment.Set(WMComponents.AlignTop); locationPanel.bounds.SetHeight(26);
  1672. AddContent(locationPanel);
  1673. NEW(locationEdit); locationEdit.bearing.Set(bearing); locationEdit.alignment.Set(WMComponents.AlignClient); locationEdit.bounds.SetHeight(20); locationEdit.multiLine.Set(FALSE);
  1674. locationEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  1675. locationEdit.fillColor.Set(White); locationEdit.tv.showBorder.Set(TRUE);
  1676. locationPanel.AddContent(locationEdit);
  1677. NEW(browseBtn); browseBtn.alignment.Set(WMComponents.AlignRight); browseBtn.bounds.SetWidth(60); browseBtn.caption.SetAOC("Browse...");
  1678. locationPanel.AddContent(browseBtn); browseBtn.onClick.Add(OnBrowse);
  1679. END Init;
  1680. PROCEDURE OnBrowse(sender, data: ANY);
  1681. VAR
  1682. dlg: Utils.FileDialog;
  1683. path: String;
  1684. BEGIN
  1685. NEW(dlg, Strings.NewString("Image File"), owner.bounds, 400, 200);
  1686. dlg.Show();
  1687. IF dlg.result = WMDialogs.ResOk THEN
  1688. path := dlg.path.Get();
  1689. locationEdit.SetAsString(path^);
  1690. END;
  1691. END OnBrowse;
  1692. PROCEDURE UpdateData(save: BOOLEAN);
  1693. VAR
  1694. str: ARRAY MaxLen OF CHAR;
  1695. string: String;
  1696. BEGIN
  1697. IF save THEN
  1698. locationEdit.GetAsString(str); RemoveSpecialChars(str);
  1699. location.Set(Strings.NewString(str));
  1700. ELSE
  1701. string := location.Get();
  1702. IF string # NIL THEN
  1703. locationEdit.SetAsString(string^);
  1704. END;
  1705. RecacheProperties();
  1706. END;
  1707. END UpdateData;
  1708. END ImagePage;
  1709. BurnPage = OBJECT(Utils.PropertyPage);
  1710. VAR
  1711. recorder: CDRecord.CDRecorder;
  1712. settings: CDRecord.BurnSettings;
  1713. recList: Utils.ListBox;
  1714. speedList: Utils.ListBox;
  1715. typeList: Utils.ListBox; (* TAO / SAO *)
  1716. verifyChk, bufeChk: WMStandardComponents.Checkbox;
  1717. PROCEDURE &Init*;
  1718. VAR
  1719. bearing: WMRectangles.Rectangle;
  1720. i: LONGINT;
  1721. BEGIN
  1722. Init^();
  1723. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1724. NEW(recList); recList.bearing.Set(bearing); recList.bounds.SetHeight(60); recList.alignment.Set(WMComponents.AlignTop);
  1725. recList.caption.Set(Strings.NewString("Drive"));
  1726. i := 0;
  1727. WHILE (i < LEN(recorders)) & (recorders[i] # NIL) DO
  1728. recList.Add(Strings.NewString(recorders[i].name), NIL);
  1729. INC(i);
  1730. END;
  1731. recList.onSelectionChanged.Add(ListSpeeds);
  1732. recList.onSelectionChanged.Add(ListTypes);
  1733. recList.onSelectionChanged.Add(ListOptions);
  1734. AddContent(recList);
  1735. NEW(speedList); speedList.bearing.Set(bearing); speedList.bounds.SetHeight(100); speedList.alignment.Set(WMComponents.AlignTop);
  1736. speedList.caption.Set(Strings.NewString("speed"));
  1737. AddContent(speedList);
  1738. NEW(typeList); typeList.bearing.Set(bearing); typeList.bounds.SetHeight(60); typeList.alignment.Set(WMComponents.AlignTop);
  1739. typeList.caption.Set(Strings.NewString("write type"));
  1740. AddContent(typeList);
  1741. NEW(verifyChk); verifyChk.bearing.Set(bearing); verifyChk.bounds.SetExtents(100, 14); verifyChk.alignment.Set(WMComponents.AlignTop);
  1742. verifyChk.caption.Set(Strings.NewString("Verify written data"));
  1743. AddContent(verifyChk);
  1744. NEW(bufeChk); bufeChk.bearing.Set(bearing); bufeChk.bounds.SetExtents(100, 14); bufeChk.alignment.Set(WMComponents.AlignTop);
  1745. bufeChk.caption.Set(Strings.NewString("Buffer Underrrun Free")); bufeChk.visible.Set(FALSE);
  1746. AddContent(bufeChk);
  1747. END Init;
  1748. PROCEDURE ListOptions(sender, data: ANY);
  1749. VAR
  1750. recorder: CDRecord.CDRecorder;
  1751. BEGIN
  1752. recorder := recorders[recList.selected.Get()];
  1753. IF recorder # NIL THEN
  1754. bufeChk.visible.Set(CDRecord.MFBufe IN recorder.cap.mediaFunc );
  1755. END;
  1756. END ListOptions;
  1757. PROCEDURE ListSpeeds(sender, data: ANY);
  1758. VAR
  1759. i: LONGINT;
  1760. recorder: CDRecord.CDRecorder;
  1761. tmp, entry: ARRAY MaxLen OF CHAR;
  1762. speed, max : LONGINT;
  1763. disc: CDRecord.DiscEx;
  1764. BEGIN
  1765. max := MAX(LONGINT);
  1766. recorder := recorders[recList.selected.Get()];
  1767. speedList.Clear();
  1768. IF recorder # NIL THEN
  1769. (* in case that a disc is inserted and the disc specifies a maximum speed we do not list all speeds *)
  1770. NEW(disc);
  1771. IF (recorder.GetDiscInfoEx(disc) = ResOk) & (disc.maxSpeed > 0) THEN
  1772. max := disc.maxSpeed;
  1773. END;
  1774. FOR i:= 0 TO LEN(recorder.cap.writeSpeeds)-1 DO
  1775. speed := recorder.cap.writeSpeeds[i];
  1776. IF (speed DIV CDRecord.SingleSpeed) <= max THEN
  1777. Strings.IntToStr(speed DIV CDRecord.SingleSpeed, entry);
  1778. Strings.Append(entry, "x (");
  1779. Strings.IntToStr(speed, tmp);
  1780. Strings.Append(entry, tmp);
  1781. Strings.Append(entry, " KB/s)");
  1782. speedList.Add(Strings.NewString(entry), NIL);
  1783. END;
  1784. END;
  1785. END;
  1786. speedList.Update();
  1787. END ListSpeeds;
  1788. PROCEDURE ListTypes(sender, data: ANY);
  1789. VAR
  1790. recorder: CDRecord.CDRecorder;
  1791. BEGIN
  1792. recorder := recorders[recList.selected.Get()];
  1793. typeList.Clear();
  1794. IF recorder # NIL THEN
  1795. typeList.Add(Strings.NewString("Track at Once"), NIL);
  1796. IF CDRecord.MFSao IN recorder.cap.mediaFunc THEN
  1797. typeList.Add(Strings.NewString("Session at Once"), NIL);
  1798. END;
  1799. END;
  1800. typeList.Update();
  1801. END ListTypes;
  1802. PROCEDURE UpdateData(save: BOOLEAN);
  1803. BEGIN
  1804. IF save THEN
  1805. recorder := recorders[recList.selected.Get()];
  1806. END;
  1807. IF recorder # NIL THEN
  1808. settings.speed := recorder.cap.writeSpeeds[speedList.selected.Get()] DIV CDRecord.SingleSpeed;
  1809. IF typeList.selected.Get() = 1 THEN
  1810. settings.writeType :=CDRecord.SessionAtOnce;
  1811. ELSE
  1812. settings.writeType := CDRecord.TrackAtOnce;
  1813. END;
  1814. settings.verify := verifyChk.state.Get() = 1;
  1815. settings.bufe := bufeChk.state.Get() = 1;
  1816. END;
  1817. END UpdateData;
  1818. END BurnPage;
  1819. IsoPage = OBJECT(Utils.PropertyPage);
  1820. VAR
  1821. settings: MakeIsoImages.IsoSettings;
  1822. remove: WMProperties.BooleanProperty;
  1823. location: WMProperties.StringProperty;
  1824. jolietChk, removeChk: WMStandardComponents.Checkbox;
  1825. levelList: Utils.ListBox;
  1826. locationEdit: WMEditors.Editor;
  1827. PROCEDURE &Init*;
  1828. VAR
  1829. label: WMStandardComponents.Label;
  1830. bearing: WMRectangles.Rectangle;
  1831. BEGIN
  1832. Init^();
  1833. NEW(remove, NIL, NIL, NIL); NEW(location, NIL, NIL, NIL);
  1834. bearing := WMRectangles.MakeRect(3, 3, 3, 3);
  1835. NEW(levelList); levelList.bearing.Set(bearing); levelList.bounds.SetHeight(100); levelList.alignment.Set(WMComponents.AlignTop);
  1836. levelList.caption.Set(Strings.NewString("ISO Level"));
  1837. levelList.Add(Strings.NewString("ISO Level 1"), NIL);
  1838. levelList.Add(Strings.NewString("ISO Level 2"), NIL);
  1839. AddContent(levelList);
  1840. NEW(jolietChk); jolietChk.bearing.Set(bearing); jolietChk.bounds.SetExtents(100, 14); jolietChk.alignment.Set(WMComponents.AlignTop);
  1841. jolietChk.caption.Set(Strings.NewString("Joliet Extensions"));
  1842. AddContent(jolietChk);
  1843. NEW(label); label.bearing.Set(bearing); label.alignment.Set(WMComponents.AlignTop); label.bounds.SetHeight(20); label.caption.SetAOC("location of iso image");
  1844. AddContent(label);
  1845. NEW(locationEdit); locationEdit.bearing.Set(bearing); locationEdit.alignment.Set(WMComponents.AlignTop); locationEdit.bounds.SetHeight(20); locationEdit.multiLine.Set(FALSE);
  1846. locationEdit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  1847. locationEdit.fillColor.Set(White); locationEdit.tv.showBorder.Set(TRUE);
  1848. AddContent(locationEdit);
  1849. NEW(removeChk); removeChk.bearing.Set(bearing); removeChk.bounds.SetExtents(100, 14); removeChk.alignment.Set(WMComponents.AlignTop);
  1850. removeChk.caption.Set(Strings.NewString("Remove image after writing"));
  1851. AddContent(removeChk);
  1852. END Init;
  1853. PROCEDURE UpdateData(save: BOOLEAN);
  1854. VAR
  1855. str: ARRAY MaxLen OF CHAR;
  1856. string: String;
  1857. BEGIN
  1858. IF save THEN
  1859. IF levelList.selected.Get() = 1 THEN
  1860. settings.isoLevel := MakeIsoImages.IsoLevel2;
  1861. ELSE
  1862. settings.isoLevel := MakeIsoImages.IsoLevel1;
  1863. END;
  1864. IF jolietChk.state.Get() = 0 THEN settings.joliet := FALSE ELSE settings.joliet := TRUE END;
  1865. IF removeChk.state.Get() = 0 THEN remove.Set(FALSE); ELSE remove.Set(TRUE); END;
  1866. locationEdit.GetAsString(str); RemoveSpecialChars(str); location.Set(Strings.NewString(str));
  1867. ELSE
  1868. IF settings.isoLevel = MakeIsoImages.IsoLevel2 THEN
  1869. levelList.selected.Set(1);
  1870. ELSE
  1871. levelList.selected.Set(0);
  1872. END;
  1873. IF settings.joliet THEN jolietChk.state.Set(1); ELSE jolietChk.state.Set(0); END;
  1874. IF remove.Get() THEN removeChk.state.Set(1); ELSE removeChk.state.Set(0); END;
  1875. string := location.Get();
  1876. locationEdit.SetAsString(string^);
  1877. RecacheProperties();
  1878. END;
  1879. END UpdateData;
  1880. END IsoPage;
  1881. URLDropTarget* = OBJECT(WMDropTarget.DropTarget)
  1882. VAR
  1883. node: ANY;
  1884. panel: ProjectPanel;
  1885. PROCEDURE &New*(panel: ProjectPanel; node: ANY);
  1886. BEGIN
  1887. SELF.panel := panel;
  1888. SELF.node := node;
  1889. END New;
  1890. PROCEDURE GetInterface*(type: LONGINT): WMDropTarget.DropInterface;
  1891. VAR
  1892. di: DropURL;
  1893. BEGIN
  1894. IF type = WMDropTarget.TypeURL THEN
  1895. NEW(di, SELF.panel, SELF.node);
  1896. RETURN di;
  1897. ELSE
  1898. RETURN NIL;
  1899. END;
  1900. END GetInterface;
  1901. END URLDropTarget;
  1902. DropURL* = OBJECT(WMDropTarget.DropURLs)
  1903. VAR
  1904. panel: ProjectPanel;
  1905. node: ANY;
  1906. PROCEDURE &New*(panel: ProjectPanel; node: ANY);
  1907. BEGIN
  1908. SELF.panel := panel;
  1909. SELF.node := node;
  1910. END New;
  1911. PROCEDURE URL*(CONST url: ARRAY OF CHAR; VAR res: WORD);
  1912. BEGIN
  1913. IF panel.enabled.Get() THEN
  1914. panel.AddFile(url, node);
  1915. END;
  1916. END URL;
  1917. END DropURL;
  1918. String = Strings.String;
  1919. Node = OBJECT
  1920. VAR
  1921. fullpath, convName: String;
  1922. next: Node;
  1923. size: LONGINT;
  1924. mp3: BOOLEAN;
  1925. END Node;
  1926. AudioFile = OBJECT(Node)
  1927. VAR
  1928. title: String;
  1929. duration: LONGINT;
  1930. PROCEDURE &New*(fullpath, title: String; duration: LONGINT; mp3: BOOLEAN);
  1931. BEGIN
  1932. SELF.fullpath := fullpath;
  1933. SELF.title := title;
  1934. SELF.duration := duration;
  1935. SELF.mp3 := mp3;
  1936. END New;
  1937. END AudioFile;
  1938. Selection = POINTER TO ARRAY OF ANY;
  1939. SelectionWrapper = POINTER TO RECORD
  1940. sel: Selection;
  1941. END;
  1942. Project = OBJECT
  1943. VAR
  1944. totalSize: LONGINT;
  1945. root: ANY;
  1946. END Project;
  1947. AudioProject = OBJECT(Project);
  1948. END AudioProject;
  1949. DataProject = OBJECT(Project);
  1950. VAR
  1951. session: LONGINT;
  1952. isoOfs: LONGINT; (* in case of multisession, this is the offset of the new session lead in*)
  1953. oldSize: LONGINT; (* total size of previous sessions *)
  1954. overhead: LONGINT; (* overhead for session leadins *)
  1955. bootCatalog: MakeIsoImages.BootCatalog;
  1956. END DataProject;
  1957. ProjectPanel = OBJECT(WMComponents.VisualComponent);
  1958. VAR
  1959. owner: Window;
  1960. project: Project;
  1961. PROCEDURE AddFile(CONST name: ARRAY OF CHAR; Node: ANY);
  1962. (* abstract *)
  1963. END AddFile;
  1964. END ProjectPanel;
  1965. AudioPanel = OBJECT(ProjectPanel);
  1966. VAR
  1967. grid: WMStringGrids.StringGrid;
  1968. colWidths: WMGrids.Spacings;
  1969. nofEntries: LONGINT;
  1970. popup: WMPopups.Popup;
  1971. root: Node;
  1972. PROCEDURE &New*(project: AudioProject);
  1973. BEGIN
  1974. Init();
  1975. SELF.project := project;
  1976. NEW(grid);
  1977. grid.alignment.Set(WMComponents.AlignClient);
  1978. AddContent(grid);
  1979. grid.model.Acquire;
  1980. grid.model.SetNofCols(3);
  1981. grid.model.SetNofRows(1);
  1982. grid.fixedRows.Set(1);
  1983. grid.model.SetCellText(0, 0, Strings.NewString("No"));
  1984. grid.model.SetCellText(1, 0, Strings.NewString("Title"));
  1985. grid.model.SetCellText(2, 0, Strings.NewString("Length"));
  1986. grid.SetSelectionMode(WMGrids.GridSelectRows);
  1987. NEW(colWidths, 3);
  1988. grid.model.Release;
  1989. grid.SetExtDragDroppedHandler(DragDroppedH);
  1990. grid.SetExtContextMenuHandler(ContextMenu);
  1991. END New;
  1992. PROCEDURE ContextMenu(sender: ANY; x, y: LONGINT);
  1993. VAR
  1994. curSel: Selection;
  1995. w: SelectionWrapper;
  1996. px, py: LONGINT;
  1997. BEGIN
  1998. NEW(popup); NEW(w);
  1999. curSel := GetSelection();
  2000. w.sel := curSel;
  2001. IF LEN(curSel) > 0 THEN
  2002. popup.AddParButton("Delete", DeleteFiles, w);
  2003. px := x; py := y;
  2004. grid.ToWMCoordinates(x, y, px, py);
  2005. popup.Popup(px, py);
  2006. END;
  2007. END ContextMenu;
  2008. PROCEDURE GetSelection(): Selection;
  2009. VAR
  2010. selection: Selection;
  2011. l, t, r, b, i, j: LONGINT;
  2012. p: ANY;
  2013. BEGIN
  2014. grid.model.Acquire;
  2015. grid.GetSelection(l, t, r, b);
  2016. NEW(selection, b-t+1);
  2017. j := 0;
  2018. FOR i := t TO b DO
  2019. p := grid.model.GetCellData(0, i);
  2020. IF (p # NIL) & (p IS Node) THEN
  2021. selection[j] := p(Node);
  2022. INC(j);
  2023. END;
  2024. END;
  2025. grid.model.Release;
  2026. RETURN selection;
  2027. END GetSelection;
  2028. PROCEDURE DeleteFiles(sender, data: ANY);
  2029. VAR
  2030. cur, prev: Node;
  2031. i: LONGINT;
  2032. selection: Selection;
  2033. BEGIN
  2034. IF popup # NIL THEN popup.Close; popup := NIL END;
  2035. i := 0;
  2036. selection := data(SelectionWrapper).sel;
  2037. cur := root;
  2038. WHILE (cur # NIL) & (i < LEN(selection)) DO
  2039. IF cur = selection[i] THEN
  2040. IF cur = root THEN
  2041. root := cur.next;
  2042. ELSE
  2043. prev.next := cur.next;
  2044. END;
  2045. INC(i); DEC(project.totalSize, cur.size); DEC(nofEntries);
  2046. owner.UpdateSize(project.totalSize, 0);
  2047. ELSE
  2048. prev := cur;
  2049. END;
  2050. cur := cur.next;
  2051. END;
  2052. Refresh();
  2053. END DeleteFiles;
  2054. PROCEDURE AddFile(CONST name: ARRAY OF CHAR; node: ANY);
  2055. VAR
  2056. title, file, path, ext: ARRAY MaxLen OF CHAR;
  2057. mp3info: Utils.MP3Info;
  2058. wavinfo: Utils.WAVInfo;
  2059. audioFile: AudioFile;
  2060. waitDlg : WaitDialog;
  2061. BEGIN
  2062. NEW(waitDlg, Strings.NewString("Waiting"), owner.bounds, 200, 100, TRUE);
  2063. waitDlg.SetText("Analyzing File");
  2064. waitDlg.ShowNonModal;
  2065. IF ~MakeIsoImages.GetExtension(name, file, ext) THEN RETURN END;
  2066. Strings.UpperCase(ext);
  2067. IF ext = "WAV" THEN
  2068. NEW(wavinfo);
  2069. IF (wavinfo.Open(Strings.NewString(name)) = ResOk) &
  2070. (wavinfo.compression = Utils.CPCM) & (wavinfo.nofchannels = 2) &
  2071. (wavinfo.samplerate = 44100) & (wavinfo.encoding = 16) THEN
  2072. Files.SplitPath(file, path, title);
  2073. NEW(audioFile, Strings.NewString(name), Strings.NewString(title), wavinfo.size DIV (44100*2*(16 DIV 8)), FALSE);
  2074. audioFile.size := wavinfo.size;
  2075. Insert(audioFile);
  2076. END;
  2077. ELSIF ext = "MP3" THEN
  2078. NEW(mp3info);
  2079. IF mp3info.Open(Strings.NewString(name)) = ResOk THEN
  2080. IF mp3info.id3v1 # NIL THEN
  2081. COPY(mp3info.id3v1.Title, title);
  2082. END;
  2083. IF title = "" THEN
  2084. Files.SplitPath(file, path, title);
  2085. END;
  2086. NEW(audioFile, Strings.NewString(name), Strings.NewString(title), mp3info.playtime, TRUE);
  2087. audioFile.size := 44100*2*(16 DIV 8)*audioFile.duration;
  2088. Insert(audioFile);
  2089. END;
  2090. END;
  2091. IF waitDlg.result # WMDialogs.ResAbort THEN
  2092. waitDlg.Close();
  2093. END;
  2094. END AddFile;
  2095. (* inserts track at the end of the list *)
  2096. PROCEDURE Insert(file: AudioFile);
  2097. VAR
  2098. cur: Node;
  2099. BEGIN
  2100. IF root = NIL THEN
  2101. root := file;
  2102. project.root := root;
  2103. ELSE
  2104. cur := root;
  2105. WHILE cur.next # NIL DO
  2106. cur := cur.next;
  2107. END;
  2108. cur.next := file;
  2109. END;
  2110. INC(nofEntries);
  2111. INC(project.totalSize, file.size);
  2112. owner.UpdateSize(project.totalSize, 0);
  2113. Refresh();
  2114. END Insert;
  2115. (* refreshes the list *)
  2116. PROCEDURE Refresh;
  2117. VAR
  2118. cur: Node;
  2119. row: LONGINT;
  2120. tmp: ARRAY MaxLen OF CHAR;
  2121. time: Time;
  2122. BEGIN
  2123. NEW(time);
  2124. cur := root;
  2125. grid.model.Acquire;
  2126. grid.model.SetNofRows(nofEntries + 1);
  2127. WHILE cur # NIL DO
  2128. INC(row);
  2129. Strings.IntToStr(row, tmp);
  2130. grid.model.SetCellData(0, row, cur);
  2131. grid.model.SetCellText(0, row, Strings.NewString(tmp));
  2132. grid.model.SetCellText(1, row, cur(AudioFile).title);
  2133. time.SetTime(cur(AudioFile).duration);
  2134. time.Format(tmp);
  2135. grid.model.SetCellText(2, row, Strings.NewString(tmp));
  2136. cur := cur.next;
  2137. END;
  2138. grid.model.Release;
  2139. END Refresh;
  2140. PROCEDURE Resized;
  2141. VAR
  2142. width: LONGINT;
  2143. BEGIN
  2144. Resized^();
  2145. width := bounds.GetWidth();
  2146. colWidths[0] := 20;
  2147. colWidths[1] := width - 100;
  2148. colWidths[2] := 80;
  2149. grid.SetColSpacings(colWidths);
  2150. END Resized;
  2151. PROCEDURE DragDroppedH(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo; VAR handled : BOOLEAN);
  2152. VAR
  2153. dropTarget: URLDropTarget;
  2154. BEGIN
  2155. NEW(dropTarget, SELF, NIL);
  2156. dragInfo.data := dropTarget;
  2157. ConfirmDrag(TRUE, dragInfo);
  2158. END DragDroppedH;
  2159. END AudioPanel;
  2160. DirectoryView* = OBJECT(WMTrees.TreeView);
  2161. VAR
  2162. tree : WMTrees.Tree;
  2163. curNode: WMTrees.TreeNode;
  2164. owner: DataPanel;
  2165. onPathChanged : WMEvents.EventSource;
  2166. onNodeRenamed : WMEvents.EventSource;
  2167. popup: WMPopups.Popup;
  2168. px, py: LONGINT;
  2169. PROCEDURE &Init*;
  2170. VAR
  2171. BEGIN
  2172. Init^;
  2173. NEW(onPathChanged, SELF, NIL, NIL, NIL);
  2174. events.Add(onPathChanged);
  2175. NEW(onNodeRenamed, SELF, NIL, NIL, NIL);
  2176. events.Add(onPathChanged);
  2177. tree := GetTree();
  2178. onSelectNode.Add(NodeSelected);
  2179. SetExtContextMenuHandler(ContextMenu);
  2180. END Init;
  2181. PROCEDURE AddDir(dir: Directory);
  2182. BEGIN
  2183. AddNode(curNode, dir);
  2184. END AddDir;
  2185. PROCEDURE AddNode(parent: WMTrees.TreeNode; dir: Directory);
  2186. VAR
  2187. tr: WMTrees.TreeNode;
  2188. cur: Directory;
  2189. BEGIN
  2190. tree.Acquire;
  2191. NEW(tr);
  2192. tree.SetNodeCaption(tr, dir.name);
  2193. tree.SetNodeData(tr, dir);
  2194. tree.InclNodeState(tr, WMTrees.NodeSubnodesUnknown);
  2195. tree.AddChildNode(parent, tr);
  2196. tree.Release;
  2197. cur := dir.subdir;
  2198. ExpandNode(tr);
  2199. WHILE cur # NIL DO
  2200. AddNode(tr, cur);
  2201. cur := cur.nextdir;
  2202. END;
  2203. END AddNode;
  2204. PROCEDURE SetSubDir(subdir: Directory);
  2205. BEGIN
  2206. curNode := GetTreeNode(subdir);
  2207. ExpandNode(curNode);
  2208. END SetSubDir;
  2209. PROCEDURE GetTreeNode(dir: Directory): WMTrees.TreeNode;
  2210. VAR
  2211. cur: WMTrees.TreeNode;
  2212. x: String;
  2213. BEGIN
  2214. (* dir must be a child of current node *)
  2215. tree.Acquire;
  2216. cur :=tree.GetChildren(curNode);
  2217. WHILE (cur # NIL) & (tree.GetNodeData(cur) # dir) DO
  2218. cur := tree.GetNextSibling(cur);
  2219. x := tree.GetNodeCaption(cur);
  2220. END;
  2221. tree.Release;
  2222. ASSERT (cur # NIL);
  2223. RETURN cur;
  2224. END GetTreeNode;
  2225. PROCEDURE RemoveDir(dir: Directory);
  2226. BEGIN
  2227. tree.Acquire;
  2228. tree.RemoveNode(GetTreeNode(dir));
  2229. tree.Release;
  2230. END RemoveDir;
  2231. PROCEDURE ContextMenu(sender: ANY; x, y: LONGINT);
  2232. VAR
  2233. node: WMTrees.TreeNode;
  2234. BEGIN
  2235. IF enabled.Get() THEN
  2236. NEW(popup);
  2237. tree.Acquire;
  2238. node := GetNodeAtPos(x, y);
  2239. IF node # NIL THEN
  2240. popup.AddParButton("Rename", Rename, node);
  2241. px := x; py := y;
  2242. ToWMCoordinates(x, y, px, py);
  2243. popup.Popup(px, py);
  2244. END;
  2245. tree.Release;
  2246. END;
  2247. END ContextMenu;
  2248. PROCEDURE Rename(sender, data : ANY);
  2249. VAR
  2250. rename : WMDialogs.MiniStringInput;
  2251. name : ARRAY 128 OF CHAR;
  2252. dir: Directory;
  2253. tr: WMTrees.TreeNode;
  2254. p: ANY;
  2255. BEGIN
  2256. IF ~sequencer.IsCallFromSequencer() THEN
  2257. sequencer.ScheduleEvent(SELF.Rename, sender, data);
  2258. ELSE
  2259. IF popup # NIL THEN popup.Close; popup := NIL END;
  2260. tree.Acquire;
  2261. tr := data(WMTrees.TreeNode);
  2262. p := tree.GetNodeData(tr);
  2263. dir := p(Directory);
  2264. NEW(rename);
  2265. COPY(dir.name^, name);
  2266. IF rename.Show(px, py, name) = WMDialogs.ResOk THEN
  2267. IF (name # dir.name^) & (Strings.Length(name) > 0) THEN
  2268. dir.name := Strings.NewString(name);
  2269. tree.SetNodeCaption(tr, dir.name);
  2270. onNodeRenamed.Call(dir);
  2271. END;
  2272. END;
  2273. tree.Release;
  2274. END;
  2275. END Rename;
  2276. PROCEDURE RenameNode(dir: Directory);
  2277. BEGIN
  2278. tree.Acquire;
  2279. tree.SetNodeCaption(GetTreeNode(dir), dir.name);
  2280. tree.Release;
  2281. END RenameNode;
  2282. PROCEDURE NodeSelected(sender, data : ANY);
  2283. VAR
  2284. tr: WMTrees.TreeNode;
  2285. p: ANY;
  2286. BEGIN
  2287. IF ~sequencer.IsCallFromSequencer() THEN
  2288. sequencer.ScheduleEvent(SELF.NodeSelected, sender, data);
  2289. ELSE
  2290. IF (data # NIL) & (data IS WMTrees.TreeNode) THEN
  2291. tr := data(WMTrees.TreeNode);
  2292. tree.Acquire;
  2293. p := tree.GetNodeData(tr);
  2294. curNode := tr; ExpandNode(tr);
  2295. onPathChanged.Call(p(Directory));
  2296. tree.Release
  2297. END;
  2298. END;
  2299. END NodeSelected;
  2300. PROCEDURE ExpandNode(tr: WMTrees.TreeNode);
  2301. BEGIN
  2302. tree.Acquire;
  2303. tree.SetNodeState(tr, {WMTrees.NodeExpanded});
  2304. tree.Release
  2305. END ExpandNode;
  2306. PROCEDURE DragDropped(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo);
  2307. VAR
  2308. dropTarget: URLDropTarget;
  2309. node : WMTrees.TreeNode;
  2310. p: ANY;
  2311. dir: Directory;
  2312. BEGIN
  2313. tree.Acquire;
  2314. node := GetNodeAtPos(x, y);
  2315. IF node # NIL THEN
  2316. p := tree.GetNodeData(node);
  2317. dir := p(Directory);
  2318. END;
  2319. NEW(dropTarget, owner, dir);
  2320. dragInfo.data := dropTarget;
  2321. ConfirmDrag(TRUE, dragInfo);
  2322. tree.Release;
  2323. END DragDropped;
  2324. PROCEDURE SetRoot(dir: Directory);
  2325. VAR
  2326. tr: WMTrees.TreeNode;
  2327. cur: Directory;
  2328. BEGIN
  2329. tree.Acquire;
  2330. NEW(tr);
  2331. curNode := tr;
  2332. tree.SetRoot(tr);
  2333. tree.SetNodeCaption(tr, dir.name);
  2334. tree.SetNodeData( tr, dir);
  2335. tree.InclNodeState(tr, WMTrees.NodeAlwaysExpanded);
  2336. tree.Release;
  2337. cur := dir.subdir;
  2338. WHILE cur # NIL DO
  2339. AddNode(tr, cur);
  2340. cur := cur.nextdir;
  2341. END;
  2342. END SetRoot;
  2343. END DirectoryView;
  2344. FileList* = OBJECT(WMComponents.VisualComponent)
  2345. VAR
  2346. owner: DataPanel;
  2347. grid : WMStringGrids.StringGrid;
  2348. curDir: Directory;
  2349. onPathChanged : WMEvents.EventSource;
  2350. onDeleteEntries : WMEvents.EventSource;
  2351. onNodeRenamed: WMEvents.EventSource;
  2352. onNodeCreated: WMEvents.EventSource;
  2353. popup: WMPopups.Popup;
  2354. px, py: LONGINT;
  2355. nofEntries: LONGINT;
  2356. PROCEDURE &Init*;
  2357. BEGIN
  2358. Init^;
  2359. NEW(onPathChanged, SELF, NIL, NIL, NIL);
  2360. events.Add(onPathChanged);
  2361. NEW(onDeleteEntries, SELF, NIL, NIL, NIL);
  2362. events.Add(onDeleteEntries);
  2363. NEW(onNodeRenamed, SELF, NIL, NIL, NIL);
  2364. events.Add(onNodeRenamed);
  2365. NEW(onNodeCreated, SELF, NIL, NIL, NIL);
  2366. events.Add(onNodeCreated);
  2367. NEW(grid);
  2368. grid.alignment.Set(WMComponents.AlignClient);
  2369. grid.onClickSelected.Add(ClickSelected);
  2370. grid.SetExtContextMenuHandler(ContextMenu);
  2371. AddContent(grid);
  2372. grid.model.Acquire;
  2373. grid.model.SetNofCols(1);
  2374. grid.model.SetNofRows(1);
  2375. grid.fixedRows.Set(1);
  2376. grid.model.SetCellText(0, 0, Strings.NewString("Name"));
  2377. grid.SetSelectionMode(WMGrids.GridSelectRows);
  2378. grid.model.Release;
  2379. grid.SetExtDragDroppedHandler(DragDroppedH);
  2380. END Init;
  2381. PROCEDURE ContextMenu(sender: ANY; x, y: LONGINT);
  2382. VAR
  2383. curSel: Selection;
  2384. w: SelectionWrapper;
  2385. BEGIN
  2386. IF enabled.Get() THEN
  2387. NEW(popup); NEW(w);
  2388. curSel := GetSelection();
  2389. w.sel := curSel;
  2390. popup.AddParButton("Create Direcotry", CreateDir, w);
  2391. IF curSel # NIL THEN
  2392. popup.AddParButton("Delete", Delete, w);
  2393. IF LEN(curSel) = 1 THEN
  2394. popup.AddParButton("Rename", Rename, curSel[0]);
  2395. END;
  2396. END;
  2397. px := x; py := y;
  2398. grid.ToWMCoordinates(x, y, px, py);
  2399. popup.Popup(px, py);
  2400. END;
  2401. END ContextMenu;
  2402. PROCEDURE Delete(sender, data: ANY);
  2403. BEGIN
  2404. IF ~sequencer.IsCallFromSequencer() THEN
  2405. sequencer.ScheduleEvent(SELF.Delete, sender, data);
  2406. ELSE
  2407. IF popup # NIL THEN popup.Close; popup := NIL END;
  2408. onDeleteEntries.Call(data);
  2409. END;
  2410. END Delete;
  2411. PROCEDURE CreateDir(sender, data: ANY);
  2412. VAR
  2413. dlg: WMDialogs.MiniStringInput;
  2414. name: ARRAY MaxLen OF CHAR;
  2415. dir: Directory;
  2416. BEGIN
  2417. IF ~sequencer.IsCallFromSequencer() THEN
  2418. sequencer.ScheduleEvent(SELF.CreateDir, sender, data);
  2419. ELSE
  2420. IF popup # NIL THEN popup.Close; popup := NIL END;
  2421. NEW(dlg);
  2422. NEW(dlg);
  2423. IF dlg.Show(px, py, name) = WMDialogs.ResOk THEN
  2424. IF Strings.Length(name) > 0 THEN
  2425. NEW(dir, curDir, Strings.NewString(name), NIL, curDir.depth+1);
  2426. onNodeCreated.Call(dir);
  2427. Refresh();
  2428. END;
  2429. END;
  2430. END;
  2431. END CreateDir;
  2432. PROCEDURE Rename(sender, data : ANY);
  2433. VAR
  2434. dlg : WMDialogs.MiniStringInput;
  2435. name : ARRAY MaxLen OF CHAR;
  2436. node: MakeIsoImages.Node;
  2437. BEGIN
  2438. IF ~sequencer.IsCallFromSequencer() THEN
  2439. sequencer.ScheduleEvent(SELF.Rename, sender, data);
  2440. ELSE
  2441. IF popup # NIL THEN popup.Close; popup := NIL END;
  2442. IF data # NIL THEN
  2443. node:= data(MakeIsoImages.Node);
  2444. NEW(dlg);
  2445. COPY(node.name^, name);
  2446. IF dlg.Show(px, py, name) = WMDialogs.ResOk THEN
  2447. IF (name # node.name^) & (Strings.Length(name) > 0) THEN
  2448. node.name := Strings.NewString(name);
  2449. onNodeRenamed.Call(node);
  2450. Refresh();
  2451. END;
  2452. END;
  2453. END;
  2454. END;
  2455. END Rename;
  2456. PROCEDURE GetSelection(): Selection;
  2457. VAR
  2458. selection: Selection;
  2459. l, t, r, b, i, j: LONGINT;
  2460. p: ANY;
  2461. BEGIN
  2462. IF nofEntries < 1 THEN RETURN NIL END;
  2463. grid.GetSelection(l, t, r, b);
  2464. grid.model.Acquire;
  2465. NEW(selection, b-t+1);
  2466. j := 0;
  2467. FOR i := t TO b DO
  2468. p := grid.model.GetCellData(0, i);
  2469. IF (p # NIL) & (p IS MakeIsoImages.Node) THEN
  2470. selection[j] := p;
  2471. INC(j);
  2472. END;
  2473. END;
  2474. grid.model.Release;
  2475. RETURN selection;
  2476. END GetSelection;
  2477. PROCEDURE SetCurrentDir(dir: Directory);
  2478. BEGIN
  2479. curDir := dir;
  2480. Refresh();
  2481. END SetCurrentDir;
  2482. PROCEDURE ClickSelected(sender, data : ANY);
  2483. BEGIN
  2484. IF ~sequencer.IsCallFromSequencer() THEN
  2485. sequencer.ScheduleEvent(SELF.ClickSelected, sender, data);
  2486. ELSE
  2487. IF (data # NIL) & (data IS Directory) THEN
  2488. SetCurrentDir(data(Directory));
  2489. onPathChanged.Call(data(Directory));
  2490. END;
  2491. END;
  2492. END ClickSelected;
  2493. PROCEDURE Refresh;
  2494. VAR
  2495. node: MakeIsoImages.Node;
  2496. row: LONGINT;
  2497. BEGIN
  2498. IF curDir # NIL THEN
  2499. grid.model.Acquire;
  2500. nofEntries := GetNofNodes(curDir);
  2501. grid.model.SetNofRows(nofEntries+1);
  2502. node := curDir.content;
  2503. WHILE node # NIL DO
  2504. INC(row);
  2505. IF node IS Directory THEN
  2506. grid.model.SetCellImage(0, row, WMGraphics.LoadImage("icons.tar://Folder.png", TRUE));
  2507. ELSE
  2508. grid.model.SetCellImage(0, row, NIL)
  2509. END;
  2510. grid.model.SetCellData(0, row, node);
  2511. grid.model.SetCellText(0, row, node.name);
  2512. node := node.next;
  2513. END;
  2514. grid.model.Release;
  2515. END;
  2516. END Refresh;
  2517. PROCEDURE GetNofNodes(dir: Directory): LONGINT;
  2518. VAR
  2519. cur: MakeIsoImages.Node;
  2520. nofNodes: LONGINT;
  2521. BEGIN
  2522. cur := dir.content;
  2523. WHILE cur # NIL DO
  2524. INC(nofNodes);
  2525. cur := cur.next;
  2526. END;
  2527. RETURN nofNodes;
  2528. END GetNofNodes;
  2529. PROCEDURE DragDroppedH(x, y : LONGINT; dragInfo : WMWindowManager.DragInfo; VAR handled : BOOLEAN);
  2530. VAR
  2531. dropTarget: URLDropTarget;
  2532. BEGIN
  2533. NEW(dropTarget, owner, curDir);
  2534. dragInfo.data := dropTarget;
  2535. ConfirmDrag(TRUE, dragInfo);
  2536. END DragDroppedH;
  2537. END FileList;
  2538. DataPanel = OBJECT(ProjectPanel);
  2539. VAR
  2540. dirView : DirectoryView;
  2541. list: FileList;
  2542. root: Directory;
  2543. sidePanel: WMStandardComponents.Panel;
  2544. PROCEDURE &New*(project: DataProject);
  2545. VAR
  2546. panel: WMStandardComponents.Panel;
  2547. resizer: WMStandardComponents.Resizer;
  2548. BEGIN
  2549. Init();
  2550. SELF.project := project;
  2551. NEW(panel);
  2552. panel.alignment.Set(WMComponents.AlignClient);
  2553. panel.fillColor.Set(White);
  2554. AddContent(panel);
  2555. NEW(sidePanel);
  2556. sidePanel.alignment.Set(WMComponents.AlignLeft);
  2557. sidePanel.bounds.SetWidth(200);
  2558. NEW(resizer);
  2559. resizer.alignment.Set(WMComponents.AlignRight);
  2560. resizer.bounds.SetWidth(4);
  2561. sidePanel.AddContent(resizer);
  2562. NEW(dirView); dirView.alignment.Set(WMComponents.AlignClient);
  2563. dirView.owner := SELF;
  2564. dirView.onPathChanged.Add(PathChanged);
  2565. dirView.onNodeRenamed.Add(NodeRenamed);
  2566. sidePanel.AddContent(dirView);
  2567. panel.AddContent(sidePanel);
  2568. NEW(list);
  2569. list.owner := SELF;
  2570. list.alignment.Set(WMComponents.AlignClient);
  2571. list.onPathChanged.Add(PathChanged);
  2572. list.onDeleteEntries.Add(DeleteEntries);
  2573. list.onNodeRenamed.Add(NodeRenamed);
  2574. list.onNodeCreated.Add(NodeCreated);
  2575. panel.AddContent(list);
  2576. IF project.root = NIL THEN
  2577. NEW(root, NIL, Strings.NewString("NEW"), NIL, 0);
  2578. root.parent := root;
  2579. project.root := root;
  2580. ELSE
  2581. root := project.root(Directory);
  2582. END;
  2583. dirView.SetRoot(root);
  2584. list.SetCurrentDir(root);
  2585. END New;
  2586. PROCEDURE NodeRenamed(sender, data: ANY);
  2587. BEGIN
  2588. IF sender IS DirectoryView THEN
  2589. list.Refresh();
  2590. ELSIF (sender IS FileList) & (data IS Directory) THEN
  2591. dirView.RenameNode(data(Directory));
  2592. END;
  2593. END NodeRenamed;
  2594. PROCEDURE NodeCreated(sender, data: ANY);
  2595. VAR
  2596. dir: Directory;
  2597. BEGIN
  2598. IF (sender IS FileList) THEN
  2599. dir := data(Directory);
  2600. Insert(dir.parent(Directory), dir);
  2601. END;
  2602. END NodeCreated;
  2603. PROCEDURE DeleteEntry(node: MakeIsoImages.Node);
  2604. VAR
  2605. w: SelectionWrapper;
  2606. sel: Selection;
  2607. BEGIN
  2608. NEW(sel, 1); sel[0] := node;
  2609. NEW(w); w.sel := sel;
  2610. DeleteEntries(SELF, w);
  2611. END DeleteEntry;
  2612. PROCEDURE DeleteEntries(sender, data: ANY);
  2613. VAR
  2614. cur, prev: MakeIsoImages.Node;
  2615. curDir, prevDir, dir: Directory;
  2616. i: LONGINT;
  2617. selection: Selection;
  2618. BEGIN
  2619. i := 0;
  2620. selection := data(SelectionWrapper).sel;
  2621. curDir := list.curDir;
  2622. cur := curDir.content;
  2623. WHILE (cur # NIL) & (i < LEN(selection)) DO
  2624. IF cur = selection[i] THEN
  2625. IF cur = curDir.content THEN
  2626. curDir.content := cur.next;
  2627. ELSE
  2628. prev.next := cur.next;
  2629. END;
  2630. INC(i);
  2631. RemoveNode(cur); (* update project size *)
  2632. owner.UpdateSize(project.totalSize, project(DataProject).overhead);
  2633. ELSE
  2634. prev := cur;
  2635. END;
  2636. cur := cur.next;
  2637. END;
  2638. list.Refresh();
  2639. (* directories *)
  2640. i := 0;
  2641. dir := curDir.subdir;
  2642. WHILE (dir # NIL) & (i < LEN(selection)) DO
  2643. IF dir = selection[i] THEN
  2644. IF curDir.subdir = selection[i] THEN
  2645. curDir.subdir := dir.nextdir;
  2646. ELSE
  2647. prevDir.nextdir := dir.nextdir;
  2648. END;
  2649. dirView.RemoveDir(dir(Directory));
  2650. INC(i);
  2651. END;
  2652. prevDir := dir;
  2653. dir := dir.nextdir;
  2654. END;
  2655. END DeleteEntries;
  2656. (* update overhead and size *)
  2657. PROCEDURE RemoveNode(node: MakeIsoImages.Node);
  2658. VAR
  2659. cur: MakeIsoImages.Node;
  2660. BEGIN
  2661. IF node IS Directory THEN
  2662. cur := node(Directory).content;
  2663. WHILE cur # NIL DO
  2664. RemoveNode(cur);
  2665. cur := cur.next;
  2666. END;
  2667. ELSE (* File *)
  2668. DEC(project.totalSize, node.size);
  2669. IF node(MakeIsoImages.File).prevSession THEN
  2670. INC(project(DataProject).overhead, node.size);
  2671. DEC(project(DataProject).oldSize, node.size);
  2672. END;
  2673. END;
  2674. END RemoveNode;
  2675. PROCEDURE PathChanged(sender, data: ANY);
  2676. BEGIN
  2677. IF (data # NIL) & (data IS Directory) THEN
  2678. IF sender IS DirectoryView THEN
  2679. list.SetCurrentDir(data(Directory));
  2680. ELSIF (data # NIL) & (sender IS FileList) THEN
  2681. dirView.SetSubDir(data(Directory));
  2682. END;
  2683. END;
  2684. END PathChanged;
  2685. PROCEDURE AddFile(CONST name: ARRAY OF CHAR; node: ANY);
  2686. VAR
  2687. file: Files.File;
  2688. parent, newDir: Directory;
  2689. newFile: MakeIsoImages.File;
  2690. path, filename: ARRAY MaxLen OF CHAR;
  2691. old: MakeIsoImages.Node;
  2692. BEGIN
  2693. file:= Files.Old(name);
  2694. IF (node # NIL) & (file # NIL) THEN
  2695. parent := node(Directory);
  2696. Files.SplitPath(name, path, filename);
  2697. old := GetNodeByName(parent, Strings.NewString(filename));
  2698. IF old # NIL THEN
  2699. IF WMDialogs.Confirmation("Confirm overwriting", filename) = WMDialogs.ResYes THEN
  2700. DeleteEntry(old);
  2701. ELSE
  2702. RETURN;
  2703. END;
  2704. END;
  2705. IF Files.Directory IN file.flags THEN
  2706. NEW(newDir, parent, Strings.NewString(filename), Strings.NewString(name), parent.depth+1);
  2707. Insert(parent, newDir);
  2708. list.Refresh();
  2709. ELSE
  2710. NEW(newFile, Strings.NewString(filename), Strings.NewString(name), file.Length());
  2711. INC(project.totalSize, newFile.size);
  2712. owner.UpdateSize(project.totalSize, project(DataProject).overhead);
  2713. Insert(parent, newFile);
  2714. list.Refresh();
  2715. END;
  2716. END;
  2717. END AddFile;
  2718. PROCEDURE Insert(parent: Directory; node: MakeIsoImages.Node);
  2719. VAR
  2720. cur: MakeIsoImages.Node;
  2721. dir: Directory;
  2722. BEGIN
  2723. (* always insert at the end of the list *)
  2724. IF parent.content = NIL THEN
  2725. parent.content := node;
  2726. ELSE
  2727. cur := parent.content;
  2728. WHILE cur.next # NIL DO
  2729. cur := cur.next;
  2730. END;
  2731. cur.next := node;
  2732. END;
  2733. IF node IS Directory THEN
  2734. IF parent.subdir = NIL THEN
  2735. parent.subdir := node(Directory);
  2736. ELSE
  2737. dir := parent.subdir(Directory);
  2738. WHILE dir.nextdir # NIL DO
  2739. dir := dir.nextdir(Directory);
  2740. END;
  2741. dir.nextdir := node(Directory);
  2742. END;
  2743. BuildDir(node(Directory));
  2744. dirView.AddDir(node(Directory));
  2745. END;
  2746. END Insert;
  2747. PROCEDURE GetNodeByName(parent: Directory; name: String): MakeIsoImages.Node;
  2748. VAR
  2749. cur: MakeIsoImages.Node;
  2750. BEGIN
  2751. cur := parent.content;
  2752. WHILE cur # NIL DO
  2753. IF cur.name^ = name^ THEN
  2754. RETURN cur;
  2755. END;
  2756. cur := cur.next;
  2757. END;
  2758. RETURN NIL;
  2759. END GetNodeByName;
  2760. PROCEDURE BuildDir(dir: Directory);
  2761. VAR
  2762. enumerator: Files.Enumerator;
  2763. name, filename, path, mask: ARRAY MaxLen OF CHAR;
  2764. time, date, size: LONGINT;
  2765. flags: SET;
  2766. newDir, curDir : Directory;
  2767. newFile : MakeIsoImages.File;
  2768. cur, tmp : MakeIsoImages.Node;
  2769. BEGIN
  2770. NEW(enumerator);
  2771. IF dir.fullpath = NIL THEN RETURN END;
  2772. COPY(dir.fullpath^, mask);
  2773. Strings.Append(mask, "/*");
  2774. enumerator.Open(mask, {Files.EnumSize});
  2775. WHILE enumerator.HasMoreEntries() DO
  2776. IF enumerator.GetEntry(name, flags, time, date, size) THEN
  2777. Files.SplitPath(name, path, filename);
  2778. IF Files.Directory IN flags THEN
  2779. NEW(newDir, dir, Strings.NewString(filename), Strings.NewString(name), dir.depth+1);
  2780. BuildDir(newDir);
  2781. IF dir.subdir = NIL THEN
  2782. dir.subdir := newDir;
  2783. ELSE
  2784. curDir.nextdir := newDir;
  2785. END;
  2786. curDir := newDir;
  2787. tmp := newDir;
  2788. ELSE
  2789. NEW(newFile, Strings.NewString(filename), Strings.NewString(name), size);
  2790. INC(project.totalSize, size);
  2791. owner.UpdateSize(project.totalSize, project(DataProject).overhead);
  2792. tmp := newFile;
  2793. END;
  2794. IF dir.content = NIL THEN
  2795. dir.content := tmp;
  2796. ELSE
  2797. cur.next := tmp;
  2798. END;
  2799. cur := tmp;
  2800. END;
  2801. END;
  2802. END BuildDir;
  2803. END DataPanel;
  2804. Time = OBJECT
  2805. VAR
  2806. sec, min, hour: LONGINT;
  2807. PROCEDURE SetTime(seconds: LONGINT);
  2808. VAR
  2809. rem: LONGINT;
  2810. BEGIN
  2811. rem := seconds;
  2812. sec := rem MOD 60; rem := rem DIV 60;
  2813. min := rem MOD 60; rem := rem DIV 60;
  2814. hour := rem MOD 24;
  2815. END SetTime;
  2816. PROCEDURE Format(VAR str: ARRAY OF CHAR);
  2817. VAR
  2818. tmp: ARRAY MaxLen OF CHAR;
  2819. BEGIN
  2820. str := "";
  2821. IF hour < 10 THEN str := "0" END;
  2822. Strings.IntToStr(hour, tmp); Strings.Append(str, tmp); Strings.Append(str, ":");
  2823. IF min < 10 THEN Strings.Append(str, "0") END;
  2824. Strings.IntToStr(min, tmp); Strings.Append(str, tmp); Strings.Append(str, ":");
  2825. IF sec < 10 THEN Strings.Append(str, "0") END;
  2826. Strings.IntToStr(sec, tmp); Strings.Append(str, tmp);
  2827. END Format;
  2828. END Time;
  2829. RunProc = PROCEDURE{DELEGATE} (sender, data: ANY);
  2830. Handler = OBJECT
  2831. VAR
  2832. data: ANY;
  2833. proc: RunProc;
  2834. PROCEDURE &New*(proc: RunProc; data: ANY);
  2835. BEGIN
  2836. SELF.proc := proc;
  2837. SELF.data := data;
  2838. END New;
  2839. BEGIN {ACTIVE}
  2840. proc(SELF, data);
  2841. END Handler;
  2842. Timer = OBJECT(WMStandardComponents.Timer);
  2843. VAR
  2844. start: LONGINT;
  2845. onUpdate*: WMEvents.EventSource;
  2846. time: Time;
  2847. PROCEDURE &Init*;
  2848. BEGIN
  2849. Init^();
  2850. NEW(onUpdate, SELF, NIL, NIL, NIL);
  2851. NEW(time);
  2852. onTimer.Add(UpdateHandler);
  2853. END Init;
  2854. PROCEDURE UpdateHandler(sender, date: ANY);
  2855. VAR
  2856. diff: LONGINT;
  2857. BEGIN
  2858. diff := (Kernel.GetTicks () - start) DIV 1000;
  2859. time.SetTime(diff);
  2860. onUpdate.Call(time);
  2861. END UpdateHandler;
  2862. PROCEDURE Start(sender, data: ANY);
  2863. BEGIN
  2864. start := Kernel.GetTicks ();
  2865. Start^(sender, data);
  2866. END Start;
  2867. END Timer;
  2868. VAR
  2869. nofWindows: LONGINT;
  2870. recorders: ARRAY CDRecord.MaxRecorders OF CDRecord.CDRecorder;
  2871. (* returns true if the hd on which a source file is located is on the same controller as the recorder *)
  2872. PROCEDURE CheckController(compilation: CDRecord.Compilation; recorder: CDRecord.CDRecorder; VAR name: ARRAY OF CHAR): BOOLEAN;
  2873. VAR
  2874. i: LONGINT;
  2875. track: CDRecord.InformationTrack;
  2876. device: Disks.Device;
  2877. BEGIN
  2878. FOR i := 0 TO compilation.nofTracks-1 DO
  2879. IF (compilation.tracks[i] # NIL) & (compilation.tracks[i] IS CDRecord.InformationTrack) THEN
  2880. track := compilation.tracks[i](CDRecord.InformationTrack);
  2881. IF (Utils.GetDevice(track.file, device) = ResOk) & Utils.IsOnSameController(device, recorder.dev) THEN
  2882. COPY(device.name, name);
  2883. RETURN TRUE;
  2884. END;
  2885. END;
  2886. END;
  2887. RETURN FALSE;
  2888. END CheckController;
  2889. PROCEDURE FileExists(CONST filename: ARRAY OF CHAR): BOOLEAN;
  2890. BEGIN
  2891. RETURN Files.Old(filename) # NIL;
  2892. END FileExists;
  2893. PROCEDURE GetFileSize(CONST filename: ARRAY OF CHAR): LONGINT;
  2894. VAR
  2895. file: Files.File;
  2896. BEGIN
  2897. file := Files.Old(filename);
  2898. RETURN file.Length();
  2899. END GetFileSize;
  2900. PROCEDURE RemoveSpecialChars(VAR str: ARRAY OF CHAR);
  2901. VAR
  2902. i, j: LONGINT;
  2903. BEGIN
  2904. j := 0;
  2905. FOR i := 0 TO LEN(str) - 1 DO
  2906. IF ORD(str[i]) > 31 THEN
  2907. str[j] := str[i]; INC(j);
  2908. END;
  2909. END;
  2910. str[j] := 0X;
  2911. END RemoveSpecialChars;
  2912. PROCEDURE IncCount;
  2913. BEGIN {EXCLUSIVE}
  2914. INC(nofWindows);
  2915. END IncCount;
  2916. PROCEDURE DecCount;
  2917. BEGIN {EXCLUSIVE}
  2918. DEC(nofWindows);
  2919. END DecCount;
  2920. PROCEDURE Cleanup;
  2921. VAR
  2922. die: KillerMsg;
  2923. msg: WMMessages.Message;
  2924. m: WMWindowManager.WindowManager;
  2925. BEGIN {EXCLUSIVE}
  2926. NEW(die); msg.ext := die; msg.msgType := WMMessages.MsgExt;
  2927. m := WMWindowManager.GetDefaultManager();
  2928. m.Broadcast(msg);
  2929. AWAIT(nofWindows = 0);
  2930. END Cleanup;
  2931. PROCEDURE Open*;
  2932. VAR
  2933. wnd: Window;
  2934. BEGIN
  2935. NEW(wnd);
  2936. END Open;
  2937. BEGIN
  2938. Modules.InstallTermHandler(Cleanup);
  2939. END WMCDRecorder.
  2940. WMCDRecorder.Open~