WMPartitions.Mod 119 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089
  1. MODULE WMPartitions; (** AUTHOR "staubesv"; PURPOSE "Partition Tool"; *)
  2. IMPORT
  3. Streams, Modules, Commands, Strings, Disks, Files, Texts, TextUtilities, Codecs,
  4. PartitionsLib, DiskVolumes, OldDiskVolumes, FATVolumes, ISO9660Volumes, FATScavenger, DiskBenchmark, DiskTests, Installer,
  5. WMRectangles, WMGraphics, WMMessages, WMRestorable, WMWindowManager, WMProperties, WMDialogs,
  6. WMComponents, WMStandardComponents, WMTextView, WMEditors, WMGrids, WMTabComponents, WMPartitionsComponents;
  7. CONST
  8. (* Return values of PopupWindow.Popup() *)
  9. ResNone = 0;
  10. ResOk = 1;
  11. ResCancel = 2;
  12. (* Parameter types for Parameter.type field *)
  13. ParInteger = 0;
  14. ParString = 1;
  15. ParBoolean = 2;
  16. (* Return values of Plugin.SelectionUpdated *)
  17. SelectionValid = 1; (** selected partition seems to be of the exspected type *)
  18. SelectionInvalid = 2; (** plugin will do nothing when user tries to apply it *)
  19. SelectionMaybe = 3; (** plugin can't determine whether its application will be successful *)
  20. SelectionNotSupported = 0; (** plugin doesn't care about this return value *)
  21. (* Default window size at startup *)
  22. DefaultWidth = 700; DefaultHeight = 400;
  23. (* If the window is smaller than this size, scale it *)
  24. WindowMinWidth = 350; WindowMinHeight = 350;
  25. NofTabs = 6;
  26. BackgroundColor = 0444444FFH;
  27. MarginH = 5 ;
  28. MarginV = 5 ;
  29. MarginColor = 0444444FFH;
  30. ButtonHeight = 20;
  31. ButtonWidth = 80;
  32. ButtonSpacer = 2;
  33. StatusBarHeight = 20;
  34. StatusBarBgColor = WMGraphics.Blue;
  35. (* Pending operation plugin constants *)
  36. RemoveSelected = 0;
  37. RemoveFinished = 1;
  38. RemoveAll = 2;
  39. (* Prefix for automatically generated mount prefixes. *)
  40. DefaultPrefix = "Auto";
  41. (* FAT file systems only: default size of cache in KB (as string) *)
  42. DefaultFatCacheSize = "2048";
  43. (* Config editor constants *)
  44. CeLabelHeight = 20;
  45. CeOpPanelHeight = ButtonHeight + 2*MarginV;
  46. CeKeyWidth = 100;
  47. CeEditPanelHeight = 3*ButtonHeight + 2*MarginV + 2*ButtonSpacer;
  48. CeCellHeightMinSpacer = 2;
  49. ToFile = 0;
  50. ToPartition = 1;
  51. UseSkinColors = FALSE;
  52. TYPE
  53. Plugin = OBJECT(WMComponents.VisualComponent);
  54. VAR
  55. (** Usage: owner.UpdateStatusLabel(string : Strings.String) updates the main window status bar *)
  56. owner : Window;
  57. selection : WMPartitionsComponents.Selection;
  58. (** This procedure is called everytime when the selection has been updated *)
  59. (** Return values: SelectionValid, SelectionInvalid, SelectionMaybe or SelectionNotSupported *)
  60. PROCEDURE SelectionUpdated(selection : WMPartitionsComponents.Selection) : LONGINT; (* abstract *)
  61. END SelectionUpdated;
  62. (** Returns TRUE if the selection is valid *)
  63. PROCEDURE IsValid(selection : WMPartitionsComponents.Selection) : BOOLEAN;
  64. BEGIN
  65. RETURN (selection.disk.device # NIL) & (selection.partition >= 0) & (selection.disk.table # NIL) & (selection.partition < LEN(selection.disk.table));
  66. END IsValid;
  67. END Plugin;
  68. TYPE
  69. (*
  70. * The File System Tools (FSTools) is basically a graphical front-end for the operations provided by FSTools.Mod.
  71. * It can be used to mount / unmount volumes and display a overview (free/total memory) of volumes. If the file system type
  72. * of the selected partition is recognize, the plugin will automatically set the correct parameters for the mount command, including
  73. * a generate mount prefix.
  74. *)
  75. FSToolsPlugin = OBJECT(Plugin);
  76. VAR
  77. (* mount command *)
  78. mount : WMStandardComponents.Button;
  79. prefixEditor, fsEditor : WMEditors.Editor;
  80. mountPanel : WMStandardComponents.Panel;
  81. (* FatFS specific settings - will only be visible if selected partition contains FAT volume*)
  82. forceRWlabel, enableWBlabel, cacheSizeLabel : WMStandardComponents.Label;
  83. forceRW, enableWB : WMStandardComponents.Button;
  84. cacheSizeEditor : WMEditors.Editor;
  85. parForceRW, parEnableWB : BOOLEAN;
  86. (* unmount command *)
  87. unmount, force : WMStandardComponents.Button;
  88. parForce : BOOLEAN;
  89. (* disk info panel *)
  90. info : WMStandardComponents.Label;
  91. prefixUsed : ARRAY 128 OF BOOLEAN; (* used by GenPrefix() *)
  92. PROCEDURE &Init*;
  93. VAR label : WMStandardComponents.Label; spacer : WMStandardComponents.Panel;
  94. BEGIN
  95. Init^;
  96. NEW(mount);
  97. mount.bounds.SetExtents(ButtonWidth, ButtonHeight); mount.bounds.SetLeft(0); mount.bounds.SetTop(0);
  98. mount.onClick.Add(Mount); mount.SetCaption("Mount");
  99. AddInternalComponent(mount);
  100. NEW(mountPanel);
  101. mountPanel.bounds.SetLeft(ButtonWidth + ButtonHeight + 2*ButtonSpacer +40); mountPanel.bounds.SetTop(0);
  102. AddInternalComponent(mountPanel);
  103. NEW(label);
  104. label.bounds.SetWidth(32); label.bounds.SetHeight(ButtonHeight); label.alignment.Set(WMComponents.AlignLeft);
  105. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  106. label.caption.Set(Strings.NewString("Prefix"));
  107. mountPanel.AddInternalComponent(label);
  108. NEW(prefixEditor);
  109. prefixEditor.bounds.SetWidth(40); prefixEditor.bounds.SetHeight(ButtonHeight); prefixEditor.alignment.Set(WMComponents.AlignLeft);
  110. prefixEditor.multiLine.Set(FALSE);
  111. prefixEditor.tv.textAlignV.Set(WMGraphics.AlignCenter);
  112. IF ~UseSkinColors THEN prefixEditor.fillColor.Set(WMGraphics.White); END;
  113. prefixEditor.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1)); prefixEditor.tv.showBorder.Set(TRUE);
  114. mountPanel.AddInternalComponent(prefixEditor);
  115. NEW(label);
  116. label.bounds.SetWidth(64); label.bounds.SetHeight(ButtonHeight); label.alignment.Set(WMComponents.AlignLeft);
  117. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  118. label.caption.Set(Strings.NewString(" FileSystem"));
  119. mountPanel.AddInternalComponent(label);
  120. NEW(fsEditor);
  121. fsEditor.bounds.SetWidth(60); fsEditor.bounds.SetHeight(20); fsEditor.alignment.Set(WMComponents.AlignLeft);
  122. fsEditor.multiLine.Set(FALSE);
  123. fsEditor.tv.textAlignV.Set(WMGraphics.AlignCenter);
  124. IF ~UseSkinColors THEN fsEditor.fillColor.Set(WMGraphics.White); END;
  125. fsEditor.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1)); fsEditor.tv.showBorder.Set(TRUE);
  126. mountPanel.AddInternalComponent(fsEditor);
  127. NEW(spacer); spacer.bounds.SetWidth(2*ButtonSpacer); spacer.alignment.Set(WMComponents.AlignLeft);
  128. mountPanel.AddInternalComponent(spacer);
  129. NEW(cacheSizeLabel);
  130. cacheSizeLabel.bounds.SetWidth(83); cacheSizeLabel.bounds.SetHeight(ButtonHeight); cacheSizeLabel.alignment.Set(WMComponents.AlignLeft);
  131. IF ~UseSkinColors THEN cacheSizeLabel.fillColor.Set(BackgroundColor); cacheSizeLabel.textColor.Set(WMGraphics.White); END;
  132. cacheSizeLabel.caption.Set(Strings.NewString("CacheSize (KB)")); cacheSizeLabel.visible.Set(FALSE);
  133. mountPanel.AddInternalComponent(cacheSizeLabel);
  134. NEW(cacheSizeEditor);
  135. cacheSizeEditor.bounds.SetWidth(40); cacheSizeEditor.bounds.SetHeight(ButtonHeight); cacheSizeEditor.alignment.Set(WMComponents.AlignLeft);
  136. cacheSizeEditor.multiLine.Set(FALSE);
  137. cacheSizeEditor.tv.textAlignV.Set(WMGraphics.AlignCenter);
  138. IF ~UseSkinColors THEN cacheSizeEditor.fillColor.Set(WMGraphics.White); END;
  139. cacheSizeEditor.SetAsString(DefaultFatCacheSize);
  140. cacheSizeEditor.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1)); cacheSizeEditor.tv.showBorder.Set(TRUE); cacheSizeEditor.visible.Set(FALSE);
  141. mountPanel.AddInternalComponent(cacheSizeEditor);
  142. NEW(spacer); spacer.bounds.SetWidth(2*ButtonSpacer); spacer.alignment.Set(WMComponents.AlignLeft);
  143. mountPanel.AddInternalComponent(spacer);
  144. NEW(enableWB);
  145. enableWB.bounds.SetExtents(ButtonHeight, ButtonHeight); enableWB.alignment.Set(WMComponents.AlignLeft);
  146. enableWB.bounds.SetLeft(ButtonWidth + ButtonSpacer); enableWB.bounds.SetTop(ButtonHeight + ButtonSpacer);
  147. enableWB.onClick.Add(EnableWB); enableWB.SetCaption(""); enableWB.visible.Set(FALSE);
  148. mountPanel.AddInternalComponent(enableWB);
  149. NEW(enableWBlabel);
  150. enableWBlabel.bounds.SetWidth(70); enableWBlabel.bounds.SetHeight(ButtonHeight); enableWBlabel.alignment.Set(WMComponents.AlignLeft);
  151. IF ~UseSkinColors THEN enableWBlabel.fillColor.Set(BackgroundColor); enableWBlabel.textColor.Set(WMGraphics.White); END;
  152. enableWBlabel.caption.SetAOC(" Writeback"); enableWBlabel.visible.Set(FALSE);
  153. mountPanel.AddInternalComponent(enableWBlabel);
  154. NEW(forceRW);
  155. forceRW.bounds.SetExtents(ButtonHeight, ButtonHeight); forceRW.alignment.Set(WMComponents.AlignLeft);
  156. forceRW.bounds.SetLeft(ButtonWidth + ButtonSpacer); forceRW.bounds.SetTop(ButtonHeight + ButtonSpacer);
  157. forceRW.onClick.Add(ForceRW); forceRW.SetCaption(""); forceRW.visible.Set(FALSE);
  158. mountPanel.AddInternalComponent(forceRW);
  159. NEW(forceRWlabel);
  160. forceRWlabel.bounds.SetWidth(160); forceRWlabel.bounds.SetHeight(ButtonHeight); forceRWlabel.alignment.Set(WMComponents.AlignLeft);
  161. IF ~UseSkinColors THEN forceRWlabel.fillColor.Set(BackgroundColor); forceRWlabel.textColor.Set(WMGraphics.White); END;
  162. forceRWlabel.caption.Set(Strings.NewString(" Force R/W"));
  163. forceRWlabel.visible.Set(FALSE);
  164. mountPanel.AddInternalComponent(forceRWlabel);
  165. NEW(unmount);
  166. unmount.bounds.SetExtents(ButtonWidth, ButtonHeight);
  167. unmount.bounds.SetLeft(0); unmount.bounds.SetTop(ButtonHeight + ButtonSpacer);
  168. unmount.onClick.Add(Unmount); unmount.SetCaption("Unmount");
  169. AddInternalComponent(unmount);
  170. NEW(force);
  171. force.bounds.SetExtents(ButtonHeight, ButtonHeight);
  172. force.bounds.SetLeft(ButtonWidth + ButtonSpacer); force.bounds.SetTop(ButtonHeight + ButtonSpacer);
  173. force.onClick.Add(Force); force.SetCaption("");
  174. AddInternalComponent(force);
  175. NEW(label);
  176. label.bounds.SetExtents(40, ButtonHeight);
  177. label.bounds.SetLeft(ButtonWidth + ButtonHeight + 2*ButtonSpacer); label.bounds.SetTop(ButtonHeight + ButtonSpacer);
  178. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  179. label.caption.Set(Strings.NewString("Force"));
  180. AddInternalComponent(label);
  181. NEW(info);
  182. info.bounds.SetLeft(ButtonWidth + ButtonHeight + 2*ButtonSpacer + 40); info.bounds.SetTop(ButtonHeight + ButtonSpacer);
  183. IF ~UseSkinColors THEN info.fillColor.Set(BackgroundColor); info.textColor.Set(WMGraphics.White); END;
  184. info.caption.Set(Strings.NewString("File System Info: n/a"));
  185. AddInternalComponent(info);
  186. END Init;
  187. PROCEDURE Initialize*;
  188. BEGIN
  189. Initialize^;
  190. mountPanel.bounds.SetExtents(bounds.GetWidth(), ButtonHeight);
  191. info.bounds.SetExtents(bounds.GetWidth(), ButtonHeight);
  192. END Initialize;
  193. PROCEDURE Resized*;
  194. BEGIN
  195. Resized^;
  196. mountPanel.bounds.SetExtents(bounds.GetWidth(), ButtonHeight);
  197. info.bounds.SetExtents(bounds.GetWidth(), ButtonHeight);
  198. END Resized;
  199. PROCEDURE SelectionUpdated(selection: WMPartitionsComponents.Selection): LONGINT;
  200. VAR
  201. caption, temp : ARRAY 128 OF CHAR;
  202. fs : Files.FileSystem;
  203. fstype : LONGINT;
  204. doClose : BOOLEAN;
  205. result : LONGINT; res : WORD;
  206. BEGIN
  207. SELF.selection := selection;
  208. IF IsValid(selection) THEN
  209. fstype := 0; (* invalid *)
  210. IF (selection.disk.isDiskette) & (selection.disk.res = Disks.Ok) THEN
  211. (* special case: floppy disk *)
  212. doClose := FALSE;
  213. IF (selection.disk.device.openCount < 1) THEN
  214. doClose := TRUE;
  215. selection.disk.device.Open(res); (* ignore res *)
  216. END;
  217. IF PartitionsLib.DisketteInserted(selection.disk.device) THEN
  218. fstype := PartitionsLib.DetectFS(selection.disk.device, selection.partition);
  219. END;
  220. ELSE
  221. fstype := DetectFS(selection.disk.device, selection.partition);
  222. END;
  223. temp := "";
  224. CASE fstype OF
  225. |PartitionsLib.UnknownFS: result := SelectionInvalid;
  226. |PartitionsLib.NativeFS: temp := "NatFS"; result := SelectionValid;
  227. |PartitionsLib.OldAosFS32: temp := "OldAosFS"; result := SelectionValid;
  228. |PartitionsLib.AosFS32: temp := "OldAosFS"; result := SelectionValid;
  229. |PartitionsLib.FatFS: temp := "FatFS"; result := SelectionValid;
  230. |PartitionsLib.AosFS128: temp := "AosFS"; result := SelectionValid;
  231. END;
  232. IF (selection.disk.isDiskette) & doClose & (selection.disk.device.openCount > 0) THEN
  233. selection.disk.device.Close(res); (* ignore res *)
  234. END;
  235. (* If device is not partitioned, assume CDROM or floppy drive *)
  236. IF ((result = SelectionInvalid) & (LEN(selection.disk.table) = 1)) THEN
  237. result := SelectionMaybe;
  238. temp := "IsoFS";
  239. END;
  240. IF fstype = PartitionsLib.FatFS THEN (* FatFS specific settings *)
  241. parForceRW := FALSE; forceRW.caption.SetAOC("");
  242. IF Strings.Match("USB*", selection.disk.device.name) THEN (* enable wb caching for USB devices *)
  243. parEnableWB := TRUE; enableWB.caption.SetAOC("X");
  244. ELSE
  245. parEnableWB := FALSE; enableWB.caption.SetAOC("");
  246. END;
  247. forceRWlabel.visible.Set(TRUE); forceRW.visible.Set(TRUE);
  248. cacheSizeEditor.visible.Set(TRUE); cacheSizeLabel.visible.Set(TRUE);
  249. enableWB.visible.Set(TRUE); enableWBlabel.visible.Set(TRUE);
  250. ELSE
  251. forceRWlabel.visible.Set(FALSE); forceRW.visible.Set(FALSE);
  252. cacheSizeEditor.visible.Set(FALSE); cacheSizeLabel.visible.Set(FALSE);
  253. enableWB.visible.Set(FALSE); enableWBlabel.visible.Set(FALSE);
  254. END;
  255. fsEditor.SetAsString(temp); (* file system *)
  256. prefixEditor.SetAsString(GenPrefix());
  257. IF (selection.disk.fs # NIL) & (selection.partition <LEN(selection.disk.fs)) & (selection.disk.fs[selection.partition] # NIL) THEN (* we have a reference to the FS *)
  258. fs := selection.disk.fs[selection.partition];
  259. caption := "File System Info: "; Strings.Append(caption, fs.prefix); Strings.Append(caption, ": ");
  260. Strings.Append(caption, fs.desc); Strings.Append(caption, " on ");
  261. Strings.Append(caption, selection.disk.device.name);
  262. Strings.Append(caption, "#"); Strings.IntToStr(selection.partition, temp); Strings.Append(caption, temp);
  263. IF fs.vol # NIL THEN
  264. IF Files.ReadOnly IN fs.vol.flags THEN Strings.Append(caption, " (read-only)") END;
  265. IF Files.Removable IN fs.vol.flags THEN Strings.Append(caption, " (removable)") END;
  266. IF Files.Boot IN fs.vol.flags THEN Strings.Append(caption, " (boot)") END;
  267. Strings.Append(caption, ", ");
  268. WriteK(ENTIER(fs.vol.Available()/1024.0D0 * fs.vol.blockSize), caption); Strings.Append(caption, " of ");
  269. WriteK(ENTIER(fs.vol.size/1024.0D0 * fs.vol.blockSize), caption); Strings.Append(caption, " free");
  270. END;
  271. info.caption.Set(Strings.NewString(caption));
  272. ELSE
  273. info.caption.Set(Strings.NewString(" File System Info: n/a"));
  274. END;
  275. ELSE
  276. result := SelectionInvalid;
  277. END;
  278. RETURN result;
  279. END SelectionUpdated;
  280. (* TBD *)
  281. PROCEDURE WriteK(k: LONGINT; VAR string : ARRAY OF CHAR);
  282. VAR suffix: ARRAY 3 OF CHAR; temp : ARRAY 32 OF CHAR;
  283. BEGIN
  284. IF k < 10*1024 THEN COPY("Ki", suffix)
  285. ELSIF k < 10*1024*1024 THEN COPY("Mi", suffix); k := k DIV 1024
  286. ELSE COPY("Gi", suffix); k := k DIV (1024*1024)
  287. END;
  288. Strings.IntToStr(k , temp); Strings.Append(string, temp); Strings.Append(string, suffix); Strings.Append(string, "B");
  289. END WriteK;
  290. (* Generate a mount prefix by appending a number to the string represented by the constant DefaultPrefix. *)
  291. PROCEDURE GenPrefix() : Files.Prefix;
  292. VAR prefix : Files.Prefix; temp : ARRAY 12 OF CHAR; i : LONGINT;
  293. BEGIN {EXCLUSIVE}
  294. WHILE prefixUsed[i] & (i < LEN(prefixUsed)-1) DO INC(i); END;
  295. ASSERT(i < LEN(prefixUsed));
  296. prefix := ""; Strings.Append(prefix, DefaultPrefix); Strings.IntToStr(i, temp); Strings.Append(prefix, temp);
  297. RETURN prefix;
  298. END GenPrefix;
  299. PROCEDURE SetPrefixUsed(CONST prefix : ARRAY OF CHAR);
  300. VAR nbr : LONGINT;
  301. BEGIN (* will not be concurrently called with GenPrefix *)
  302. nbr := GetPrefixNbr(prefix);
  303. IF nbr#-1 THEN prefixUsed[nbr] := TRUE; END;
  304. END SetPrefixUsed;
  305. PROCEDURE GetPrefixNbr(CONST iprefix : ARRAY OF CHAR) : LONGINT;
  306. VAR
  307. match : BOOLEAN;
  308. temp : ARRAY 32 OF CHAR;
  309. default, prefix : Strings.String;
  310. i, j, result : LONGINT;
  311. BEGIN
  312. prefix := Strings.NewString(iprefix);
  313. default := Strings.NewString(DefaultPrefix);
  314. result := -1; (* invalid *)
  315. IF LEN(prefix) > LEN(default) THEN
  316. match := TRUE;
  317. FOR i := 0 TO LEN(default)-2 (* ignore 0X *) DO
  318. IF prefix[i]#default[i] THEN match := FALSE; END;
  319. END;
  320. IF match THEN
  321. temp := ""; j := 0; i := LEN(default)-1;
  322. WHILE i < LEN(prefix) DO temp[j] := prefix[i]; INC(j); INC(i); END;
  323. Strings.StrToInt(temp, result);
  324. IF (result < 0) OR (result >= LEN(prefixUsed)) THEN result := -1; END;
  325. END;
  326. END;
  327. RETURN result;
  328. END GetPrefixNbr;
  329. (* Appends FatFS specific parameters to command string *)
  330. PROCEDURE GetFATspecific(VAR volPar : ARRAY OF CHAR);
  331. VAR string : ARRAY 128 OF CHAR; cachesize : LONGINT;
  332. BEGIN
  333. volPar := "";
  334. IF parForceRW THEN Strings.Append(volPar, " ,X"); END;
  335. cacheSizeEditor.GetAsString(string); Strings.StrToInt(string, cachesize);
  336. IF (cachesize > 0) THEN
  337. cachesize := (1024 * cachesize) DIV PartitionsLib.BS; (* cachesize in 512B blocks *)
  338. IF parEnableWB THEN cachesize := -cachesize; END;
  339. Strings.IntToStr(cachesize, string);
  340. Strings.Append(volPar, ",C:"); Strings.Append(volPar, string);
  341. END;
  342. END GetFATspecific;
  343. (** prefix [hashSize] [cachesize] alias [volpar] ["|" fspar] ~ *)
  344. PROCEDURE Mount(sender, data : ANY);
  345. VAR
  346. mount : PartitionsLib.Mount;
  347. prefix, alias, volPar, fsPar : ARRAY 128 OF CHAR;
  348. BEGIN
  349. IF IsValid(selection) THEN
  350. IF selection.disk.table[selection.partition].flags * {Disks.Mounted} = {} THEN
  351. (** cmd: prefix [hashSize] [cachesize] alias [volpar] ["|" fspar] ~ *)
  352. prefixEditor.GetAsString(prefix);
  353. IF (prefix # "") THEN
  354. fsEditor.GetAsString(alias);
  355. IF (alias # "") THEN
  356. GetFATspecific(volPar); fsPar := "";
  357. SetPrefixUsed(prefix);
  358. NEW(mount, selection.disk, selection.partition, NIL);
  359. mount.SetParameters(prefix, alias, volPar, fsPar);
  360. mount.SetStart;
  361. ELSE owner.UpdateStatusLabel(Strings.NewString("No file system alies specified"));
  362. END;
  363. ELSE owner.UpdateStatusLabel(Strings.NewString("No prefix specified"));
  364. END;
  365. ELSE owner.UpdateStatusLabel(Strings.NewString("Volume is already mounted"));
  366. END;
  367. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection not valid"));
  368. END;
  369. END Mount;
  370. (* Force parameter of the unmount command *)
  371. PROCEDURE Force(sender, data : ANY);
  372. BEGIN
  373. IF parForce THEN parForce := FALSE; force.caption.Set(Strings.NewString(""));
  374. ELSE parForce := TRUE; force.caption.Set(Strings.NewString("X"));
  375. END;
  376. END Force;
  377. (* FatFS only: Force R/W mountng *)
  378. PROCEDURE ForceRW(sender, data : ANY);
  379. BEGIN
  380. IF parForceRW THEN parForceRW := FALSE; forceRW.caption.Set(Strings.NewString(""));
  381. ELSE parForceRW := TRUE; forceRW.caption.Set(Strings.NewString("X"));
  382. END;
  383. END ForceRW;
  384. (* FatFS only: Enable/disable write back caching *)
  385. PROCEDURE EnableWB(sender, data : ANY);
  386. BEGIN
  387. IF parEnableWB THEN parEnableWB := FALSE; enableWB.caption.SetAOC("");
  388. ELSE parEnableWB := TRUE; enableWB.caption.SetAOC("X");
  389. END;
  390. END EnableWB;
  391. (* parameters : dev#part [/f] *)
  392. PROCEDURE Unmount(sender, data : ANY);
  393. VAR
  394. dev : Disks.Device;
  395. fs: Files.FileSystem; ft: Files.FileSystemTable;
  396. vol : DiskVolumes.Volume;
  397. volOld : OldDiskVolumes.Volume;
  398. volFAT: FATVolumes.Volume;
  399. volISO : ISO9660Volumes.Volume;
  400. fsStart : LONGINT;
  401. found : BOOLEAN;
  402. result : Strings.String;
  403. i : LONGINT;
  404. BEGIN
  405. NEW(result, 128);
  406. IF IsValid(selection) & (selection.disk.device.table # NIL) & (selection.partition < LEN(selection.disk.device.table)) THEN
  407. (* for unpartitioned devices we also try to unmount when Disks.Mounted is not set *)
  408. IF (LEN(selection.disk.table) = 1) OR (selection.disk.device.table[selection.partition].flags * {Disks.Mounted} # {}) THEN
  409. Files.GetList(ft);
  410. IF ft # NIL THEN
  411. i := 0; found := FALSE;
  412. LOOP
  413. fs := ft[i];
  414. IF fs.vol # NIL THEN
  415. IF fs.vol IS DiskVolumes.Volume THEN
  416.  vol := fs.vol (DiskVolumes.Volume);
  417.  dev := vol.dev; fsStart := vol.startfs;
  418.  ELSIF fs.vol IS OldDiskVolumes.Volume THEN
  419.  volOld := fs.vol (OldDiskVolumes.Volume);
  420.  dev := volOld.dev; fsStart := volOld.startfs;
  421.  ELSIF fs.vol IS FATVolumes.Volume THEN
  422.  volFAT := fs.vol (FATVolumes.Volume);
  423.  dev := volFAT.dev; fsStart := volFAT.start;
  424.  ELSIF fs.vol IS ISO9660Volumes.Volume THEN
  425.  volISO := fs.vol (ISO9660Volumes.Volume);
  426.  dev := volISO.dev; fsStart := 512; (* dummy value *)
  427.  ELSE
  428.  dev := NIL;
  429.  END;
  430. IF (dev#NIL) & (dev = selection.disk.device) &
  431. ((selection.disk.isDiskette) OR
  432. (fsStart >= dev.table[selection.partition].start) &
  433. (fsStart < dev.table[selection.partition].start + dev.table[selection.partition].size))
  434. THEN
  435. found := TRUE;
  436. IF (fs.vol = NIL) OR parForce OR ~(Files.Boot IN fs.vol.flags) THEN
  437. Files.Remove(fs);
  438. EXCL(selection.disk.table[selection.partition].flags, Disks.Mounted);
  439. selection.disk.fs[selection.partition] := NIL;
  440. Strings.Append(result^, fs.prefix); Strings.Append(result^, " unmounted");
  441. PartitionsLib.diskModel.UpdateDisk(selection.disk);
  442. owner.UpdateContent;
  443. ELSE
  444. Strings.Append(result^, " can't unmount boot volume. Use \f parameter to force unmounting.");
  445. END;
  446. EXIT;
  447. END;
  448. END;
  449. INC(i);
  450. IF found OR (i > LEN(ft)-1) THEN EXIT; END;
  451. END;
  452. IF ~found THEN Strings.Append(result^, "Failed: Volume not found"); END;
  453. ELSE Strings.Append(result^, "Failed: Volume not found");
  454. END;
  455. ELSE Strings.Append(result^, "Failed: Volume is not mounted");
  456. END;
  457. ELSE Strings.Append(result^, "Failed: Selection Invalid");
  458. END;
  459. owner.UpdateStatusLabel(result);
  460. END Unmount;
  461. (* Check if an Oberon or FAT file system is present on a partition. Returns 0 if no Oberon or FAT file system found,
  462. 1 for a Native file system, 2 for an old Aos file system and 3 for a new Aos file system, 4 for FAT file system (from Partitions.Mod) *)
  463. PROCEDURE DetectFS(dev: Disks.Device; part: LONGINT): LONGINT;
  464. VAR
  465. block: POINTER TO ARRAY OF CHAR;
  466. type : LONGINT;
  467. res: WORD; fs: LONGINT;
  468. BEGIN
  469. IF (dev.table=NIL) OR (part >= LEN(dev.table)) THEN RETURN 0; END;
  470. type := dev.table[part].type;
  471. fs := PartitionsLib.UnknownFS;
  472. IF (type = 01H ) OR (type = 04H) OR (type = 06H) OR (type = 0BH) OR (type = 0CH) OR (type = 0EH) THEN (* FAT Filesystems *)
  473. NEW(block, dev.blockSize);
  474. dev.Transfer(Disks.Read, dev.table[part].start, 1, block^, 0, res);
  475. IF (res = Disks.Ok) & (block[510]=055X) & (block[511]=0AAX) THEN
  476. fs := PartitionsLib.FatFS;
  477. END;
  478. ELSIF (type = 4CH) OR (type = 04FH) OR (type = 050H) THEN (* Aos/NativeOveron *)
  479. IF dev.blockSize = PartitionsLib.BS THEN
  480. fs := PartitionsLib.DetectFS(dev, part);
  481. END;
  482. END;
  483. RETURN fs
  484. END DetectFS;
  485. END FSToolsPlugin;
  486. TYPE
  487. ConfigEditor = OBJECT(WMComponents.FormWindow);
  488. VAR
  489. config : PartitionsLib.Configuration;
  490. configTable : PartitionsLib.ConfigTable;
  491. popup : PopupWindow;
  492. mainpanel : WMStandardComponents.Panel;
  493. titlelabel : WMStandardComponents.Label;
  494. (* config grid *)
  495. grid : WMPartitionsComponents.NoWheelGrid;
  496. gridContainer : WMStandardComponents.Panel;
  497. gridPanel : WMPartitionsComponents.BevelPanel;
  498. selectedRow : LONGINT;
  499. cellHeight : LONGINT;
  500. scrollbarY : WMStandardComponents.Scrollbar;
  501. (* edit panel *)
  502. editPanel : WMPartitionsComponents.BevelPanel;
  503. editorKey, editorValue : WMEditors.Editor;
  504. add, delete, replace, clear, moveup, movedown : WMStandardComponents.Button;
  505. (* operation panel *)
  506. opPanel : WMPartitionsComponents.BevelPanel;
  507. set, get : WMStandardComponents.Button;
  508. toFile, toPartition : WMStandardComponents.Button; (* check boxes *)
  509. editorFile, editorPartition : WMEditors.Editor;
  510. target : LONGINT; (* ToFile | ToPartition *)
  511. fileLeft : LONGINT; (* left offset from editorFile *)
  512. statusLabel : WMStandardComponents.Label;
  513. hex : ARRAY 32 OF CHAR;
  514. PROCEDURE LoadFromPartition(CONST devpart : ARRAY OF CHAR) : BOOLEAN;
  515. VAR
  516. getConfig : PartitionsLib.GetConfig;
  517. selection : PartitionsLib.Selection;
  518. caption : ARRAY 128 OF CHAR;
  519. fs : LONGINT;
  520. BEGIN
  521. IF PartitionsLib.diskModel.GetDisk(devpart, selection, FALSE) THEN
  522. fs := PartitionsLib.DetectFS(selection.disk.device, selection.partition);
  523. IF (fs = PartitionsLib.AosFS32) OR (fs = PartitionsLib.AosFS128) THEN (* new AosFS *)
  524. NEW(getConfig, selection.disk, selection.partition, NIL);
  525. getConfig.SetBlockingStart;
  526. IF ~(PartitionsLib.StatusError IN getConfig.state.status) THEN
  527. config.table := getConfig.GetTable();
  528. configTable.ParseRawTable(config);
  529. caption := " Configuration string loaded from partition "; Strings.Append(caption, getConfig.diskpartString);
  530. statusLabel.caption.Set(Strings.NewString(caption));
  531. caption := ""; Strings.Append(caption, getConfig.diskpartString);
  532. Strings.Append(caption, "("); Strings.Append(caption, selection.disk.device.desc); Strings.Append(caption, ")");
  533. titlelabel.caption.Set(Strings.NewString(caption));
  534. RETURN TRUE;
  535. ELSE
  536. caption := " Error: Could not load configuration from partition ";
  537. Strings.Append(caption, getConfig.diskpartString);
  538. statusLabel.caption.Set(Strings.NewString(caption));
  539. END;
  540. ELSE
  541. caption := " Error: Could not load configuration from partition (Filesystem is not AosFS) ";
  542. statusLabel.caption.Set(Strings.NewString(caption));
  543. END;
  544. ELSE
  545. caption := " Error: Could not load configuration from partition (Could not get disk)";
  546. statusLabel.caption.Set(Strings.NewString(caption));
  547. END;
  548. RETURN FALSE;
  549. END LoadFromPartition;
  550. PROCEDURE StoreToPartition(CONST devpart : ARRAY OF CHAR);
  551. VAR
  552. setConfig : PartitionsLib.SetConfig;
  553. selection : PartitionsLib.Selection;
  554. caption : ARRAY 128 OF CHAR;
  555. params : Parameters;
  556. string : Strings.String;
  557. res : WORD;
  558. BEGIN
  559. IF PartitionsLib.diskModel.GetDisk(devpart, selection, FALSE) THEN
  560. string := configTable.GetAsString();
  561. IF string # NIL THEN
  562. NEW(popup, 200, 100, FALSE); params := NIL;
  563. popup.SetTextAsString("Are you sure?");
  564. popup.SetParameters("Write config to ", selection, params);
  565. popup.Popup(100, 100, res);
  566. IF res = ResOk THEN
  567. NEW(setConfig, selection.disk, selection.partition, NIL);
  568. setConfig.SetParameters(string, 0);
  569. setConfig.SetBlockingStart;
  570. IF ~(PartitionsLib.StatusError IN setConfig.state.status) THEN
  571. caption := "Configuration loaded from "; Strings.Append(caption, setConfig.diskpartString);
  572. statusLabel.caption.Set(Strings.NewString(caption));
  573. ELSE
  574. statusLabel.caption.Set(setConfig.GetResult());
  575. END;
  576. END;
  577. popup := NIL;
  578. ELSE statusLabel.caption.Set(Strings.NewString("Could not get config string"));
  579. END;
  580. ELSE
  581. caption := " Error: Could not load configuration from partition (Could not get disk) ";
  582. statusLabel.caption.Set(Strings.NewString(caption));
  583. END;
  584. END StoreToPartition;
  585. PROCEDURE LoadFromFile(CONST filename : ARRAY OF CHAR);
  586. VAR caption, msg : ARRAY 256 OF CHAR; res : WORD;
  587. BEGIN
  588. configTable.LoadFromFile(filename, msg, res);
  589. IF (res = PartitionsLib.Ok) THEN
  590. caption := " Configuration string loaded from "; Strings.Append(caption, filename);
  591. statusLabel.caption.Set(Strings.NewString(caption));
  592. titlelabel.caption.Set(Strings.NewString(filename));
  593. ELSE
  594. statusLabel.caption.SetAOC(msg);
  595. END;
  596. UpdateGrid;
  597. END LoadFromFile;
  598. PROCEDURE StoreToFile(CONST filename : ARRAY OF CHAR);
  599. VAR caption, msg : ARRAY 256 OF CHAR; res : WORD;
  600. BEGIN
  601. configTable.StoreToFile(filename, msg, res);
  602. IF (res = PartitionsLib.Ok) THEN
  603. caption := " Configuration string stored to "; Strings.Append(caption, filename);
  604. statusLabel.caption.Set(Strings.NewString(caption));
  605. ELSE
  606. statusLabel.caption.SetAOC(msg);
  607. END;
  608. END StoreToFile;
  609. PROCEDURE SetSelection(selection : WMPartitionsComponents.Selection) : BOOLEAN;
  610. VAR string, diskpartStr : ARRAY 128 OF CHAR; temp : ARRAY 4 OF CHAR; res : WORD;
  611. BEGIN
  612. diskpartStr := "";
  613. Strings.Append(diskpartStr, selection.disk.device.name);
  614. Strings.Append(diskpartStr, "#"); Strings.IntToStr(selection.partition, temp); Strings.Append(diskpartStr, temp);
  615. editorPartition.SetAsString(diskpartStr);
  616. string := " ";
  617. Strings.Append(string, diskpartStr);
  618. Strings.Append(string, " ("); Strings.Append(string, selection.disk.device.desc); Strings.Append(string, ")");
  619. titlelabel.caption.Set(Strings.NewString(string));
  620. config.GetTable(selection.disk.device, selection.partition, res);
  621. configTable.ParseRawTable(config);
  622. UpdateGrid;
  623. RETURN res = Disks.Ok;
  624. END SetSelection;
  625. PROCEDURE WheelMove*(dz : LONGINT);
  626. CONST Multiplier = 30;
  627. VAR pos : LONGINT;
  628. BEGIN
  629. IF scrollbarY.visible.Get() THEN
  630. pos := scrollbarY.pos.Get() + Multiplier*dz;
  631. IF pos < scrollbarY.min.Get() THEN pos := scrollbarY.min.Get(); END;
  632. IF pos > scrollbarY.max.Get() THEN pos := scrollbarY.max.Get(); END;
  633. scrollbarY.pos.Set(pos);
  634. END;
  635. END WheelMove;
  636. PROCEDURE ButtonHandler(sender, data : ANY);
  637. VAR
  638. button : WMStandardComponents.Button;
  639. entry : PartitionsLib.ConfigEntry;
  640. key, value, string : ARRAY 1024 OF CHAR;
  641. BEGIN
  642. button := sender (WMStandardComponents.Button);
  643. IF button = add THEN
  644. editorKey.GetAsString(string); entry.key := Strings.NewString(string);
  645. editorValue.GetAsString(string); entry.value := Strings.NewString(string);
  646. configTable.AddEntry(selectedRow, entry);
  647. UpdateGrid;
  648. ELSIF button = delete THEN
  649. configTable.RemoveEntry(selectedRow);
  650. UpdateGrid;
  651. ELSIF button = replace THEN
  652. editorKey.GetAsString(key);
  653. editorValue.GetAsString(value);
  654. configTable.ChangeEntry(selectedRow, Strings.NewString(key), Strings.NewString(value));
  655. UpdateGrid;
  656. ELSIF button = clear THEN
  657. editorKey.SetAsString("");
  658. editorValue.SetAsString("");
  659. ELSIF button = moveup THEN
  660. configTable.SwapEntries(selectedRow, selectedRow -1);
  661. IF selectedRow > 0 THEN
  662. grid.Acquire; grid.SetSelection(0, selectedRow - 1, 0, selectedRow-1);grid.Release;
  663. selectedRow := selectedRow - 1;
  664. END;
  665. UpdateGrid;
  666. ELSIF button = movedown THEN
  667. configTable.SwapEntries(selectedRow, selectedRow + 1);
  668. IF selectedRow < configTable.GetNofEntries()-1 THEN
  669. grid.Acquire; grid.SetSelection(0, selectedRow + 1, 0, selectedRow +1); grid.Release;
  670. selectedRow := selectedRow + 1;
  671. END;
  672. UpdateGrid;
  673. ELSIF button = get THEN
  674. IF target = ToFile THEN
  675. editorFile.GetAsString(string);
  676. LoadFromFile(string);
  677. ELSIF target = ToPartition THEN
  678. editorPartition.GetAsString(string);
  679. IF LoadFromPartition(string) THEN UpdateGrid; END;
  680. ELSE
  681. HALT(397);
  682. END;
  683. ELSIF button = set THEN
  684. IF target = ToFile THEN
  685. editorFile.GetAsString(string);
  686. StoreToFile(string);
  687. ELSIF target = ToPartition THEN
  688. editorPartition.GetAsString(string);
  689. StoreToPartition(string);
  690. ELSE
  691. HALT(397);
  692. END;
  693. ELSE
  694. HALT(398);
  695. END;
  696. END ButtonHandler;
  697. PROCEDURE ScrollY(sender, data : ANY);
  698. VAR y : WMProperties.Int32Property;
  699. BEGIN
  700. y := data (WMProperties.Int32Property);
  701. grid.bounds.SetTop(-y.Get());
  702. END ScrollY;
  703. PROCEDURE CheckboxHandler(sender, data : ANY);
  704. VAR button : WMStandardComponents.Button;
  705. BEGIN
  706. button := sender (WMStandardComponents.Button);
  707. toFile.caption.Set(Strings.NewString(""));
  708. toPartition.caption.Set(Strings.NewString(""));
  709. IF button = toFile THEN
  710. target := ToFile; toFile.caption.Set(Strings.NewString("X"));
  711. ELSIF button = toPartition THEN
  712. target := ToPartition; toPartition.caption.Set(Strings.NewString("X"));
  713. ELSE
  714. HALT(398);
  715. END;
  716. END CheckboxHandler;
  717. PROCEDURE GridClicked(sender, data : ANY);
  718. VAR grid : WMPartitionsComponents.NoWheelGrid; ignore, row : LONGINT; string : Strings.String;
  719. BEGIN
  720. grid := sender (WMPartitionsComponents.NoWheelGrid);
  721. grid.GetSelection(ignore, row, ignore, ignore);
  722. selectedRow := row;
  723. grid.Acquire;
  724. grid.model.Acquire;
  725. string := grid.model.GetCellText(0, row); editorKey.SetAsString(string^);
  726. string := grid.model.GetCellText(1, row); editorValue.SetAsString(string^);
  727. grid.model.Release;
  728. grid.Release;
  729. END GridClicked;
  730. PROCEDURE UpdateGrid;
  731. VAR row, height : LONGINT; spacings : WMGrids.Spacings; table : PartitionsLib.Table;
  732. BEGIN
  733. table := configTable.GetEntries();
  734. IF table # NIL THEN
  735. grid.Acquire;
  736. grid.model.Acquire;
  737. grid.model.SetNofRows(LEN(table));
  738. FOR row := 0 TO LEN(table)-1 DO
  739. grid.model.SetCellText(0, row, table[row].key);
  740. grid.model.SetCellText(1, row, table[row].value);
  741. height := height + cellHeight + CeCellHeightMinSpacer + 1;
  742. END;
  743. NEW(spacings, LEN(table));
  744. FOR row := 0 TO LEN(table)-1 DO spacings[row] := cellHeight + CeCellHeightMinSpacer; END;
  745. grid.SetRowSpacings(spacings);
  746. grid.model.Release;
  747. grid.Release;
  748. grid.bounds.SetExtents(2000, height);
  749. ELSE
  750. grid.Acquire;
  751. grid.model.Acquire;
  752. grid.model.SetNofRows(1);
  753. grid.model.SetCellText(0, row, Strings.NewString(""));
  754. grid.model.SetCellText(1, row, Strings.NewString("No config loaded"));
  755. NEW(spacings, 1); spacings[0] := cellHeight + CeCellHeightMinSpacer; grid.SetRowSpacings(spacings);
  756. grid.model.Release;
  757. grid.Release;
  758. grid.bounds.SetExtents(2000, spacings[0]+1);
  759. END;
  760. UpdateLayout(SELF.bounds.r - SELF.bounds.l, SELF.bounds.b - SELF.bounds.t);
  761. END UpdateGrid;
  762. PROCEDURE UpdateLayout(width, height : LONGINT);
  763. VAR gridHeight : LONGINT; table : PartitionsLib.Table;
  764. BEGIN
  765. DisableUpdate;
  766. mainpanel.bounds.SetExtents(width, height);
  767. titlelabel.bounds.SetExtents(width - 2*MarginH, CeLabelHeight);
  768. gridPanel.bounds.SetExtents(width - 2*MarginH, height - CeLabelHeight - StatusBarHeight- CeOpPanelHeight - CeEditPanelHeight - 5*MarginV);
  769. gridContainer.bounds.SetExtents(gridPanel.bounds.GetWidth() - 2*MarginH, gridPanel.bounds.GetHeight() - 2*MarginV);
  770. table := configTable.GetEntries();
  771. IF table # NIL THEN
  772. gridHeight := LEN(table)*(cellHeight + CeCellHeightMinSpacer + 1);
  773. END;
  774. scrollbarY.bounds.SetLeft(gridContainer.bounds.GetWidth() - scrollbarY.bounds.GetWidth());
  775. scrollbarY.bounds.SetHeight(gridContainer.bounds.GetHeight());
  776. IF gridHeight > gridContainer.bounds.GetHeight() THEN
  777. scrollbarY.pos.Set(ENTIER(1.0*scrollbarY.pos.Get()*(1.0*(gridHeight-gridContainer.bounds.GetHeight()) / scrollbarY.max.Get())));
  778. scrollbarY.max.Set(gridHeight-gridContainer.bounds.GetHeight());
  779. scrollbarY.visible.Set(TRUE);
  780. ELSE
  781. scrollbarY.visible.Set(FALSE);
  782. END;
  783. editPanel.bounds.SetTop(height - CeOpPanelHeight - CeEditPanelHeight - StatusBarHeight - 2*MarginV);
  784. editPanel.bounds.SetExtents(width - 2*MarginH, CeEditPanelHeight);
  785. editorValue.bounds.SetWidth(width - CeKeyWidth - 2*MarginH - 2*MarginH);
  786. opPanel.bounds.SetExtents(width - 2*MarginH, CeOpPanelHeight);
  787. opPanel.bounds.SetTop(height - StatusBarHeight - CeOpPanelHeight - MarginV);
  788. editorFile.bounds.SetWidth(width - fileLeft - 2*MarginH - MarginH);
  789. statusLabel.bounds.SetExtents(width, StatusBarHeight);
  790. statusLabel.bounds.SetTop(height - StatusBarHeight);
  791. EnableUpdate;
  792. CSChanged;
  793. END UpdateLayout;
  794. PROCEDURE Close*;
  795. BEGIN
  796. Close^; IF popup # NIL THEN popup.Close; END;
  797. END Close;
  798. PROCEDURE Resized*(width, height : LONGINT);
  799. BEGIN
  800. Resized^(width, height);
  801. UpdateLayout(width, height);
  802. END Resized;
  803. PROCEDURE &Init*(width, height : LONGINT; alpha : BOOLEAN);
  804. VAR
  805. left, ignore : LONGINT;
  806. spacings : WMGrids.Spacings;
  807. font : WMGraphics.Font;
  808. label : WMStandardComponents.Label;
  809. BEGIN
  810. Init^(width, height, alpha); scaling := FALSE; hex := "0123456789ABCDEF";
  811. NEW(config);
  812. NEW(configTable);
  813. NEW(mainpanel); mainpanel.bounds.SetLeft(0); mainpanel.bounds.SetTop(0);
  814. IF ~UseSkinColors THEN mainpanel.fillColor.Set(BackgroundColor); END;
  815. NEW(titlelabel); titlelabel.bounds.SetLeft(MarginH); titlelabel.bounds.SetTop(MarginV);
  816. mainpanel.AddInternalComponent(titlelabel);
  817. NEW(gridPanel); gridPanel.bounds.SetLeft(MarginH); gridPanel.bounds.SetTop(CeLabelHeight + 2*MarginV);
  818. mainpanel.AddInternalComponent(gridPanel);
  819. NEW(gridContainer); gridContainer.bounds.SetLeft(MarginH); gridContainer.bounds.SetTop(MarginV);
  820. gridPanel.AddInternalComponent(gridContainer);
  821. NEW(grid);
  822. grid.fixedCols.Set(1);
  823. grid.onClick.Add(GridClicked); grid.SetSelectionMode(WMGrids.GridSelectSingleRow);
  824. grid.alwaysShowScrollX.Set(FALSE); grid.showScrollX.Set(FALSE);
  825. grid.alwaysShowScrollY.Set(FALSE); grid.showScrollY.Set(FALSE);
  826. grid.allowColResize.Set(TRUE); grid.allowRowResize.Set(FALSE);
  827. NEW(spacings, 2); spacings[0] := CeKeyWidth; spacings[1] := 2000; (* since allowColResize *)
  828. grid.Acquire;
  829. grid.model.Acquire;
  830. grid.model.SetNofCols(2); grid.SetColSpacings(spacings);
  831. grid.model.Release;
  832. grid.Release;
  833. gridContainer.AddInternalComponent(grid);
  834. NEW(scrollbarY);
  835. scrollbarY.vertical.Set(TRUE); scrollbarY.bounds.SetHeight(gridContainer.bounds.GetHeight());
  836. scrollbarY.bounds.SetTop(0); scrollbarY.bounds.SetLeft(gridContainer.bounds.GetWidth() - scrollbarY.bounds.GetWidth());
  837. scrollbarY.min.Set(0); scrollbarY.onPositionChanged.Add(ScrollY);
  838. gridContainer.AddInternalComponent(scrollbarY);
  839. font := grid.GetFont(); font.GetStringSize("TestString", ignore, cellHeight);
  840. NEW(editPanel); editPanel.bounds.SetLeft(MarginH);
  841. editPanel.bounds.SetTop(height - CeEditPanelHeight - StatusBarHeight - CeOpPanelHeight - 2*MarginV);
  842. mainpanel.AddInternalComponent(editPanel);
  843. NEW(editorKey);
  844. editorKey.bounds.SetExtents(CeKeyWidth, ButtonHeight);
  845. editorKey.bounds.SetLeft(MarginH); editorKey.bounds.SetTop(MarginV);
  846. editorKey.multiLine.Set(FALSE);
  847. editorKey.tv.textAlignV.Set(WMGraphics.AlignCenter);
  848. IF ~UseSkinColors THEN editorKey.fillColor.Set(WMGraphics.White); END;
  849. editorKey.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1)); editorKey.tv.showBorder.Set(TRUE);
  850. editPanel.AddInternalComponent(editorKey);
  851. NEW(editorValue);
  852. editorValue.bounds.SetExtents(width - CeKeyWidth - 2*MarginH - 2*MarginH, ButtonHeight);
  853. editorValue.bounds.SetLeft(CeKeyWidth + MarginH); editorValue.bounds.SetTop(MarginV);
  854. editorValue.multiLine.Set(FALSE);
  855. editorValue.tv.textAlignV.Set(WMGraphics.AlignCenter);
  856. IF ~UseSkinColors THEN editorValue.fillColor.Set(WMGraphics.White); END;
  857. editorValue.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1)); editorValue.tv.showBorder.Set(TRUE);
  858. editPanel.AddInternalComponent(editorValue);
  859. NEW(add); left := MarginH;
  860. add.bounds.SetExtents(ButtonWidth, ButtonHeight);
  861. add.bounds.SetLeft(left); add.bounds.SetTop(MarginV + ButtonHeight + ButtonSpacer);
  862. add.onClick.Add(ButtonHandler); add.caption.Set(Strings.NewString("Add"));
  863. editPanel.AddInternalComponent(add);
  864. NEW(delete); left := left + ButtonWidth + ButtonSpacer;
  865. delete.bounds.SetExtents(ButtonWidth, ButtonHeight);
  866. delete.bounds.SetLeft(left); delete.bounds.SetTop(MarginV + ButtonHeight + ButtonSpacer);
  867. delete.onClick.Add(ButtonHandler); delete.caption.Set(Strings.NewString("Delete"));
  868. editPanel.AddInternalComponent(delete);
  869. NEW(replace); left := left + ButtonWidth + ButtonSpacer;
  870. replace.bounds.SetExtents(ButtonWidth, ButtonHeight);
  871. replace.bounds.SetLeft(left); replace.bounds.SetTop(MarginV + ButtonHeight + ButtonSpacer);
  872. replace.onClick.Add(ButtonHandler); replace.caption.Set(Strings.NewString("Replace"));
  873. editPanel.AddInternalComponent(replace);
  874. NEW(clear); left := left + ButtonWidth + ButtonSpacer;
  875. clear.bounds.SetExtents(ButtonWidth, ButtonHeight);
  876. clear.bounds.SetLeft(left); clear.bounds.SetTop(MarginV + ButtonHeight + ButtonSpacer);
  877. clear.onClick.Add(ButtonHandler); clear.caption.Set(Strings.NewString("Clear"));
  878. editPanel.AddInternalComponent(clear);
  879. NEW(moveup); left := left + ButtonWidth + ButtonSpacer;
  880. moveup.bounds.SetExtents(ButtonWidth, ButtonHeight);
  881. moveup.bounds.SetLeft(left); moveup.bounds.SetTop(MarginV + ButtonHeight + ButtonSpacer);
  882. moveup.onClick.Add(ButtonHandler); moveup.caption.Set(Strings.NewString("Up"));
  883. editPanel.AddInternalComponent(moveup);
  884. NEW(movedown);
  885. movedown.bounds.SetExtents(ButtonWidth, ButtonHeight);
  886. movedown.bounds.SetLeft(left); movedown.bounds.SetTop(MarginV + 2*ButtonHeight + 2*ButtonSpacer);
  887. movedown.onClick.Add(ButtonHandler); movedown.caption.Set(Strings.NewString("Down"));
  888. editPanel.AddInternalComponent(movedown);
  889. NEW(opPanel);
  890. opPanel.bounds.SetExtents(width - 2*MarginH, CeOpPanelHeight);
  891. opPanel.bounds.SetLeft(MarginH); opPanel.bounds.SetTop(height - StatusBarHeight - CeOpPanelHeight - MarginV);
  892. mainpanel.AddInternalComponent(opPanel);
  893. NEW(get); left := MarginH;
  894. get.bounds.SetExtents(ButtonWidth, ButtonHeight);
  895. get.bounds.SetLeft(left); get.bounds.SetTop(MarginV);
  896. get.onClick.Add(ButtonHandler); get.caption.Set(Strings.NewString("GetConfig"));
  897. opPanel.AddInternalComponent(get);
  898. NEW(set); left := left + ButtonWidth + ButtonSpacer;
  899. set.bounds.SetExtents(ButtonWidth, ButtonHeight);
  900. set.bounds.SetLeft(left); set.bounds.SetTop(MarginV);
  901. set.onClick.Add(ButtonHandler); set.caption.Set(Strings.NewString("SetConfig"));
  902. opPanel.AddInternalComponent(set);
  903. target := ToPartition;
  904. NEW(toPartition); left := left + ButtonWidth + ButtonSpacer;
  905. toPartition.bounds.SetExtents(ButtonHeight, ButtonHeight);
  906. toPartition.bounds.SetLeft(left); toPartition.bounds.SetTop(MarginV);
  907. toPartition.onClick.Add(CheckboxHandler); toPartition.caption.Set(Strings.NewString("X"));
  908. opPanel.AddInternalComponent(toPartition);
  909. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  910. label.bounds.SetExtents(50, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(MarginV);
  911. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); END;
  912. label.caption.Set(Strings.NewString("Partition:"));
  913. opPanel.AddInternalComponent(label);
  914. NEW(editorPartition); left := left + 50;
  915. editorPartition.bounds.SetExtents(50, ButtonHeight);
  916. editorPartition.bounds.SetLeft(left); editorPartition.bounds.SetTop(MarginV);
  917. editorPartition.multiLine.Set(FALSE);
  918. editorPartition.tv.textAlignV.Set(WMGraphics.AlignCenter);
  919. IF ~UseSkinColors THEN editorPartition.fillColor.Set(WMGraphics.White); END;
  920. editorPartition.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1)); editorPartition.tv.showBorder.Set(TRUE);
  921. opPanel.AddInternalComponent(editorPartition);
  922. NEW(toFile); left := left + 50 + ButtonSpacer;
  923. toFile.bounds.SetExtents(ButtonHeight, ButtonHeight);
  924. toFile.bounds.SetLeft(left); toFile.bounds.SetTop(MarginV);
  925. toFile.onClick.Add(CheckboxHandler); toFile.caption.Set(Strings.NewString(""));
  926. opPanel.AddInternalComponent(toFile);
  927. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  928. label.bounds.SetExtents(22, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(MarginV);
  929. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); END;
  930. label.caption.Set(Strings.NewString("File:"));
  931. opPanel.AddInternalComponent(label);
  932. NEW(editorFile); left := left + 22 + ButtonSpacer; fileLeft := left;
  933. editorFile.bounds.SetExtents(width - fileLeft - MarginH - MarginH, ButtonHeight);
  934. editorFile.bounds.SetLeft(left); editorFile.bounds.SetTop(MarginV);
  935. editorFile.multiLine.Set(FALSE);
  936. editorFile.tv.textAlignV.Set(WMGraphics.AlignCenter);
  937. IF ~UseSkinColors THEN editorFile.fillColor.Set(WMGraphics.White); END;
  938. editorFile.tv.borders.Set(WMRectangles.MakeRect(3, 3, 1, 1)); editorFile.tv.showBorder.Set(TRUE);
  939. editorFile.SetAsString("config.txt"); (* default file name *)
  940. opPanel.AddInternalComponent(editorFile);
  941. NEW(statusLabel);
  942. statusLabel.bounds.SetLeft(0); statusLabel.bounds.SetTop(height - StatusBarHeight);
  943. IF ~UseSkinColors THEN
  944. statusLabel.fillColor.Set(WMGraphics.Blue); statusLabel.textColor.Set(WMGraphics.Yellow);
  945. END;
  946. statusLabel.caption.Set(Strings.NewString("Ready"));
  947. mainpanel.AddInternalComponent(statusLabel);
  948. SetTitle(Strings.NewString("Configuration Editor"));
  949. SetContent(mainpanel);
  950. WMWindowManager.AddWindow (SELF, 100, 100);
  951. manager := WMWindowManager.GetDefaultManager();
  952. manager.SetFocus(SELF);
  953. UpdateLayout(width, height);
  954. END Init;
  955. END ConfigEditor;
  956. (*
  957. * The Partitions plugin is a graphical front-end for partitioning operations provided by PartitionsLib.Mod.
  958. *)
  959. PartitionsPlugin = OBJECT (Plugin);
  960. VAR
  961. show, eject, checkPartition, activeBit, format, changeType,
  962. delete, create, partitionToFile, fileToPartition, writeMBR, editPBR : WMStandardComponents.Button;
  963. PROCEDURE &Init*;
  964. VAR left : LONGINT;
  965. BEGIN
  966. Init^;
  967. (* upper row of buttons *)
  968. NEW(create); left := 0;
  969. create.bounds.SetExtents(ButtonWidth, ButtonHeight); create.bounds.SetLeft(left); create.bounds.SetTop(0);
  970. create.onClick.Add(Create); create.SetCaption("Create");
  971. AddInternalComponent(create);
  972. NEW(format); left := left + ButtonWidth + ButtonSpacer;
  973. format.bounds.SetExtents(ButtonWidth, ButtonHeight); format.bounds.SetLeft(left); format.bounds.SetTop(0);
  974. format.onClick.Add(Format); format.SetCaption("Format");
  975. AddInternalComponent(format);
  976. NEW(fileToPartition); left := left + ButtonWidth + ButtonSpacer;
  977. fileToPartition.bounds.SetExtents(ButtonWidth, ButtonHeight); fileToPartition.bounds.SetLeft(left); fileToPartition.bounds.SetTop(0);
  978. fileToPartition.onClick.Add(FileToPartition); fileToPartition.SetCaption("FromFile");
  979. AddInternalComponent(fileToPartition);
  980. NEW(activeBit); left := left + ButtonWidth + ButtonSpacer;
  981. activeBit.bounds.SetExtents(ButtonWidth, ButtonHeight); activeBit.bounds.SetLeft(left); activeBit.bounds.SetTop(0);
  982. activeBit.onClick.Add(ActiveBit); activeBit.SetCaption("Activate");
  983. AddInternalComponent(activeBit);
  984. NEW(show); left := left + ButtonWidth + ButtonSpacer;
  985. show.bounds.SetExtents(ButtonWidth, ButtonHeight); show.bounds.SetLeft(left); show.bounds.SetTop(0);
  986. show.onClick.Add(Show); show.SetCaption("ShowBlocks");
  987. AddInternalComponent(show);
  988. NEW(writeMBR); left := left + ButtonWidth + ButtonSpacer;
  989. writeMBR.bounds.SetExtents(ButtonWidth, ButtonHeight); writeMBR.bounds.SetLeft(left); writeMBR.bounds.SetTop(0);
  990. writeMBR.onClick.Add(WriteMBR); writeMBR.SetCaption("WriteMBR");
  991. AddInternalComponent(writeMBR);
  992. (* 2nd row of buttons *)
  993. NEW(delete); left := 0;
  994. delete.bounds.SetExtents(ButtonWidth, ButtonHeight); delete.bounds.SetLeft(left); delete.bounds.SetTop(ButtonHeight + ButtonSpacer);
  995. delete.onClick.Add(Delete); delete.SetCaption("Delete");
  996. AddInternalComponent(delete);
  997. NEW(changeType); left := left + ButtonWidth + ButtonSpacer;
  998. changeType.bounds.SetExtents(ButtonWidth, ButtonHeight); changeType.bounds.SetLeft(left); changeType.bounds.SetTop(ButtonHeight + ButtonSpacer);
  999. changeType.onClick.Add(ChangeType); changeType.SetCaption("ChangeType");
  1000. AddInternalComponent(changeType);
  1001. NEW(partitionToFile); left := left + ButtonWidth + ButtonSpacer;
  1002. partitionToFile.bounds.SetExtents(ButtonWidth, ButtonHeight); partitionToFile.bounds.SetLeft(left); partitionToFile.bounds.SetTop(ButtonHeight + ButtonSpacer);
  1003. partitionToFile.onClick.Add(PartitionToFile); partitionToFile.SetCaption("ToFile");
  1004. AddInternalComponent(partitionToFile);
  1005. NEW(eject); left := left + ButtonWidth + ButtonSpacer;
  1006. eject.bounds.SetExtents(ButtonWidth, ButtonHeight); eject.bounds.SetLeft(left); eject.bounds.SetTop(ButtonHeight + ButtonSpacer);
  1007. eject.onClick.Add(Eject); eject.SetCaption("Eject");
  1008. AddInternalComponent(eject);
  1009. NEW(checkPartition); left := left + ButtonWidth + ButtonSpacer;
  1010. checkPartition.bounds.SetExtents(ButtonWidth, ButtonHeight); checkPartition.bounds.SetLeft(left); checkPartition.bounds.SetTop(ButtonHeight + ButtonSpacer);
  1011. checkPartition.onClick.Add(CheckPartition); checkPartition.SetCaption("Check");
  1012. AddInternalComponent(checkPartition);
  1013. NEW(editPBR); left := left + ButtonWidth + ButtonSpacer;
  1014. editPBR.bounds.SetExtents(ButtonWidth, ButtonHeight); editPBR.bounds.SetLeft(left); editPBR.bounds.SetTop(ButtonHeight + ButtonSpacer);
  1015. editPBR.onClick.Add(EditPBR); editPBR.SetCaption("EditPBR");
  1016. AddInternalComponent(editPBR);
  1017. END Init;
  1018. (** This procedure is called everytime when the selection has been updated *)
  1019. (** Return value: SelectionValid, SelectionInvalid, SelectionMaybe *)
  1020. PROCEDURE SelectionUpdated(selection : WMPartitionsComponents.Selection) : LONGINT;
  1021. VAR result : LONGINT;
  1022. BEGIN
  1023. SELF.selection := selection;
  1024. IF IsValid(selection) THEN
  1025. IF Disks.Boot IN selection.disk.table[selection.partition].flags THEN
  1026. activeBit.caption.Set(Strings.NewString("Deactivate"));
  1027. ELSE
  1028. activeBit.caption.Set(Strings.NewString("Activate"));
  1029. END;
  1030. result := SelectionMaybe;
  1031. ELSE
  1032. result := SelectionInvalid;
  1033. END;
  1034. RETURN result;
  1035. END SelectionUpdated;
  1036. (* Create a new extended or primary partition. *)
  1037. PROCEDURE Create(sender, data : ANY);
  1038. VAR
  1039. create : PartitionsLib.CreatePartition;
  1040. popup : PopupWindow; param : Parameters;
  1041. res : WORD;
  1042. BEGIN
  1043. IF IsValid(selection) & ~selection.disk.isDiskette THEN
  1044. NEW(param, 2);
  1045. param[0].description := "Size"; param[0].type := ParInteger; param[0].width := 0;
  1046. param[0].optional := FALSE; param[0].default := FALSE;
  1047. param[1].description := "Type"; param[1].type := ParInteger; param[1].width := 0;
  1048. param[1].optional := FALSE; param[1].default := FALSE;
  1049. NEW(popup, 220, 160, FALSE);
  1050. popup.SetTextAsString("Enter size [MB] and type of the partition to be created. To create an extended partition, select type 5.");
  1051. popup.SetParameters("Create a new partition on", selection, param);
  1052. popup.Popup(100, 100, res);
  1053. IF res = ResOk THEN
  1054. ASSERT(param[0].valid);
  1055. NEW(create, selection.disk, selection.partition, NIL);
  1056. create.SetParameters(param[0].resInteger, param[1].resInteger, FALSE);
  1057. create.SetStart;
  1058. END;
  1059. ELSE
  1060. owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1061. END;
  1062. END Create;
  1063. (* Delete the selected partition. *)
  1064. PROCEDURE Delete(sender, data : ANY);
  1065. VAR
  1066. delete : PartitionsLib.DeletePartition;
  1067. popup : PopupWindow; param : Parameters;
  1068. res : WORD;
  1069. BEGIN
  1070. IF ~selection.disk.isDiskette & IsValid(selection) &
  1071. (selection.disk.device # NIL) & (selection.partition < LEN(selection.disk.device.table))
  1072. THEN
  1073. NEW(popup, 200, 100, FALSE);
  1074. popup.SetTextAsString("Delete partition?");
  1075. param := NIL;
  1076. popup.SetParameters("Delete partition", selection, param);
  1077. popup.Popup(100, 100, res);
  1078. IF res = ResOk THEN
  1079. NEW(delete, selection.disk, selection.partition, NIL);
  1080. delete.SetParameters(selection.disk.table[selection.partition].type);
  1081. delete.SetStart;
  1082. END;
  1083. ELSE
  1084. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1085. END;
  1086. END Delete;
  1087. (* Write a MBR to the selected device *)
  1088. PROCEDURE WriteMBR(sender, data : ANY);
  1089. VAR
  1090. writeMBR : PartitionsLib.WriteMBR;
  1091. popup : PopupWindow; param : Parameters;
  1092. res : WORD;
  1093. BEGIN
  1094. IF (selection.disk.device # NIL) & (selection.partition = 0) & (selection.disk.table # NIL) & ~selection.disk.isDiskette THEN
  1095. NEW(popup, 250, 180, FALSE);
  1096. popup.SetTextAsString("Write MBR to partition?");
  1097. NEW(param, 3);
  1098. param[0].description := "MBR file"; param[0].type := ParString; param[0].optional := FALSE;
  1099. param[0].width := 0; param[0].default := TRUE; param[0].resString := "OBEMBR.BIN";
  1100. param[1].description := "Preserve Table"; param[1].type := ParBoolean;
  1101. param[1].default := TRUE; param[1].resBoolean := TRUE;
  1102. param[2].description := "Preserve Disk Signature"; param[2].type := ParBoolean;
  1103. param[2].default := TRUE; param[2].resBoolean := TRUE;
  1104. popup.SetParameters("Write MBR to", selection, param);
  1105. popup.Popup(100, 100, res);
  1106. IF res = ResOk THEN
  1107. NEW(writeMBR, selection.disk, selection.partition, NIL);
  1108. writeMBR.SetParameters(param[0].resString, param[1].resBoolean, param[2].resBoolean);
  1109. writeMBR.SetStart;
  1110. END;
  1111. ELSE
  1112. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1113. END;
  1114. END WriteMBR;
  1115. PROCEDURE EditPBR(sender, data : ANY);
  1116. VAR cmd, msg : ARRAY 512 OF CHAR; nbr : ARRAY 16 OF CHAR; res : WORD;
  1117. BEGIN
  1118. IF (selection.disk.device # NIL) & (selection.disk.table # NIL) & (selection.partition < LEN(selection.disk.table)) & ~selection.disk.isDiskette THEN
  1119. cmd := "PartitionEditor.Open ";
  1120. Strings.Append(cmd, selection.disk.device.name);
  1121. Strings.Append(cmd, " ");
  1122. Strings.IntToStr(selection.disk.table[selection.partition].start, nbr);
  1123. Strings.Append(cmd, nbr);
  1124. Commands.Call(cmd, {}, res, msg);
  1125. IF (res # Commands.Ok) THEN
  1126. owner.UpdateStatusLabel(Strings.NewString(msg));
  1127. END;
  1128. ELSE
  1129. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1130. END;
  1131. END EditPBR;
  1132. (* Format the selected partition. *)
  1133. PROCEDURE Format (sender, data : ANY);
  1134. VAR
  1135. formatAOS : PartitionsLib.FormatPartition;
  1136. formatFAT : FATScavenger.FormatPartition;
  1137. volumelabel : Strings.String;
  1138. popup : PopupWindow; params : Parameters;
  1139. cancel, doClose : BOOLEAN;
  1140. fs : LONGINT;
  1141. res : WORD;
  1142. BEGIN
  1143. IF IsValid(selection) & ((selection.disk.table[selection.partition].flags * {Disks.Valid} # {}) OR selection.disk.isDiskette) THEN
  1144. (* If a floppy drive is selected, check whether it contains a diskette *)
  1145. cancel := FALSE; doClose := FALSE;
  1146. IF selection.disk.isDiskette & (selection.disk.device.openCount < 1) THEN
  1147. doClose := TRUE;
  1148. selection.disk.device.Open(res);
  1149. IF res = Disks.MediaMissing THEN
  1150. cancel := TRUE;
  1151. owner.UpdateStatusLabel(Strings.NewString("No diskette inserted"));
  1152. ELSIF res # Disks.Ok THEN
  1153. cancel := TRUE;
  1154. owner.UpdateStatusLabel(Strings.NewString("Cannot open floppy device"));
  1155. END;
  1156. END;
  1157. IF selection.disk.isDiskette THEN (* let the user choose the file system *)
  1158. NEW(params, 1);
  1159. params[0].description := "File System (FatFS or AosFS)"; params[0].type := ParString;
  1160. params[0].optional := FALSE; params[0].width := 0;
  1161. NEW(popup, 250, 200, FALSE);
  1162. popup.SetTextAsString("Format the selected diskette with the specified file system");
  1163. popup.SetParameters("Format diskette", selection, params);
  1164. popup.Popup(100,100,res);
  1165. IF res = ResOk THEN
  1166. IF params[0].valid THEN
  1167. IF params[0].resString = "FatFS" THEN
  1168. fs := 2;
  1169. ELSIF params[0].resString = "AosFS" THEN
  1170. fs := 1;
  1171. ELSE
  1172. fs := 0; (* invalid paramter *)
  1173. END;
  1174. END;
  1175. ELSE
  1176. cancel := TRUE; (* user abort *)
  1177. END;
  1178. ELSE (* use file system that matches the partition type *)
  1179. IF PartitionsLib.IsNativeType(selection.disk.table[selection.partition].type) THEN
  1180. fs := 1;
  1181. ELSIF PartitionsLib.IsFatType(selection.disk.table[selection.partition].type) THEN
  1182. fs := 2;
  1183. ELSE
  1184. fs := 0; (* not supported *)
  1185. owner.UpdateStatusLabel(Strings.NewString("Only FatFS or AosFS supported"));
  1186. END;
  1187. END;
  1188. IF cancel THEN
  1189. (* do nothing *)
  1190. ELSIF fs = 1 THEN
  1191. NEW(params, 4);
  1192. params[0].description := "File System"; params[0].type := ParString;
  1193. params[0].optional := FALSE; params[0].width := 0; params[0].resString := "AosFS"; params[0].default := TRUE;
  1194. params[1].description := "[Bootfile]"; params[1].type := ParString;
  1195. params[1].optional := TRUE; params[1].width := 0; params[1].resString := "IDE.Bin"; params[1].default := TRUE;
  1196. params[2].description := "[fsRes (KB)]"; params[2].type := ParInteger; params[2].default := TRUE;
  1197. params[2].optional := TRUE; params[2].width := 0; params[2].resInteger := 640;
  1198. params[3].description := "[flags]"; params[3].type := ParInteger; params[3].default := TRUE;
  1199. params[3].optional := TRUE; params[3].width := 0; params[3].resInteger := 0;
  1200. NEW(popup, 250, 200, FALSE);
  1201. popup.SetTextAsString("Enter parameters");
  1202. popup.SetParameters("Format partition ", selection, params);
  1203. popup.Popup(100,100, res);
  1204. IF res = ResOk THEN
  1205. IF params[1].valid = FALSE THEN params[1].resString := ""; END;
  1206. (* filesystem [bootfilename] [fsres] [flags] *)
  1207. NEW(formatAOS, selection.disk, selection.partition, NIL);
  1208. formatAOS.SetParameters(params[0].resString, params[1].resString, params[2].resInteger, params[3].resInteger);
  1209. formatAOS.SetStart;
  1210. END;
  1211. ELSIF fs = 2 THEN
  1212. NEW(params, 2);
  1213. params[0].description := "Volume label"; params[0].type := ParString;
  1214. params[0].optional := TRUE; params[0].width := 0; params[0].default := FALSE;
  1215. params[1].description := "Quickformat"; params[1].type := ParBoolean;
  1216. params[1].optional := TRUE; params[1].width := 30; params[1].default := TRUE;
  1217. params[1].resBoolean := FALSE;
  1218. NEW(popup, 250, 150, FALSE);
  1219. popup.SetTextAsString("Enter parameters");
  1220. popup.SetParameters("Format partition ", selection, params);
  1221. popup.Popup(100,100, res);
  1222. IF res = ResOk THEN
  1223. IF params[0].valid THEN volumelabel := Strings.NewString(params[0].resString);
  1224. ELSE volumelabel := Strings.NewString("");
  1225. END;
  1226. NEW(formatFAT, selection.disk, selection.partition, NIL);
  1227. formatFAT.SetParameters(volumelabel, params[0].resBoolean);
  1228. formatFAT.SetStart;
  1229. END;
  1230. ELSE owner.UpdateStatusLabel(Strings.NewString("Can't format partition of this type"));
  1231. END;
  1232. IF selection.disk.isDiskette & doClose & (selection.disk.device.openCount > 0) THEN
  1233. selection.disk.device.Close(res); (* ignore res *)
  1234. END;
  1235. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1236. END;
  1237. END Format;
  1238. (* Change the type of the selected partition. *)
  1239. PROCEDURE ChangeType(sender, data : ANY);
  1240. VAR
  1241. changeType : PartitionsLib.ChangePartType;
  1242. oldtype, newtype : LONGINT;
  1243. popup : PopupWindow;
  1244. param : Parameters;
  1245. res : WORD;
  1246. BEGIN
  1247. IF IsValid(selection) & (selection.disk.table[selection.partition].flags * {Disks.Valid} # {}) THEN
  1248. NEW(param, 1);
  1249. param[0].description := "New Type"; param[0].type := ParInteger; param[0].optional := FALSE;
  1250. param[0].width := 30; param[0].default := FALSE;
  1251. NEW(popup, 200, 130, FALSE);
  1252. popup.SetParameters("Change type of ", selection, param); popup.SetTextAsString("Enter new type");
  1253. popup.Popup(100,100, res);
  1254. IF res = ResOk THEN
  1255. ASSERT(param[0].valid);
  1256. NEW(changeType, selection.disk, selection.partition, NIL);
  1257. newtype := param[0].resInteger;
  1258. oldtype := selection.disk.table[selection.partition].type;
  1259. changeType.SetParameters(oldtype, newtype);
  1260. changeType.SetStart;
  1261. END;
  1262. ELSE
  1263. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1264. END;
  1265. END ChangeType;
  1266. (* Set the active bit for the selected partition. *)
  1267. PROCEDURE ActiveBit(sender, data : ANY);
  1268. VAR
  1269. setFlags : PartitionsLib.SetFlags;
  1270. popup : PopupWindow; param : Parameters;
  1271. string : ARRAY 64 OF CHAR;
  1272. on : BOOLEAN;
  1273. res : WORD;
  1274. BEGIN
  1275. IF IsValid(selection) & (Disks.Valid IN selection.disk.table[selection.partition].flags) & ~selection.disk.isDiskette THEN
  1276. on := Disks.Boot IN selection.disk.table[selection.partition].flags;
  1277. NEW(popup, 200, 100, FALSE);
  1278. IF on THEN
  1279. string := "Deactivate partition";
  1280. ELSE
  1281. string := "Activate partition";
  1282. END;
  1283. param := NIL;
  1284. popup.SetParameters(string, selection, param); popup.SetTextAsString("Are you sure?");
  1285. popup.Popup(100, 100, res);
  1286. IF res = ResOk THEN
  1287. NEW(setFlags, selection.disk, selection.partition, NIL);
  1288. setFlags.SetParameters(~on);
  1289. setFlags.SetStart;
  1290. END;
  1291. ELSE
  1292. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1293. END;
  1294. END ActiveBit;
  1295. PROCEDURE FileToPartition(sender, data : ANY);
  1296. VAR
  1297. fileToPartition : PartitionsLib.FileToPartition;
  1298. popup : PopupWindow; param : Parameters;
  1299. block, numblocks : LONGINT; res : WORD;
  1300. BEGIN
  1301. IF IsValid(selection) THEN
  1302. NEW(param, 3);
  1303. param[0].description := "Filename"; param[0].type := ParString; param[0].optional := FALSE;
  1304. param[0].width := 0; param[0].default := FALSE;
  1305. param[1].description := "Offset"; param[1].type := ParInteger; param[1].optional := TRUE;
  1306. param[1].width := 0; param[1].default := FALSE;
  1307. param[2].description := "Numblocks"; param[2].type := ParInteger; param[2].optional := TRUE;
  1308. param[2].width := 0; param[2].default := FALSE;
  1309. NEW(popup, 200, 180, FALSE);
  1310. popup.SetTextAsString("Write file <Filename> to the specified partition, starting at bock <Offset>, <Numblocks> blocks ");
  1311. popup.SetParameters("FileToPartition on", selection, param);
  1312. popup.Popup(100,100, res);
  1313. IF res = ResOk THEN
  1314. ASSERT(param[0].valid);
  1315. NEW(fileToPartition, selection.disk, selection.partition, NIL);
  1316. IF param[1].valid THEN block := param[1].resInteger; ELSE block := -1; END;
  1317. IF param[2].valid THEN numblocks := param[2].resInteger; ELSE numblocks := -1; END;
  1318. fileToPartition.SetParameters(param[0].resString, block, numblocks); (* filename [block numblocks] *)
  1319. fileToPartition.SetStart;
  1320. END;
  1321. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1322. END;
  1323. END FileToPartition;
  1324. PROCEDURE PartitionToFile(sender, data : ANY);
  1325. VAR
  1326. partitionToFile : PartitionsLib.PartitionToFile;
  1327. popup : PopupWindow; param : Parameters;
  1328. block, numblocks : LONGINT; res : WORD;
  1329. BEGIN
  1330. IF IsValid(selection) THEN
  1331. NEW(param, 3);
  1332. param[0].description := "Filename"; param[0].type := ParString; param[0].optional := FALSE;
  1333. param[0].width := 0; param[0].default := FALSE;
  1334. param[1].description := "Offset"; param[1].type := ParInteger; param[1].optional := TRUE;
  1335. param[1].width := 0; param[1].default := FALSE;
  1336. param[2].description := "Numblocks"; param[2].type := ParInteger; param[2].optional := TRUE;
  1337. param[2].width := 0; param[2].default := FALSE;
  1338. NEW(popup, 200, 180, FALSE);
  1339. popup.SetTextAsString("Write partition to file <Filename>, starting at block <Offset>, <Numblocks> blocks. ");
  1340. popup.SetParameters("PartitionToFile on ", selection, param);
  1341. popup.Popup(100,100, res);
  1342. IF res = ResOk THEN
  1343. ASSERT(param[0].valid);
  1344. IF param[1].valid THEN block := param[1].resInteger; ELSE block := -1; END;
  1345. IF param[2].valid THEN numblocks := param[2].resInteger; ELSE numblocks := -1; END;
  1346. NEW(partitionToFile, selection.disk, selection.partition, NIL);
  1347. partitionToFile.SetParameters(param[0].resString, block, numblocks); (* filename [block numblocks] *)
  1348. partitionToFile.SetStart;
  1349. END;
  1350. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1351. END;
  1352. END PartitionToFile;
  1353. (* Will be registered as callback at PartitionsLib.ShowBlocks *)
  1354. PROCEDURE ShowCallback(text : Texts.Text);
  1355. VAR window : ReportWindow;
  1356. BEGIN
  1357. NEW(window, text, 560, 240, FALSE); window.Show;
  1358. END ShowCallback;
  1359. PROCEDURE Show(sender, data : ANY);
  1360. VAR
  1361. showBlocks : PartitionsLib.ShowBlocks;
  1362. popup : PopupWindow; param : Parameters;
  1363. block, numblocks : LONGINT; res : WORD;
  1364. BEGIN
  1365. IF IsValid(selection) THEN
  1366. NEW(param, 2);
  1367. param[0].description := "Block"; param[0].type := ParInteger; param[0].optional := FALSE;
  1368. param[0].width := 0; param[0].default := FALSE;
  1369. param[1].description := "Numblocks"; param[1].type := ParInteger; param[1].optional := FALSE;
  1370. param[1].width := 0; param[1].default := FALSE;
  1371. NEW(popup, 200, 160, FALSE);
  1372. popup.SetTextAsString("Show <numblocks> blocks of partition starting at block <block>");
  1373. popup.SetParameters("Showblocks on", selection, param);
  1374. popup.Popup(100,100, res);
  1375. IF res = ResOk THEN
  1376. ASSERT(param[0].valid);
  1377. NEW(showBlocks, selection.disk, selection.partition, NIL);
  1378. block := param[0].resInteger;
  1379. numblocks := param[1].resInteger;
  1380. showBlocks.SetParameters(block, numblocks); (* block [numblocks] *)
  1381. showBlocks.SetCallback(ShowCallback);
  1382. showBlocks.SetStart;
  1383. END;
  1384. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1385. END;
  1386. END Show;
  1387. PROCEDURE Eject(sender, data : ANY);
  1388. VAR
  1389. result : ARRAY 128 OF CHAR;
  1390. popup : PopupWindow; param : Parameters;
  1391. eject : BOOLEAN;
  1392. res : WORD;
  1393. BEGIN
  1394. IF (selection.disk.device # NIL) & (~selection.disk.isDiskette) THEN
  1395. IF (Disks.Removable IN selection.disk.device.flags) THEN
  1396. eject := TRUE;
  1397. IF selection.disk.device.openCount > 0 THEN
  1398. param := NIL;
  1399. popup.SetParameters("Eject disk", selection, param);
  1400. NEW(popup, 200, 100, FALSE);
  1401. popup.SetTextAsString("Device is open. Do you really want to eject its media? ");
  1402. popup.Popup(100,100, res);
  1403. IF res # ResOk THEN eject := FALSE; END;
  1404. END;
  1405. IF eject THEN
  1406. PartitionsLib.Eject(selection.disk.device, result);
  1407. owner.UpdateStatusLabel(Strings.NewString(result));
  1408. END;
  1409. ELSE owner.UpdateStatusLabel(Strings.NewString("Device not removable"));
  1410. END;
  1411. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1412. END;
  1413. END Eject;
  1414. PROCEDURE CheckPartition(sender, data : ANY);
  1415. VAR checkPartition : PartitionsLib.CheckPartition;
  1416. BEGIN
  1417. IF IsValid(selection) THEN
  1418. NEW(checkPartition, selection.disk, selection.partition, NIL);
  1419. checkPartition.SetStart;
  1420. ELSE
  1421. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1422. END;
  1423. END CheckPartition;
  1424. END PartitionsPlugin;
  1425. TYPE
  1426. A2Plugin = OBJECT(Plugin);
  1427. VAR
  1428. config, updateLoader, updateBoot, bootManagerBtn, installBtn : WMStandardComponents.Button;
  1429. popup : PopupWindow;
  1430. PROCEDURE Config(sender, data : ANY);
  1431. VAR configEditor : ConfigEditor; doClose : BOOLEAN; fsType : LONGINT; res : WORD;
  1432. BEGIN
  1433. IF IsValid(selection) &
  1434. ((Disks.Valid IN selection.disk.table[selection.partition].flags) OR (selection.disk.isDiskette)) THEN
  1435. IF selection.disk.device.blockSize = PartitionsLib.BS THEN
  1436. (* special handling for diskette drives *)
  1437. IF selection.disk.isDiskette & (selection.disk.device.openCount < 1) THEN
  1438. doClose := TRUE;
  1439. selection.disk.device.Open(res); (* ignore res *)
  1440. END;
  1441. fsType := PartitionsLib.DetectFS(selection.disk.device, selection.partition);
  1442. IF (fsType = PartitionsLib.AosFS32) OR (fsType = PartitionsLib.AosFS128) THEN (* new AosFS *)
  1443. NEW(configEditor, 800, 600, FALSE);
  1444. IF configEditor.SetSelection(selection) THEN
  1445. owner.UpdateStatusLabel(Strings.NewString("Configuration Editor started"));
  1446. ELSE
  1447. owner.UpdateStatusLabel(Strings.NewString("Could not load configuration"));
  1448. END;
  1449. ELSE owner.UpdateStatusLabel(Strings.NewString("Partitions does not contain a AosFS volume"));
  1450. END;
  1451. IF selection.disk.isDiskette & doClose & (selection.disk.device.openCount > 0) THEN
  1452. selection.disk.device.Close(res); (* ignore res *)
  1453. END;
  1454. ELSE owner.UpdateStatusLabel(Strings.NewString("Error: Blocksize not supported"));
  1455. END;
  1456. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1457. END;
  1458. END Config;
  1459. PROCEDURE UpdateLoader(sender, data : ANY);
  1460. VAR
  1461. updateLoader : PartitionsLib.UpdateBootLoader;
  1462. param : Parameters;
  1463. res : WORD;
  1464. BEGIN
  1465. IF IsValid(selection) &
  1466. ((Disks.Valid IN selection.disk.table[selection.partition].flags) OR (selection.disk.isDiskette)) THEN
  1467. NEW(popup, 200, 140, FALSE);
  1468. NEW(param, 1); param[0].description:= "Bootloader name"; param[0].type := ParString;
  1469. param[0].optional := FALSE; param[0].resString := "OBL.Bin"; param[0].default := TRUE;
  1470. popup.SetTextAsString("Enter filename of boot loader");
  1471. popup.SetParameters("Update bootloader on", selection, param);
  1472. popup.Popup(100, 100, res);
  1473. IF res = ResOk THEN
  1474. NEW(updateLoader, selection.disk, selection.partition, NIL);
  1475. updateLoader.SetParameters(param[0].resString);
  1476. updateLoader.SetStart;
  1477. END;
  1478. popup := NIL;
  1479. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1480. END;
  1481. END UpdateLoader;
  1482. PROCEDURE UpdateBoot(sender, data : ANY);
  1483. VAR
  1484. updateBoot : PartitionsLib.UpdateBootFile;
  1485. param : Parameters;
  1486. res : WORD;
  1487. BEGIN
  1488. IF IsValid(selection) &
  1489. ((Disks.Valid IN selection.disk.table[selection.partition].flags) OR (selection.disk.isDiskette)) THEN
  1490. NEW(popup, 200, 140, FALSE);
  1491. NEW(param, 1); param[0].description:= "filename"; param[0].type := ParString;
  1492. param[0].optional := FALSE; param[0].resString := "IDE.Bin"; param[0].default := TRUE;
  1493. popup.SetTextAsString("Enter filename of boot file");
  1494. popup.SetParameters("Update bootfile on", selection, param);
  1495. popup.Popup(100, 100, res);
  1496. IF res = ResOk THEN
  1497. NEW(updateBoot, selection.disk, selection.partition, NIL);
  1498. updateBoot.SetParameters(param[0].resString);
  1499. updateBoot.SetStart;
  1500. END;
  1501. popup := NIL;
  1502. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1503. END;
  1504. END UpdateBoot;
  1505. PROCEDURE InstallBootManager(sender, data : ANY);
  1506. VAR
  1507. installBootManager : PartitionsLib.InstallBootManager;
  1508. param : Parameters;
  1509. res : WORD;
  1510. BEGIN
  1511. IF IsValid(selection) & ((Disks.Valid IN selection.disk.table[selection.partition].flags) OR (selection.disk.isDiskette)) THEN
  1512. NEW(popup, 300, 200, FALSE);
  1513. NEW(param, 2);
  1514. param[0].description:= "MBR boot manager filename"; param[0].type := ParString;
  1515. param[0].optional := FALSE; param[0].resString := "BootManagerMBR.Bin"; param[0].default := TRUE;
  1516. param[1].description:= "MBR boot manager filename"; param[1].type := ParString;
  1517. param[1].optional := FALSE; param[1].resString := "BootManagerTail.Bin"; param[1].default := TRUE;
  1518. popup.SetTextAsString("Enter names of boot manager files");
  1519. popup.SetParameters("Install boot manager on", selection, param);
  1520. popup.Popup(100, 100, res);
  1521. IF res = ResOk THEN
  1522. NEW(installBootManager, selection.disk, selection.partition, NIL);
  1523. installBootManager.SetParameters(param[0].resString, param[1].resString);
  1524. installBootManager.SetStart;
  1525. END;
  1526. popup := NIL;
  1527. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1528. END;
  1529. END InstallBootManager;
  1530. PROCEDURE Install(sender, data : ANY);
  1531. VAR
  1532. installer : Installer.Installer; packages : Installer.Packages; configuration : Installer.Configuration;
  1533. errorString : ARRAY 1024 OF CHAR; errorWriter : Streams.StringWriter;
  1534. text : Texts.Text; textWriter : TextUtilities.TextWriter;
  1535. reader : Streams.Reader;
  1536. params : Parameters;
  1537. res : WORD;
  1538. BEGIN
  1539. IF IsValid(selection) & ((Disks.Valid IN selection.disk.table[selection.partition].flags) OR selection.disk.isDiskette) THEN
  1540. NEW(packages); NEW(errorWriter, LEN(errorString));
  1541. IF packages.OpenPackages("InstallerPackages.XML", errorWriter) THEN
  1542. NEW(configuration, selection.disk, selection.partition);
  1543. configuration.SetPackages(packages);
  1544. reader := Codecs.OpenInputStream("config.txt");
  1545. IF (reader # NIL) THEN
  1546. configuration.configTable.LoadFromStream(reader, errorString, res);
  1547. IF (res = PartitionsLib.Ok) THEN
  1548. IF configuration.CheckConfiguration(errorWriter) THEN
  1549. NEW(text); NEW(textWriter, text);
  1550. configuration.ToStream(textWriter); textWriter.Update;
  1551. NEW(popup, 480, 250, FALSE);
  1552. params := NIL;
  1553. popup.SetParameters("Installer", selection, params);
  1554. popup.SetText(text);
  1555. popup.Popup(100, 100, res);
  1556. IF (res = ResOk) THEN
  1557. NEW(installer, selection.disk, selection.partition, NIL);
  1558. installer.SetParameters(configuration);
  1559. installer.SetStart;
  1560. END;
  1561. ELSE
  1562. errorWriter.Get(errorString);
  1563. WMDialogs.Error("Installer Error", errorString);
  1564. END;
  1565. ELSE
  1566. WMDialogs.Error("Installer Error", errorString);
  1567. END;
  1568. ELSE
  1569. WMDialogs.Error("Installer Error", "Configuration file Config.bin not found");
  1570. END;
  1571. ELSE
  1572. errorWriter.Get(errorString);
  1573. WMDialogs.Error("Installer Error", errorString);
  1574. END;
  1575. END;
  1576. END Install;
  1577. PROCEDURE Finalize*;
  1578. BEGIN
  1579. Finalize^;
  1580. IF popup # NIL THEN popup.Close; popup := NIL END;
  1581. END Finalize;
  1582. PROCEDURE SelectionUpdated(selection : WMPartitionsComponents.Selection) : LONGINT;
  1583. VAR result : LONGINT;
  1584. BEGIN
  1585. SELF.selection := selection;
  1586. IF IsValid(selection) & (Disks.Valid IN selection.disk.table[selection.partition].flags) OR selection.disk.isDiskette THEN
  1587. result := SelectionMaybe;
  1588. ELSE
  1589. result := SelectionInvalid;
  1590. END;
  1591. RETURN result;
  1592. END SelectionUpdated;
  1593. PROCEDURE &Init*;
  1594. VAR left : LONGINT;
  1595. BEGIN
  1596. Init^;
  1597. (* upper row of buttons *)
  1598. NEW(config); left := 0;
  1599. config.bounds.SetExtents(ButtonWidth, ButtonHeight);
  1600. config.bounds.SetLeft(left); config.bounds.SetTop(0);
  1601. config.onClick.Add(Config); config.SetCaption("Config");
  1602. AddInternalComponent(config);
  1603. NEW(updateLoader); left := left + ButtonWidth + ButtonSpacer;
  1604. updateLoader.bounds.SetExtents(2*ButtonWidth, ButtonHeight);
  1605. updateLoader.bounds.SetLeft(left); updateLoader.bounds.SetTop(0);
  1606. updateLoader.onClick.Add(UpdateLoader); updateLoader.SetCaption("UpdateBootLoader");
  1607. AddInternalComponent(updateLoader);
  1608. NEW(updateBoot); left := left +2* ButtonWidth + ButtonSpacer;
  1609. updateBoot.bounds.SetExtents(2*ButtonWidth, ButtonHeight);
  1610. updateBoot.bounds.SetLeft(left); updateBoot.bounds.SetTop(0);
  1611. updateBoot.onClick.Add(UpdateBoot); updateBoot.SetCaption("UpdateBootFile");
  1612. AddInternalComponent(updateBoot);
  1613. NEW(bootManagerBtn); left := left +2*ButtonWidth + ButtonSpacer;
  1614. bootManagerBtn.bounds.SetExtents(2*ButtonWidth, ButtonHeight);
  1615. bootManagerBtn.bounds.SetLeft(left); bootManagerBtn.bounds.SetTop(0);
  1616. bootManagerBtn.onClick.Add(InstallBootManager); bootManagerBtn.SetCaption("Install BootManager");
  1617. AddInternalComponent(bootManagerBtn);
  1618. (* bottom row *)
  1619. NEW(installBtn); left := 0;
  1620. installBtn.bounds.SetExtents(ButtonWidth, ButtonHeight);
  1621. installBtn.bounds.SetLeft(left); installBtn.bounds.SetTop(ButtonHeight + ButtonSpacer);
  1622. installBtn.onClick.Add(Install); installBtn.SetCaption("Install");
  1623. AddInternalComponent(installBtn);
  1624. END Init;
  1625. END A2Plugin;
  1626. TYPE
  1627. ScavengerPlugin = OBJECT(Plugin);
  1628. VAR
  1629. start, doSurfaceScan, doCompareFats, doLostClusters, doWrite : WMStandardComponents.Button;
  1630. (* object polls scavenger status *)
  1631. surfaceScan, compareFats, lostClusters, write : BOOLEAN;
  1632. PROCEDURE &Init*;
  1633. VAR label : WMStandardComponents.Label; left : LONGINT;
  1634. BEGIN
  1635. Init^;
  1636. surfaceScan := FALSE; compareFats := TRUE; lostClusters := TRUE; write := FALSE;
  1637. NEW(start);
  1638. start.bounds.SetExtents(ButtonWidth, ButtonHeight);
  1639. start.bounds.SetLeft(0); start.bounds.SetTop(0);
  1640. start.onClick.Add(StartScan); start.SetCaption("Start");
  1641. AddInternalComponent(start);
  1642. NEW(doSurfaceScan); left := ButtonWidth + ButtonSpacer;
  1643. doSurfaceScan.bounds.SetExtents(ButtonHeight, ButtonHeight);
  1644. doSurfaceScan.bounds.SetLeft(left); doSurfaceScan.bounds.SetTop(0);
  1645. doSurfaceScan.onClick.Add(CheckboxHandler); doSurfaceScan.SetCaption("");
  1646. AddInternalComponent(doSurfaceScan);
  1647. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  1648. label.bounds.SetExtents(70, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(0);
  1649. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  1650. label.caption.Set(Strings.NewString("Surface Scan"));
  1651. AddInternalComponent(label);
  1652. NEW(doCompareFats); left := left + 70 + ButtonSpacer;
  1653. doCompareFats.bounds.SetExtents(ButtonHeight, ButtonHeight);
  1654. doCompareFats.bounds.SetLeft(left); doCompareFats.bounds.SetTop(0);
  1655. doCompareFats.onClick.Add(CheckboxHandler); doCompareFats.SetCaption("X");
  1656. AddInternalComponent(doCompareFats);
  1657. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  1658. label.bounds.SetExtents(80, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(0);
  1659. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  1660. label.caption.Set(Strings.NewString("Compare FATs"));
  1661. AddInternalComponent(label);
  1662. NEW(doLostClusters); left := left + 80 + ButtonSpacer;
  1663. doLostClusters.bounds.SetExtents(ButtonHeight, ButtonHeight);
  1664. doLostClusters.bounds.SetLeft(left); doLostClusters.bounds.SetTop(0);
  1665. doLostClusters.onClick.Add(CheckboxHandler); doLostClusters.SetCaption("X");
  1666. AddInternalComponent(doLostClusters);
  1667. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  1668. label.bounds.SetExtents(100, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(0);
  1669. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  1670. label.caption.Set(Strings.NewString("Scan cluster chains"));
  1671. AddInternalComponent(label);
  1672. NEW(doWrite); left := left + 100 + ButtonSpacer;
  1673. doWrite.bounds.SetExtents(ButtonHeight, ButtonHeight);
  1674. doWrite.bounds.SetLeft(left); doWrite.bounds.SetTop(0);
  1675. doWrite.onClick.Add(CheckboxHandler); doWrite.SetCaption("");
  1676. AddInternalComponent(doWrite);
  1677. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  1678. label.bounds.SetExtents(100, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(0);
  1679. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  1680. label.caption.Set(Strings.NewString("Correct Errors"));
  1681. AddInternalComponent(label);
  1682. END Init;
  1683. PROCEDURE SelectionUpdated(selection : WMPartitionsComponents.Selection) : LONGINT;
  1684. VAR result : LONGINT;
  1685. BEGIN
  1686. SELF.selection := selection;
  1687. IF IsValid(selection) & (Disks.Valid IN selection.disk.table[selection.partition].flags) THEN
  1688. IF PartitionsLib.IsFatType(selection.disk.table[selection.partition].type) THEN (* FAT Filesystems *)
  1689. result := SelectionValid;
  1690. ELSE (* only FAT file systems are supported *)
  1691. result := SelectionInvalid;
  1692. END;
  1693. ELSE
  1694. result := SelectionInvalid;
  1695. END;
  1696. RETURN result;
  1697. END SelectionUpdated;
  1698. PROCEDURE StartScan(sender, data : ANY);
  1699. VAR scavenger : FATScavenger.FATScavenger;
  1700. BEGIN
  1701. IF IsValid(selection) & (PartitionsLib.IsFatType(selection.disk.table[selection.partition].type) OR selection.disk.isDiskette) THEN
  1702. NEW(scavenger, selection.disk, selection.partition, NIL);
  1703. scavenger.SetParameters(surfaceScan, compareFats, lostClusters, write);
  1704. scavenger.SetStart;
  1705. owner.UpdateStatusLabel(Strings.NewString("Scavenger started"));
  1706. ELSE owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1707. END;
  1708. END StartScan;
  1709. PROCEDURE CheckboxHandler(sender, data : ANY);
  1710. VAR
  1711. button : WMStandardComponents.Button;
  1712. mark : BOOLEAN;
  1713. ch : ARRAY 2 OF CHAR;
  1714. BEGIN
  1715. button := sender (WMStandardComponents.Button);
  1716. IF button = doSurfaceScan THEN
  1717. surfaceScan := ~surfaceScan; mark := surfaceScan;
  1718. ELSIF button = doCompareFats THEN
  1719. compareFats := ~compareFats; mark := compareFats;
  1720. ELSIF button = doLostClusters THEN
  1721. lostClusters := ~lostClusters; mark := lostClusters;
  1722. ELSIF button = doWrite THEN
  1723. write := ~write; mark := write;
  1724. END;
  1725. IF mark THEN ch := "X" ELSE ch := "" END;
  1726. button.caption.Set(Strings.NewString(ch));
  1727. END CheckboxHandler;
  1728. END ScavengerPlugin;
  1729. TYPE
  1730. (* Graphical front-end for DiskTests.Mod operations *)
  1731. TestsPlugin = OBJECT (Plugin);
  1732. VAR
  1733. writeDataBtn, testPartitionBtn, verifyDataBtn, writeZerosBtn, benchmarkBtn : WMStandardComponents.Button;
  1734. PROCEDURE SelectionUpdated(selection : WMPartitionsComponents.Selection) : LONGINT;
  1735. VAR result : LONGINT;
  1736. BEGIN
  1737. SELF.selection := selection;
  1738. IF IsValid(selection) THEN result := SelectionValid;
  1739. ELSE result := SelectionInvalid;
  1740. END;
  1741. RETURN result;
  1742. END SelectionUpdated;
  1743. PROCEDURE WriteTestData(sender, data : ANY);
  1744. VAR
  1745. testDataWriter : DiskTests.TestDataWriter;
  1746. popup : PopupWindow; param : Parameters;
  1747. res : WORD;
  1748. BEGIN
  1749. IF IsValid(selection) THEN
  1750. NEW(param, 1);
  1751. param[0].description := "SectorsPerTransfer"; param[0].type := ParInteger; param[0].width := 0;
  1752. param[0].optional := FALSE; param[0].default := TRUE; param[0].resInteger := 1;
  1753. NEW(popup, 220, 160, FALSE);
  1754. popup.SetTextAsString("Writing test data to a partition will DESTROY ITS CONTENTS!!");
  1755. popup.SetParameters("Write test data to", selection, param);
  1756. popup.Popup(100, 100, res);
  1757. IF res = ResOk THEN
  1758. ASSERT(param[0].valid);
  1759. NEW(testDataWriter, selection.disk, selection.partition, NIL);
  1760. testDataWriter.SetParameters(param[0].resInteger);
  1761. testDataWriter.SetStart;
  1762. END;
  1763. ELSE
  1764. owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1765. END;
  1766. END WriteTestData;
  1767. PROCEDURE WriteZeros(sender, data : ANY);
  1768. VAR
  1769. zeroWriter : DiskTests.ZeroWriter;
  1770. popup : PopupWindow; param : Parameters;
  1771. res : WORD;
  1772. BEGIN
  1773. IF IsValid(selection) THEN
  1774. NEW(param, 1);
  1775. param[0].description := "SectorsPerTransfer"; param[0].type := ParInteger; param[0].width := 0;
  1776. param[0].optional := FALSE; param[0].default := TRUE; param[0].resInteger := 1;
  1777. NEW(popup, 220, 160, FALSE);
  1778. popup.SetTextAsString("Writing zeros to the partition will DESTROY ITS CONTENTS!!");
  1779. popup.SetParameters("Write zeros to ", selection, param);
  1780. popup.Popup(100, 100, res);
  1781. IF res = ResOk THEN
  1782. ASSERT(param[0].valid);
  1783. NEW(zeroWriter, selection.disk, selection.partition, NIL);
  1784. zeroWriter.SetParameters(param[0].resInteger);
  1785. zeroWriter.SetStart;
  1786. END;
  1787. ELSE
  1788. owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1789. END;
  1790. END WriteZeros;
  1791. PROCEDURE TestPartition(sender, data : ANY);
  1792. VAR
  1793. diskTest : DiskTests.DiskTest;
  1794. popup : PopupWindow; param : Parameters;
  1795. res : WORD;
  1796. BEGIN
  1797. IF IsValid(selection) THEN
  1798. NEW(param, 4);
  1799. param[0].description := "Number of Tests"; param[0].type := ParInteger; param[0].width := 0;
  1800. param[0].optional := FALSE; param[0].default := TRUE; param[0].resInteger := -1;
  1801. param[1].description := "Max. Sectors per Transfer"; param[1].type := ParInteger; param[1].width := 0;
  1802. param[1].optional := FALSE; param[1].default := TRUE; param[1].resInteger := 200;
  1803. param[2].description := "Max. Offset into Client Buffer"; param[2].type := ParInteger; param[2].width := 0;
  1804. param[2].optional := FALSE; param[2].default := TRUE; param[2].resInteger := 0;
  1805. param[3].description := "Verify Test Data"; param[3].type := ParBoolean; param[3].width := 0;
  1806. param[3].optional := FALSE; param[3].default := TRUE; param[3].resBoolean := FALSE;
  1807. NEW(popup, 220, 260, FALSE);
  1808. popup.SetTextAsString("To run the test endlessly, specified a negative number of tests. ");
  1809. popup.SetParameters("Run DiskTest on partition ", selection, param);
  1810. popup.Popup(100, 100, res);
  1811. IF res = ResOk THEN
  1812. NEW(diskTest, selection.disk, selection.partition, NIL);
  1813. diskTest.SetParameters(TRUE, FALSE, param[3].resBoolean, param[0].resInteger, param[1].resInteger, param[2].resInteger);
  1814. diskTest.SetStart;
  1815. END;
  1816. ELSE
  1817. owner.UpdateStatusLabel(Strings.NewString("Selection Invalid"));
  1818. END;
  1819. END TestPartition;
  1820. PROCEDURE VerifyTestData(sender, data : ANY);
  1821. VAR
  1822. testDataChecker : DiskTests.TestDataChecker;
  1823. popup : PopupWindow; param : Parameters;
  1824. res : WORD;
  1825. BEGIN
  1826. IF IsValid(selection) THEN
  1827. NEW(param, 1);
  1828. param[0].description := "SectorsPerTransfer"; param[0].type := ParInteger; param[0].width := 0;
  1829. param[0].optional := FALSE; param[0].default := TRUE; param[0].resInteger := 1;
  1830. NEW(popup, 220, 160, FALSE);
  1831. popup.SetTextAsString("Verify test data");
  1832. popup.SetParameters("Verify test data on", selection, param);
  1833. popup.Popup(100, 100, res);
  1834. IF res = ResOk THEN
  1835. ASSERT(param[0].valid);
  1836. NEW(testDataChecker, selection.disk, selection.partition, NIL);
  1837. testDataChecker.SetParameters(param[0].resInteger);
  1838. testDataChecker.SetStart;
  1839. END;
  1840. ELSE
  1841. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1842. END;
  1843. END VerifyTestData;
  1844. PROCEDURE WriteK(k: LONGINT; VAR string: ARRAY OF CHAR);
  1845. VAR suffix: ARRAY 3 OF CHAR;
  1846. BEGIN
  1847. IF k < 1024 THEN suffix := "B";
  1848. ELSE k := k DIV 1024; suffix := "KB";
  1849. END;
  1850. Strings.IntToStr(k, string); Strings.Append(string, suffix);
  1851. END WriteK;
  1852. PROCEDURE BenchPartition(sender, data : ANY);
  1853. VAR
  1854. benchPartition : DiskBenchmark.DiskBench;
  1855. popup : PopupWindow; param : Parameters;
  1856. blocksizes : SET;
  1857. i, blocksize : LONGINT; res : WORD;
  1858. string : ARRAY 128 OF CHAR;
  1859. BEGIN
  1860. IF IsValid(selection) & (selection.disk.device # NIL) THEN
  1861. NEW(popup, 300, 625, FALSE);
  1862. popup.SetTextAsString("Benchmark Configuration");
  1863. NEW(param, 21);
  1864. param[0].description := "Perform Random Block Tests"; param[0].type := ParBoolean;
  1865. param[0].optional := TRUE; param[0].width := 0; param[0].default := TRUE; param[0].resBoolean := TRUE;
  1866. param[1].description := "NbrOfBlock for random test"; param[1].type := ParInteger;
  1867. param[1].optional := FALSE; param[1].width := 0; param[1].default := TRUE; param[1].resInteger := 1000;
  1868. param[2].description := "Perform Sequential Block Tests"; param[2].type := ParBoolean;
  1869. param[2].optional := TRUE; param[2].width := 0; param[2].default := TRUE; param[2].resBoolean := TRUE;
  1870. param[3].description := "Perform Read Tests"; param[3].type := ParBoolean;
  1871. param[3].optional := TRUE; param[3].width := 0; param[3].default := TRUE; param[3].resBoolean := TRUE;
  1872. param[4].description := "Perform Write Tests (DANGEROUS)"; param[4].type := ParBoolean;
  1873. param[4].optional := TRUE; param[4].width := 0; param[4].default := TRUE; param[4].resBoolean := FALSE;
  1874. blocksize := 512;
  1875. FOR i := 1 TO 16 DO
  1876. WriteK(blocksize, string); Strings.Append(string, " Blocks");
  1877. COPY(string, param[4+i].description);
  1878. param[4+i].type := ParBoolean;
  1879. param[4+i].optional := TRUE; param[4+i].width := 0; param[4+i].default := TRUE; param[4+i].resBoolean := TRUE;
  1880. blocksize := blocksize * 2;
  1881. END;
  1882. popup.SetParameters("Partition Benchmark", selection, param);
  1883. popup.Popup(100,100, res);
  1884. IF res = ResOk THEN
  1885. blocksizes := {};
  1886. FOR i := 1 TO 16 DO
  1887. IF param[4+i].resBoolean THEN INCL(blocksizes, i-1); END;
  1888. END;
  1889. NEW(benchPartition, selection.disk, selection.partition, NIL);
  1890. benchPartition.SetParameters(param[0].resBoolean, param[2].resBoolean, param[3].resBoolean, param[4].resBoolean, param[1].resInteger, blocksizes);
  1891. benchPartition.SetStart;
  1892. END;
  1893. ELSE
  1894. owner.UpdateStatusLabel(Strings.NewString("Selection invalid"));
  1895. END;
  1896. END BenchPartition;
  1897. PROCEDURE &Init*;
  1898. VAR left : LONGINT;
  1899. BEGIN
  1900. Init^;
  1901. (* upper row of buttons *)
  1902. NEW(writeDataBtn); left := 0;
  1903. writeDataBtn.bounds.SetExtents(ButtonWidth + 20, ButtonHeight); writeDataBtn.bounds.SetLeft(left); writeDataBtn.bounds.SetTop(0);
  1904. writeDataBtn.onClick.Add(WriteTestData); writeDataBtn.SetCaption("Write Test Data");
  1905. AddInternalComponent(writeDataBtn);
  1906. NEW(testPartitionBtn); left := left + ButtonWidth + 20 + ButtonSpacer;
  1907. testPartitionBtn.bounds.SetExtents(ButtonWidth + 20, ButtonHeight); testPartitionBtn.bounds.SetLeft(left); testPartitionBtn.bounds.SetTop(0);
  1908. testPartitionBtn.onClick.Add(TestPartition); testPartitionBtn.SetCaption("Test Partition");
  1909. AddInternalComponent(testPartitionBtn);
  1910. NEW(benchmarkBtn); left := left + ButtonWidth + 20 + ButtonSpacer;
  1911. benchmarkBtn.bounds.SetExtents(ButtonWidth + 20, ButtonHeight); benchmarkBtn.bounds.SetLeft(left); benchmarkBtn.bounds.SetTop(0);
  1912. benchmarkBtn.onClick.Add(BenchPartition); benchmarkBtn.SetCaption("Benchmark");
  1913. AddInternalComponent(benchmarkBtn);
  1914. (* 2nd row of buttons *)
  1915. NEW(verifyDataBtn); left := 0;
  1916. verifyDataBtn.bounds.SetExtents(ButtonWidth + 20, ButtonHeight); verifyDataBtn.bounds.SetLeft(left); verifyDataBtn.bounds.SetTop(ButtonHeight + ButtonSpacer);
  1917. verifyDataBtn.onClick.Add(VerifyTestData); verifyDataBtn.SetCaption("Verify Test Data");
  1918. AddInternalComponent(verifyDataBtn);
  1919. NEW(writeZerosBtn); left := left + ButtonWidth + 20 + ButtonSpacer;
  1920. writeZerosBtn.bounds.SetExtents(ButtonWidth + 20, ButtonHeight); writeZerosBtn.bounds.SetLeft(left); writeZerosBtn.bounds.SetTop(ButtonHeight + ButtonSpacer);
  1921. writeZerosBtn.onClick.Add(WriteZeros); writeZerosBtn.SetCaption("Write Zeros");
  1922. AddInternalComponent(writeZerosBtn);
  1923. END Init;
  1924. END TestsPlugin;
  1925. TYPE
  1926. (** Simple text view window *)
  1927. ReportWindow = OBJECT(WMComponents.FormWindow)
  1928. VAR
  1929. textView : WMTextView.TextView;
  1930. PROCEDURE Show*;
  1931. BEGIN
  1932. WMWindowManager.AddWindow(SELF, 100, 100);
  1933. manager := WMWindowManager.GetDefaultManager ();
  1934. manager.SetFocus(SELF);
  1935. SetTitle(WMWindowManager.NewString(" Operation Status Report"));
  1936. END Show;
  1937. PROCEDURE &New*(text : Texts.Text; width, height : LONGINT; visible : BOOLEAN);
  1938. VAR panel : WMStandardComponents.Panel;
  1939. BEGIN
  1940. Init(width, height, visible); scaling := FALSE;
  1941. NEW(panel); panel.alignment.Set(WMComponents.AlignClient);
  1942. panel.fillColor.Set(WMGraphics.White);
  1943. NEW(textView); textView.alignment.Set(WMComponents.AlignClient);
  1944. textView.isMultiLine.Set(TRUE); textView.showBorder.Set(FALSE);
  1945. textView.alwaysShowCursor.Set(FALSE);
  1946. textView.SetText(text);
  1947. panel.AddContent(textView);
  1948. SetContent(panel);
  1949. END New;
  1950. END ReportWindow;
  1951. TYPE
  1952. (** Specifies a single parameter for the PopupWindow *)
  1953. Parameter = RECORD
  1954. description : ARRAY 32 OF CHAR;
  1955. type : LONGINT; (* ParInteger, ParString *)
  1956. resInteger : LONGINT;
  1957. resString : ARRAY 32 OF CHAR;
  1958. resBoolean : BOOLEAN;
  1959. width : LONGINT; (* width of editor field *)
  1960. valid : BOOLEAN; (* is the resInteger/resString value valid *)
  1961. optional : BOOLEAN; (* Ok possible width filling this parameter *)
  1962. default : BOOLEAN; (* if default is TRUE, the values of ResInteger/ResString is used as default value *)
  1963. END;
  1964. (** Parameters passed to PopupWindow via SetParameters() *)
  1965. Parameters = POINTER TO ARRAY OF Parameter;
  1966. (** Pop up window capable of getting inputs specified with Parameters *)
  1967. PopupWindow = OBJECT(WMComponents.FormWindow)
  1968. VAR
  1969. okBtn, cancelBtn : WMStandardComponents.Button;
  1970. parameterPanel : WMStandardComponents.GroupPanel;
  1971. parameters : Parameters;
  1972. editors : POINTER TO ARRAY OF WMEditors.TextField;
  1973. boxes : POINTER TO ARRAY OF WMStandardComponents.Button;
  1974. vc : POINTER TO ARRAY OF WMComponents.VisualComponent;
  1975. operationName, diskpartString : Strings.String;
  1976. textView : WMTextView.TextView;
  1977. text : Texts.Text;
  1978. attr : Texts.Attributes;
  1979. result : LONGINT;
  1980. width, height : LONGINT; (* of this popup window *)
  1981. PROCEDURE &Init*(width, height : LONGINT; alpha : BOOLEAN);
  1982. VAR panel, line : WMStandardComponents.Panel;
  1983. BEGIN
  1984. SELF.width := width; SELF.height := height; scaling := FALSE;
  1985. Init^(width, height, alpha);
  1986. NEW(panel); panel.alignment.Set(WMComponents.AlignClient);
  1987. IF ~UseSkinColors THEN panel.fillColor.Set(MarginColor); END;
  1988. NEW(line); line.alignment.Set(WMComponents.AlignBottom);
  1989. line.bounds.SetHeight(ButtonHeight);
  1990. line.bearing.Set(WMRectangles.MakeRect(MarginH, MarginV, MarginH, MarginV));
  1991. panel.AddInternalComponent(line);
  1992. NEW(okBtn);
  1993. okBtn.alignment.Set(WMComponents.AlignRight);
  1994. okBtn.onClick.Add(Ok); okBtn.caption.Set(Strings.NewString("Ok"));
  1995. okBtn.bearing.Set(WMRectangles.MakeRect(ButtonSpacer, 0, 0, 0));
  1996. line.AddInternalComponent(okBtn);
  1997. NEW(cancelBtn);
  1998. cancelBtn.alignment.Set(WMComponents.AlignRight);
  1999. cancelBtn.onClick.Add(Cancel); cancelBtn.caption.Set(Strings.NewString("Cancel"));
  2000. line.AddInternalComponent(cancelBtn);
  2001. NEW(parameterPanel); parameterPanel.alignment.Set(WMComponents.AlignClient);
  2002. panel.AddInternalComponent(parameterPanel);
  2003. parameters := NIL; editors := NIL; boxes := NIL; vc := NIL;
  2004. operationName := NIL; diskpartString := NIL;
  2005. NEW(attr); attr.color := WMGraphics.White; attr.bgcolor := BackgroundColor;
  2006. SetContent(panel);
  2007. END Init;
  2008. PROCEDURE SetText(text : Texts.Text);
  2009. BEGIN
  2010. SELF.text := text;
  2011. IF (text # NIL) THEN
  2012. text.AcquireWrite;
  2013. text.SetAttributes(0, text.GetLength(), attr);
  2014. text.ReleaseWrite;
  2015. END;
  2016. END SetText;
  2017. (** Set text displayed by the PopupWindow as string *)
  2018. PROCEDURE SetTextAsString(CONST string : ARRAY OF CHAR);
  2019. BEGIN
  2020. NEW(text); TextUtilities.StrToText(text, 0, string);
  2021. text.AcquireWrite;
  2022. text.SetAttributes(0, text.GetLength(), attr);
  2023. text.ReleaseWrite;
  2024. END SetTextAsString;
  2025. (** Pass parameters *)
  2026. PROCEDURE SetParameters(CONST operationName : ARRAY OF CHAR; selection : PartitionsLib.Selection; VAR parameters : Parameters);
  2027. VAR string, temp : ARRAY 32 OF CHAR;
  2028. BEGIN
  2029. SELF.operationName := Strings.NewString(operationName);
  2030. string := ""; Strings.Append(string, selection.disk.device.name);
  2031. Strings.IntToStr(selection.partition, temp); Strings.Append(string, "#"); Strings.Append(string, temp);
  2032. diskpartString := Strings.NewString(string);
  2033. SELF.parameters := parameters;
  2034. END SetParameters;
  2035. (** Show popup window at position (x,y); call is blocking; res = ResNone | ResCancel | ResOk *)
  2036. PROCEDURE Popup(x, y : LONGINT; VAR res : WORD);
  2037. BEGIN
  2038. BuildLayout;
  2039. WMWindowManager.AddWindow (SELF, x, y);
  2040. manager.SetFocus(SELF);
  2041. IF (vc # NIL) & (LEN(vc) >= 2) THEN vc[LEN(vc)-1].SetFocus; END;
  2042. result := ResNone;
  2043. BEGIN {EXCLUSIVE} AWAIT(result # ResNone); END;
  2044. res := result;
  2045. END Popup;
  2046. PROCEDURE BuildLayout;
  2047. CONST MinSpacer = 5;
  2048. VAR
  2049. label, line : WMStandardComponents.Label;
  2050. width, labelwidth : LONGINT;
  2051. maxWidth, ignore : LONGINT;
  2052. font : WMGraphics.Font;
  2053. caption : ARRAY 128 OF CHAR;
  2054. i : LONGINT;
  2055. PROCEDURE SetFocusChain;
  2056. VAR ref, lastRef, uid : Strings.String; nbr : ARRAY 16 OF CHAR; i : LONGINT;
  2057. PROCEDURE GenRef(number : LONGINT) : Strings.String;
  2058. VAR string : Strings.String; temp, nbr : ARRAY 16 OF CHAR;
  2059. BEGIN
  2060. temp := "&";
  2061. Strings.IntToStr(number, nbr);
  2062. Strings.Append(temp, nbr);
  2063. string := Strings.NewString(temp);
  2064. ASSERT(string # NIL);
  2065. RETURN string;
  2066. END GenRef;
  2067. BEGIN
  2068. ASSERT(vc # NIL);
  2069. FOR i := 0 TO LEN(vc)-1 DO
  2070. ASSERT(vc[i] # NIL);
  2071. vc[i].needsTab.Set(FALSE);
  2072. vc[i].takesFocus.Set(TRUE);
  2073. Strings.IntToStr(i, nbr);
  2074. uid := Strings.NewString(nbr);
  2075. ref := GenRef(i);
  2076. vc[i].uid.Set(uid);
  2077. IF (i > 0) THEN
  2078. vc[i-1].focusNext.Set(ref);
  2079. vc[i].focusPrevious.Set(lastRef);
  2080. END;
  2081. lastRef := ref;
  2082. END;
  2083. vc[0].focusPrevious.Set(GenRef(LEN(vc)-1));
  2084. vc[LEN(vc)-1].focusNext.Set(GenRef(0));
  2085. END SetFocusChain;
  2086. BEGIN
  2087. caption := "";
  2088. IF (operationName # NIL) THEN Strings.Append(caption, operationName^); Strings.Append(caption, " "); END;
  2089. IF (diskpartString # NIL) THEN Strings.Append(caption, diskpartString^); END;
  2090. SetTitle(Strings.NewString(caption));
  2091. IF (parameters # NIL) THEN
  2092. NEW(editors, LEN(parameters)); NEW(boxes, LEN(parameters));
  2093. NEW(vc, LEN(parameters) + 2);
  2094. (* look for the widest string *)
  2095. NEW(label);
  2096. font := label.GetFont(); maxWidth := 0;
  2097. FOR i := 0 TO LEN(parameters) -1 DO
  2098. font.GetStringSize(parameters[i].description, width, ignore);
  2099. IF width > maxWidth THEN maxWidth := width; END;
  2100. END;
  2101. font.GetStringSize("[]", width, ignore);
  2102. maxWidth := maxWidth + width;
  2103. labelwidth := maxWidth + MinSpacer;
  2104. FOR i := LEN(parameters)-1 TO 0 BY -1 DO
  2105. NEW(line); line.alignment.Set(WMComponents.AlignBottom);
  2106. line.bounds.SetHeight(ButtonHeight);
  2107. line.bearing.Set(WMRectangles.MakeRect(0, MarginV, 0, 0));
  2108. parameterPanel.AddContent(line);
  2109. (* parameter description *)
  2110. NEW(label); label.alignment.Set(WMComponents.AlignLeft);
  2111. label.bounds.SetWidth(labelwidth);
  2112. IF ~UseSkinColors THEN label.textColor.Set(WMGraphics.White); END;
  2113. IF (parameters[i].optional) THEN
  2114. caption := "["; Strings.AppendX(caption, parameters[i].description);
  2115. Strings.AppendX(caption, "]");
  2116. label.caption.Set(Strings.NewString(caption));
  2117. ELSE
  2118. label.caption.Set(Strings.NewString(parameters[i].description));
  2119. END;
  2120. line.AddInternalComponent(label);
  2121. (* parameter input editor *)
  2122. IF (parameters[i].type = ParInteger) OR (parameters[i].type = ParString) THEN
  2123. NEW(editors[i]); vc[i] := editors[i];
  2124. editors[i].alignment.Set(WMComponents.AlignClient);
  2125. IF ~UseSkinColors THEN editors[i].fillColor.Set(WMGraphics.White); END;
  2126. IF parameters[i].default THEN
  2127. ASSERT((parameters[i].type = ParInteger) OR (parameters[i].type = ParString));
  2128. IF parameters[i].type = ParInteger THEN
  2129. Strings.IntToStr(parameters[i].resInteger, caption);
  2130. editors[i].SetAsString(caption);
  2131. ELSE (* ParString *)
  2132. editors[i].SetAsString(parameters[i].resString);
  2133. END;
  2134. END;
  2135. line.AddInternalComponent(editors[i]);
  2136. ELSIF parameters[i].type = ParBoolean THEN
  2137. NEW(boxes[i]); vc[i] := boxes[i];
  2138. boxes[i].alignment.Set(WMComponents.AlignLeft);
  2139. boxes[i].bounds.SetExtents(ButtonHeight, ButtonHeight);
  2140. boxes[i].onClick.Add(CheckboxHandler);
  2141. IF (parameters[i].default) & (parameters[i].resBoolean) THEN
  2142. boxes[i].caption.Set(Strings.NewString("X"));
  2143. ELSE
  2144. boxes[i].caption.Set(Strings.NewString(""));
  2145. END;
  2146. line.AddInternalComponent(boxes[i]);
  2147. ELSE
  2148. HALT(99); (* Unsupported parameter type *)
  2149. END;
  2150. ASSERT(vc[i] # NIL);
  2151. END;
  2152. vc[LEN(parameters)] := cancelBtn;
  2153. vc[LEN(parameters)+1] := okBtn;
  2154. ELSE
  2155. NEW(vc, 2); vc[0] := cancelBtn; vc[1] := okBtn;
  2156. END;
  2157. (* show PopupWindow text if there is any *)
  2158. IF text # NIL THEN
  2159. NEW(textView); textView.alignment.Set(WMComponents.AlignClient);
  2160. textView.isMultiLine.Set(TRUE); textView.showBorder.Set(FALSE);
  2161. textView.defaultTextColor.Set(WMGraphics.White);
  2162. textView.alwaysShowCursor.Set(FALSE);
  2163. textView.SetText(text);
  2164. textView.takesFocus.Set(FALSE);
  2165. parameterPanel.AddInternalComponent(textView);
  2166. END;
  2167. SetFocusChain;
  2168. CSChanged;
  2169. ASSERT((vc # NIL) & (LEN(vc) >= 2));
  2170. END BuildLayout;
  2171. PROCEDURE EvalParameters() : BOOLEAN;
  2172. VAR result : BOOLEAN; string : ARRAY 32 OF CHAR; temp : Strings.String; i : LONGINT;
  2173. BEGIN
  2174. IF parameters=NIL THEN result := TRUE;
  2175. ELSE
  2176. result := TRUE;
  2177. FOR i := 0 TO LEN(parameters)-1 DO
  2178. IF (parameters[i].type = ParString) OR (parameters[i].type = ParInteger) THEN
  2179. editors[i].GetAsString(string);
  2180. IF string # "" THEN
  2181. parameters[i].valid := TRUE;
  2182. IF parameters[i].type = ParInteger THEN
  2183. Strings.StrToInt(string, parameters[i].resInteger);
  2184. ELSIF parameters[i].type = ParString THEN
  2185. parameters[i].resString := ""; Strings.Append(parameters[i].resString, string);
  2186. END;
  2187. editors[i].fillColor.Set(WMGraphics.White);
  2188. ELSIF ~parameters[i].optional THEN
  2189. editors[i].fillColor.Set(WMGraphics.Red);
  2190. result := FALSE;
  2191. END;
  2192. ELSIF parameters[i].type = ParBoolean THEN
  2193. temp := boxes[i].caption.Get();
  2194. parameters[i].valid := TRUE;
  2195. parameters[i].resBoolean := temp^ = "X";
  2196. END;
  2197. END;
  2198. END;
  2199. RETURN result;
  2200. END EvalParameters;
  2201. PROCEDURE CheckboxHandler(sender, data : ANY);
  2202. VAR
  2203. checkbox : WMStandardComponents.Button;
  2204. string : Strings.String;
  2205. i : LONGINT;
  2206. BEGIN
  2207. checkbox := sender (WMStandardComponents.Button);
  2208. FOR i := 0 TO LEN(boxes)-1 DO
  2209. IF boxes[i]=checkbox THEN
  2210. string := checkbox.caption.Get();
  2211. IF string^ = "X" THEN string := Strings.NewString(""); ELSE string := Strings.NewString("X"); END;
  2212. checkbox.caption.Set(string);
  2213. checkbox.Reset(NIL, NIL);
  2214. END;
  2215. END;
  2216. END CheckboxHandler;
  2217. PROCEDURE Ok(sender, data : ANY);
  2218. BEGIN
  2219. IF EvalParameters() THEN
  2220. BEGIN {EXCLUSIVE} result := ResOk; END;
  2221. Close^;
  2222. ELSE
  2223. CSChanged; (* force redraw *)
  2224. END;
  2225. END Ok;
  2226. PROCEDURE Cancel(sender, data : ANY);
  2227. BEGIN
  2228. Close^; BEGIN {EXCLUSIVE} result := ResCancel; END;
  2229. END Cancel;
  2230. PROCEDURE Close*;
  2231. BEGIN
  2232. Close^; BEGIN {EXCLUSIVE} result := ResCancel; END;
  2233. END Close;
  2234. END PopupWindow;
  2235. TYPE
  2236. Window = OBJECT(WMComponents.FormWindow)
  2237. VAR
  2238. tabs : WMTabComponents.Tabs;
  2239. tabList : ARRAY NofTabs OF WMTabComponents.Tab;
  2240. tabPanels : ARRAY NofTabs OF WMComponents.VisualComponent;
  2241. tabPanel : WMStandardComponents.Panel;
  2242. curTabPanel : WMComponents.VisualComponent;
  2243. curTab : WMTabComponents.Tab;
  2244. partitionSelector : WMPartitionsComponents.PartitionSelector;
  2245. operationSelector : WMPartitionsComponents.OperationSelector;
  2246. operationspanel : WMStandardComponents.Panel; (* contains opScollBarX/Y, oppanel *)
  2247. (* operation panel *)
  2248. selectedPlugin : Plugin; (* currently selected plugin, NIL if no plugin is selected *)
  2249. refreshBtn, showDetailsBtn : WMStandardComponents.Button;
  2250. pluginPanel : WMStandardComponents.Panel; (* contains selectedPanel *)
  2251. (* status bar *)
  2252. statusLabel : WMStandardComponents.Label;
  2253. width, height : LONGINT; (* caches "window size"; needed for correct update when downscaled *)
  2254. PROCEDURE &New*(c : WMRestorable.Context);
  2255. VAR configuration : WMRestorable.XmlElement; scale, showDetails : BOOLEAN;
  2256. BEGIN
  2257. scale := FALSE; showDetails := TRUE;
  2258. IF c # NIL THEN
  2259. width := c.r - c.l; height := c.b - c.t;
  2260. configuration := WMRestorable.GetElement(c, "Configuration");
  2261. IF configuration # NIL THEN
  2262. WMRestorable.LoadLongint(configuration, "Width", width);
  2263. WMRestorable.LoadLongint(configuration, "Height", height);
  2264. WMRestorable.LoadBoolean(configuration, "Details", showDetails);
  2265. IF (width < WindowMinWidth) OR (height < WindowMinHeight) THEN
  2266. (* First render window in real size and then scale it down to the size specified by the context *)
  2267. scale := TRUE;
  2268. END;
  2269. END;
  2270. ELSE
  2271. width := DefaultWidth; height := DefaultHeight;
  2272. END;
  2273. Init(width, height, FALSE);
  2274. SetTitle(WMWindowManager.NewString("Partition Tool"));
  2275. SetIcon(WMGraphics.LoadImage("WMIcons.tar://WMPartitions.png", TRUE));
  2276. scaling := FALSE;
  2277. SetContent(CreateForm());
  2278. partitionSelector.showDetails.Set(showDetails);
  2279. showDetailsBtn.SetPressed(showDetails);
  2280. IF c # NIL THEN
  2281. WMRestorable.AddByContext(SELF, c);
  2282. IF scale THEN Resized(c.r - c.l, c.b - c.t); END;
  2283. ELSE
  2284. WMWindowManager.AddWindow (SELF, 100, 100);
  2285. manager := WMWindowManager.GetDefaultManager ();
  2286. manager.SetFocus(SELF);
  2287. END;
  2288. PartitionsLib.infobus.AddListener(CompletionHandler);
  2289. END New;
  2290. PROCEDURE CreateForm() : WMComponents.VisualComponent;
  2291. VAR
  2292. panel, upperpanel, lowerpanel, line : WMStandardComponents.Panel;
  2293. operationPanel : WMStandardComponents.GroupPanel;
  2294. resizer : WMStandardComponents.Resizer;
  2295. plugin : Plugin;
  2296. fsTools : FSToolsPlugin;
  2297. partitions : PartitionsPlugin;
  2298. bluebottle : A2Plugin;
  2299. scavenger : ScavengerPlugin;
  2300. tests : TestsPlugin;
  2301. operations : OperationsPlugin;
  2302. caption : ARRAY 32 OF CHAR;
  2303. i : LONGINT;
  2304. BEGIN
  2305. NEW(panel); panel.alignment.Set(WMComponents.AlignClient);
  2306. IF ~UseSkinColors THEN panel.fillColor.Set(MarginColor); END;
  2307. NEW(line); line.alignment.Set(WMComponents.AlignBottom);
  2308. IF ~UseSkinColors THEN line.fillColor.Set(StatusBarBgColor); END;
  2309. line.bounds.SetHeight(StatusBarHeight);
  2310. panel.AddContent(line);
  2311. NEW(statusLabel); statusLabel.alignment.Set(WMComponents.AlignClient);
  2312. statusLabel.bearing.Set(WMRectangles.MakeRect(10, 0, 0, 0));
  2313. IF ~UseSkinColors THEN
  2314. statusLabel.fillColor.Set(StatusBarBgColor);
  2315. statusLabel.textColor.Set(WMGraphics.White);
  2316. END;
  2317. statusLabel.caption.Set(Strings.NewString(" Ready"));
  2318. line.AddInternalComponent(statusLabel);
  2319. NEW(operationPanel); operationPanel.alignment.Set(WMComponents.AlignBottom);
  2320. operationPanel.bounds.SetHeight(90);
  2321. panel.AddInternalComponent(operationPanel);
  2322. NEW(line); line.alignment.Set(WMComponents.AlignTop);
  2323. line.bounds.SetHeight(ButtonHeight);
  2324. operationPanel.AddInternalComponent(line);
  2325. NEW(showDetailsBtn); showDetailsBtn.alignment.Set(WMComponents.AlignRight);
  2326. showDetailsBtn.bearing.Set(WMRectangles.MakeRect(ButtonSpacer, 0, 0, 0));
  2327. showDetailsBtn.isToggle.Set(TRUE); showDetailsBtn.onClick.Add(ShowDetails);
  2328. showDetailsBtn.caption.Set(Strings.NewString("Details"));
  2329. line.AddInternalComponent(showDetailsBtn);
  2330. NEW(refreshBtn); refreshBtn.alignment.Set(WMComponents.AlignRight);
  2331. refreshBtn.bearing.Set(WMRectangles.MakeRect(ButtonSpacer, 0, 0, 0));
  2332. refreshBtn.onClick.Add(Refresh); refreshBtn.caption.Set(Strings.NewString("Refresh"));
  2333. line.AddInternalComponent(refreshBtn);
  2334. NEW(tabs); tabs.alignment.Set(WMComponents.AlignClient);
  2335. tabs.clDefault.Set(WMGraphics.Black);
  2336. tabs.clSelected.Set(0404040B0H);
  2337. tabs.onSelectTab.Add(TabSelected);
  2338. line.AddContent(tabs);
  2339. NEW(tabPanel); tabPanel.alignment.Set(WMComponents.AlignClient);
  2340. operationPanel.AddContent(tabPanel);
  2341. FOR i := 0 TO NofTabs-1 DO
  2342. CASE i OF
  2343. |0: NEW(fsTools); plugin := fsTools; caption := "FSTools"; selectedPlugin := plugin;
  2344. |1: NEW(partitions); plugin := partitions; caption := "Partitions";
  2345. |2: NEW(scavenger); plugin := scavenger; caption := "Scavenger";
  2346. |3: NEW(bluebottle); plugin := bluebottle; caption := "A2";
  2347. |4: NEW(tests); plugin := tests; caption := "Testing";
  2348. |5: NEW(operations); plugin := operations; caption := "Operations";
  2349. END;
  2350. plugin.owner := SELF;
  2351. tabPanels[i] := plugin;
  2352. tabPanels[i].alignment.Set(WMComponents.AlignClient);
  2353. tabPanels[i].bearing.Set(WMRectangles.MakeRect(0, MarginV, 0, 0));
  2354. tabPanels[i].visible.Set(FALSE);
  2355. tabList[i] := tabs.NewTab(); tabs.AddTab(tabList[i]);
  2356. tabs.SetTabCaption(tabList[i], Strings.NewString(caption));
  2357. tabs.SetTabData(tabList[i], tabPanels[i]);
  2358. tabPanel.AddContent(tabPanels[i]);
  2359. END;
  2360. curTabPanel := fsTools; curTab := tabList[0]; curTabPanel.visible.Set(TRUE);
  2361. NEW(operationSelector); operationSelector.alignment.Set(WMComponents.AlignClient);
  2362. ASSERT(operationSelector # NIL);
  2363. operations.SetSelector(operationSelector);
  2364. NEW(pluginPanel); pluginPanel.alignment.Set(WMComponents.AlignNone);
  2365. operationPanel.AddInternalComponent(pluginPanel);
  2366. NEW(upperpanel); upperpanel.alignment.Set(WMComponents.AlignClient);
  2367. panel.AddInternalComponent(upperpanel);
  2368. NEW(lowerpanel); lowerpanel.alignment.Set(WMComponents.AlignBottom);
  2369. lowerpanel.bounds.SetHeight(45);
  2370. upperpanel.AddInternalComponent(lowerpanel);
  2371. NEW(resizer); resizer.bounds.SetHeight(4); resizer.alignment.Set(WMComponents.AlignTop);
  2372. lowerpanel.AddInternalComponent(resizer);
  2373. NEW(operationspanel);
  2374. operationspanel.alignment.Set(WMComponents.AlignClient);
  2375. operationspanel.AddInternalComponent(operationSelector);
  2376. lowerpanel.AddInternalComponent(operationspanel);
  2377. NEW(partitionSelector); partitionSelector.alignment.Set(WMComponents.AlignClient);
  2378. partitionSelector.bearing.Set(WMRectangles.MakeRect(0, 0, 0, MarginV));
  2379. partitionSelector.onSelection.Add(PartitionSelected);
  2380. upperpanel.AddInternalComponent(partitionSelector);
  2381. RETURN panel;
  2382. END CreateForm;
  2383. PROCEDURE Resized*(width, height : LONGINT);
  2384. BEGIN
  2385. IF (width >= WindowMinWidth) & (height >= WindowMinHeight) THEN
  2386. scaling := FALSE;
  2387. SELF.width := width; SELF.height := height;
  2388. ELSE
  2389. scaling := TRUE;
  2390. END;
  2391. Resized^(width, height);
  2392. END Resized;
  2393. PROCEDURE TabSelected(sender, data : ANY);
  2394. VAR tab : WMTabComponents.Tab; selection : WMPartitionsComponents.Selection;
  2395. BEGIN
  2396. IF (data # NIL) & (data IS WMTabComponents.Tab) THEN
  2397. DisableUpdate;
  2398. tab := data(WMTabComponents.Tab);
  2399. IF (tab.data # NIL) & (tab.data IS WMComponents.VisualComponent) THEN
  2400. curTabPanel.visible.Set(FALSE);
  2401. curTab := tab;
  2402. curTabPanel := tab.data(WMComponents.VisualComponent);
  2403. curTabPanel.visible.Set(TRUE);
  2404. tabPanel.Reset(SELF, NIL);
  2405. tabPanel.AlignSubComponents;
  2406. END;
  2407. EnableUpdate;
  2408. tabPanel.Invalidate;
  2409. curTabPanel.Invalidate;
  2410. END;
  2411. ASSERT((curTabPanel # NIL) & (curTabPanel IS Plugin));
  2412. selectedPlugin := curTabPanel (Plugin);
  2413. selection := partitionSelector.GetSelection();
  2414. UpdateSelection(selection);
  2415. END TabSelected;
  2416. PROCEDURE CompletionHandler(operation : PartitionsLib.Operation; CONST message : ARRAY OF CHAR);
  2417. BEGIN
  2418. UpdateStatusLabel(Strings.NewString(message));
  2419. END CompletionHandler;
  2420. (** Set string displayed by the Partition Viewer's status bar *)
  2421. PROCEDURE UpdateStatusLabel(string : Strings.String);
  2422. BEGIN
  2423. statusLabel.caption.Set(string);
  2424. END UpdateStatusLabel;
  2425. PROCEDURE ShowDetails(sender, data : ANY);
  2426. VAR showDetails : BOOLEAN;
  2427. BEGIN
  2428. showDetails := showDetailsBtn.GetPressed();
  2429. partitionSelector.showDetails.Set(showDetails);
  2430. END ShowDetails;
  2431. PROCEDURE Refresh(sender, data : ANY);
  2432. BEGIN
  2433. PartitionsLib.diskModel.Update;
  2434. END Refresh;
  2435. PROCEDURE WheelMove*(dz : LONGINT);
  2436. BEGIN
  2437. partitionSelector.WheelMove(dz);
  2438. END WheelMove;
  2439. PROCEDURE PartitionSelected(sender, data : ANY);
  2440. BEGIN
  2441. IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.PartitionSelected, sender, data);
  2442. ELSIF (data # NIL) & (data IS WMPartitionsComponents.SelectionWrapper) THEN
  2443. UpdateSelection(data(WMPartitionsComponents.SelectionWrapper).selection);
  2444. END;
  2445. END PartitionSelected;
  2446. (** Update Layout & Contents *)
  2447. PROCEDURE UpdateContent*;
  2448. BEGIN
  2449. partitionSelector.Synchronize;
  2450. END UpdateContent;
  2451. PROCEDURE UpdateSelection(selection : WMPartitionsComponents.Selection);
  2452. VAR caption, temp : ARRAY 128 OF CHAR; res : WORD;
  2453. BEGIN
  2454. caption := "";
  2455. IF ((selection.disk.device = NIL) OR (selection.partition = -1)) THEN (* selection: none *)
  2456. Strings.Append(caption, "n/a");
  2457. ELSE
  2458. Strings.Append(caption, selection.disk.device.name); Strings.Append(caption, "#");
  2459. Strings.IntToStr(selection.partition, temp); Strings.Append(caption, temp);
  2460. END;
  2461. IF selectedPlugin # NIL THEN
  2462. res := selectedPlugin.SelectionUpdated(selection);
  2463. END;
  2464. END UpdateSelection;
  2465. PROCEDURE Close*;
  2466. BEGIN
  2467. Close^;
  2468. PartitionsLib.infobus.RemoveListener(CompletionHandler);
  2469. window := NIL;
  2470. END Close;
  2471. PROCEDURE Handle*(VAR x: WMMessages.Message);
  2472. VAR configuration : WMRestorable.XmlElement;
  2473. BEGIN
  2474. IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) THEN
  2475. IF (x.ext IS WMRestorable.Storage) THEN
  2476. NEW(configuration); configuration.SetName("Configuration");
  2477. WMRestorable.StoreLongint(configuration, "Width", width);
  2478. WMRestorable.StoreLongint(configuration, "Height", height);
  2479. WMRestorable.StoreBoolean(configuration, "Details", showDetailsBtn.GetPressed());
  2480. x.ext(WMRestorable.Storage).Add("PartitionTool", "Restore", SELF, configuration);
  2481. ELSE Handle^(x)
  2482. END
  2483. ELSE Handle^(x)
  2484. END
  2485. END Handle;
  2486. END Window;
  2487. TYPE
  2488. (* This is a special case plugin. It provides access to disk operations (PartitionsLib.Operation) which are registered at the disk
  2489. * operation manager (PartitionsLib.OperationManager).
  2490. *)
  2491. OperationsPlugin = OBJECT(Plugin);
  2492. VAR
  2493. abort, remove, showerrors : WMStandardComponents.Button;
  2494. finished, all, selected : WMStandardComponents.Button; (* check boxes *)
  2495. removeMode : LONGINT; (* RemoveSelected | RemoveFinished | RemoveAll *)
  2496. info : WMStandardComponents.Label;
  2497. selector : WMPartitionsComponents.OperationSelector;
  2498. PROCEDURE &Init*;
  2499. VAR left : LONGINT; label : WMStandardComponents.Label;
  2500. BEGIN
  2501. Init^;
  2502. NEW(abort); left := 0;
  2503. abort.bounds.SetExtents(ButtonWidth, ButtonHeight); abort.bounds.SetLeft(left); abort.bounds.SetTop(0);
  2504. abort.onClick.Add(Abort); abort.SetCaption("Abort");
  2505. AddInternalComponent(abort);
  2506. NEW(showerrors); left := left + ButtonWidth + ButtonSpacer;
  2507. showerrors.bounds.SetExtents(ButtonWidth, ButtonHeight); showerrors.bounds.SetLeft(left); showerrors.bounds.SetTop(0);
  2508. showerrors.onClick.Add(Showerrors); showerrors.SetCaption("Report");
  2509. AddInternalComponent(showerrors);
  2510. NEW(remove); left := left + ButtonWidth + ButtonSpacer;
  2511. remove.bounds.SetExtents(ButtonWidth, ButtonHeight); remove.bounds.SetLeft(left); remove.bounds.SetTop(0);
  2512. remove.onClick.Add(Remove); remove.SetCaption("Remove");
  2513. AddInternalComponent(remove);
  2514. (* check boxes *)
  2515. removeMode := RemoveSelected;
  2516. NEW(selected); left := left + ButtonWidth + ButtonSpacer;
  2517. selected.bounds.SetExtents(ButtonHeight, ButtonHeight); selected.bounds.SetLeft(left); selected.bounds.SetTop(0);
  2518. selected.onClick.Add(CheckBoxes); selected.caption.Set(Strings.NewString("X"));
  2519. AddInternalComponent(selected);
  2520. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  2521. label.bounds.SetExtents(50, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(0);
  2522. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  2523. label.caption.Set(Strings.NewString("Selected"));
  2524. AddInternalComponent(label);
  2525. NEW(finished); left := left + 50 + ButtonSpacer;
  2526. finished.bounds.SetExtents(ButtonHeight, ButtonHeight); finished.bounds.SetLeft(left); finished.bounds.SetTop(0);
  2527. finished.onClick.Add(CheckBoxes); finished.caption.Set(Strings.NewString(""));
  2528. AddInternalComponent(finished);
  2529. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  2530. label.bounds.SetExtents(50, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(0);
  2531. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  2532. label.caption.Set(Strings.NewString("Finished"));
  2533. AddInternalComponent(label);
  2534. NEW(all); left := left + 50 + ButtonSpacer;
  2535. all.bounds.SetExtents(ButtonHeight, ButtonHeight); all.bounds.SetLeft(left); all.bounds.SetTop(0);
  2536. all.onClick.Add(CheckBoxes); all.caption.Set(Strings.NewString(""));
  2537. AddInternalComponent(all);
  2538. NEW(label); left := left + ButtonHeight + ButtonSpacer;
  2539. label.bounds.SetExtents(50, ButtonHeight); label.bounds.SetLeft(left); label.bounds.SetTop(0);
  2540. IF ~UseSkinColors THEN label.fillColor.Set(BackgroundColor); label.textColor.Set(WMGraphics.White); END;
  2541. label.caption.Set(Strings.NewString("All"));
  2542. AddInternalComponent(label);
  2543. NEW(info);
  2544. info.bounds.SetLeft(0); info.bounds.SetTop(ButtonHeight + ButtonSpacer);
  2545. IF ~UseSkinColors THEN info.fillColor.Set(BackgroundColor); info.textColor.Set(WMGraphics.White); END;
  2546. info.caption.Set(Strings.NewString(" Selected operation: none"));
  2547. AddInternalComponent(info);
  2548. selector := NIL;
  2549. END Init;
  2550. PROCEDURE SetSelector(selector : WMPartitionsComponents.OperationSelector);
  2551. BEGIN
  2552. Acquire;
  2553. SELF.selector := selector;
  2554. selector.onSelection.Add(OnOperationSelected);
  2555. UpdateInfoLabel(GetSelectedOperation());
  2556. Release;
  2557. END SetSelector;
  2558. PROCEDURE GetSelectedOperation() : WMPartitionsComponents.Operation;
  2559. VAR operation : WMPartitionsComponents.Operation;
  2560. BEGIN
  2561. Acquire;
  2562. IF (selector # NIL) THEN operation := selector.GetSelection();
  2563. ELSE operation := NIL;
  2564. END;
  2565. Release;
  2566. RETURN operation;
  2567. END GetSelectedOperation;
  2568. PROCEDURE OnOperationSelected(sender, data : ANY);
  2569. VAR operation : WMPartitionsComponents.Operation;
  2570. BEGIN
  2571. IF (data # NIL) & (data IS WMPartitionsComponents.OperationWrapper) THEN
  2572. operation := data(WMPartitionsComponents.OperationWrapper).operation;
  2573. UpdateInfoLabel(operation);
  2574. END;
  2575. END OnOperationSelected;
  2576. PROCEDURE UpdateInfoLabel(operation : WMPartitionsComponents.Operation);
  2577. VAR w : Streams.StringWriter; string : ARRAY 256 OF CHAR;
  2578. BEGIN
  2579. IF (operation # NIL) THEN
  2580. NEW(w, LEN(string));
  2581. w.String(" Selected operation: "); w.String("UID "); w.Int(operation.uid, 0); w.String(": ");
  2582. w.String(operation.name); w.String(" ("); w.String(operation.desc); w.String(")");
  2583. w.Get(string);
  2584. info.caption.Set(Strings.NewString(string));
  2585. ELSE
  2586. info.caption.Set(Strings.NewString(" Selected operation: none"));
  2587. END;
  2588. END UpdateInfoLabel;
  2589. PROCEDURE CheckBoxes(sender, data : ANY);
  2590. VAR button : WMStandardComponents.Button;
  2591. BEGIN
  2592. button := sender (WMStandardComponents.Button);
  2593. (* clear all check boxes *)
  2594. selected.caption.Set(Strings.NewString(""));
  2595. finished.caption.Set(Strings.NewString(""));
  2596. all.caption.Set(Strings.NewString(""));
  2597. IF button = selected THEN
  2598. removeMode := RemoveSelected;
  2599. selected.caption.Set(Strings.NewString("X"));
  2600. ELSIF button = finished THEN
  2601. removeMode := RemoveFinished;
  2602. finished.caption.Set(Strings.NewString("X"));
  2603. ELSIF button = all THEN
  2604. removeMode := RemoveAll;
  2605. all.caption.Set(Strings.NewString("X"));
  2606. ELSE
  2607. HALT(399);
  2608. END;
  2609. END CheckBoxes;
  2610. PROCEDURE Resized*;
  2611. BEGIN
  2612. Resized^;
  2613. info.bounds.SetExtents(bounds.GetWidth(), ButtonHeight);
  2614. END Resized;
  2615. (* we don't care about which disk is currently selected *)
  2616. PROCEDURE SelectionUpdated(selection : WMPartitionsComponents.Selection): LONGINT;
  2617. VAR selector : WMPartitionsComponents.OperationSelector; operation : WMPartitionsComponents.Operation;
  2618. BEGIN
  2619. selector := SELF.selector;
  2620. IF (selector # NIL) THEN
  2621. operation := selector.GetSelection();
  2622. ELSE
  2623. operation := NIL;
  2624. END;
  2625. UpdateInfoLabel(operation);
  2626. RETURN SelectionNotSupported;
  2627. END SelectionUpdated;
  2628. PROCEDURE Abort(sender, data : ANY);
  2629. VAR selectedOperation : WMPartitionsComponents.Operation; result : ARRAY 256 OF CHAR; temp : ARRAY 10 OF CHAR;
  2630. BEGIN
  2631. selectedOperation := GetSelectedOperation();
  2632. IF selectedOperation # NIL THEN
  2633. selectedOperation.Abort;
  2634. result := "UID ";
  2635. Strings.IntToStr(selectedOperation.uid, temp); Strings.Append(result, temp);
  2636. Strings.Append(result, " : "); Strings.Append(result, "Operation aborted");
  2637. ELSE
  2638. result := "No operation selected";
  2639. END;
  2640. owner.UpdateStatusLabel(Strings.NewString(result));
  2641. END Abort;
  2642. PROCEDURE Remove(sender, data : ANY);
  2643. VAR selectedOperation : WMPartitionsComponents.Operation; result : ARRAY 256 OF CHAR; temp : ARRAY 10 OF CHAR; num : LONGINT;
  2644. BEGIN
  2645. ASSERT(PartitionsLib.operations # NIL);
  2646. selectedOperation := GetSelectedOperation();
  2647. IF removeMode = RemoveSelected THEN
  2648. IF selectedOperation # NIL THEN
  2649. result := "UID ";
  2650. Strings.IntToStr(selectedOperation.uid, temp); Strings.Append(result, temp);
  2651. Strings.Append(result, " : "); Strings.Append(result, "Operation removed");
  2652. IF PartitionsLib.operations.Remove(selectedOperation) THEN
  2653. result := "UID ";
  2654. Strings.IntToStr(selectedOperation.uid, temp); Strings.Append(result, temp);
  2655. Strings.Append(result, " : "); Strings.Append(result, "Operation removed");
  2656. selectedOperation := NIL;
  2657. info.caption.Set(Strings.NewString(" Selected operation: none"));
  2658. ELSE
  2659. result := "Could not remove operation";
  2660. END;
  2661. ELSE
  2662. result := "No operation selected";
  2663. END;
  2664. ELSIF removeMode = RemoveFinished THEN
  2665. num := PartitionsLib.operations.RemoveAll(TRUE);
  2666. Strings.IntToStr(num, temp);
  2667. result := ""; Strings.Append(result, temp); Strings.Append(result, " finished operations removed");
  2668. selectedOperation := NIL;
  2669. info.caption.Set(Strings.NewString(" Selected operation: none"));
  2670. ELSIF removeMode = RemoveAll THEN
  2671. num := PartitionsLib.operations.RemoveAll(FALSE);
  2672. Strings.IntToStr(num, temp);
  2673. result := ""; Strings.Append(result, temp); Strings.Append(result, " operations removed");
  2674. selectedOperation := NIL;
  2675. info.caption.Set(Strings.NewString(" Selected operation: none"));
  2676. ELSE
  2677. HALT(398);
  2678. END;
  2679. owner.UpdateStatusLabel(Strings.NewString(result));
  2680. END Remove;
  2681. PROCEDURE Showerrors(sender, data : ANY);
  2682. VAR
  2683. selectedOperation : WMPartitionsComponents.Operation;
  2684. text : Texts.Text; reportWindow : ReportWindow; result : ARRAY 256 OF CHAR; temp : ARRAY 10 OF CHAR;
  2685. BEGIN
  2686. selectedOperation := owner.operationSelector.GetSelection();
  2687. IF selectedOperation # NIL THEN
  2688. result := "UID ";
  2689. Strings.IntToStr(selectedOperation.uid, temp); Strings.Append(result, temp);
  2690. Strings.Append(result, " : "); Strings.Append(result, "Showing status report");
  2691. text := selectedOperation.GetReport(TRUE);
  2692. NEW(reportWindow, text, 500, 200, FALSE);
  2693. reportWindow.Show();
  2694. ELSE
  2695. result := "No operation selected";
  2696. END;
  2697. owner.UpdateStatusLabel(Strings.NewString(result));
  2698. END Showerrors;
  2699. PROCEDURE Finalize*;
  2700. BEGIN
  2701. Finalize^;
  2702. Acquire;
  2703. IF (selector # NIL) THEN selector.onSelection.Remove(OnOperationSelected); END;
  2704. Release;
  2705. END Finalize;
  2706. END OperationsPlugin;
  2707. VAR
  2708. window : Window;
  2709. PROCEDURE Cleanup;
  2710. BEGIN {EXCLUSIVE}
  2711. IF window # NIL THEN window.Close; window := NIL; END;
  2712. END Cleanup;
  2713. PROCEDURE Open*;
  2714. BEGIN {EXCLUSIVE}
  2715. IF window = NIL THEN
  2716. NEW(window, NIL);
  2717. ELSE
  2718. window.manager.SetFocus(window);
  2719. window.manager.ToFront(window);
  2720. END;
  2721. END Open;
  2722. PROCEDURE Restore*(context : WMRestorable.Context);
  2723. BEGIN
  2724. NEW(window, context);
  2725. END Restore;
  2726. BEGIN
  2727. Modules.InstallTermHandler(Cleanup);
  2728. END WMPartitions.
  2729. WMPartitions.Open ~
  2730. System.Free WMPartitions WMPartitionsComponents ~
  2731. PC.Compile \s PartitionsLib.Mod Partitions.Mod FATScavenger.Mod DiskBenchmark.Mod DiskTests.Mod WMPartitionsComponents.Mod WMPartitions.Mod ~
  2732. System.FreeDownTo WMPartitions ~