Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

settingsStorage.html 57KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705
  1. <!--
  2. VM Storage Settings
  3. Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com)
  4. $Id: settingsStorage.html 599 2015-07-27 10:40:37Z imoore76 $
  5. -->
  6. <table style='width: 100%;' id='vboxSettingsStorageTableWrapper'>
  7. <tr style='height: 100%'>
  8. <td width='50%' style='padding: 6px;'>
  9. <div id='vboxStoragePaneLeft'>
  10. <table class='vboxSettingsHeadingLine'
  11. style='width: 100%; border-spacing: 0; border: 0px; margin: 0px; padding: 0px;'>
  12. <tr style='vertical-align: middle'>
  13. <td style='white-space: nowrap; width: auto;'><span
  14. class='translate vboxRunningEnabled'>Storage Tree</span></td>
  15. <td style='width: 100%'>
  16. <hr style='width: 100%;' class='vboxSeparatorLine'/>
  17. </td>
  18. </tr>
  19. </table>
  20. <!-- Storage Controllers -->
  21. <div id='vboxSettingsStorageTree' style='height: 290px; outline: none;' class='vboxBordered' tabindex='0'>
  22. <ul class='vboxHover vboxHoverBorderless'>
  23. <li>Storage Thingy</li>
  24. <li>
  25. <ul>
  26. <li>Attachment Thingy</li>
  27. </ul>
  28. </li>
  29. </ul>
  30. </div>
  31. <!-- Controller Toolbar -->
  32. <div id='vboxSettingsControllersButtons' style='text-align: right'></div>
  33. </div>
  34. </td>
  35. <!-- Resize Bar -->
  36. <td style='height: 100%; width:3px; padding:0px; margin:0px;'>
  37. <div style='margin:0px; margin-top: 2px; padding:0px; width: 3px; height: 99%; background:#aaa;' id='vboxStorageResizeBar' ></div>
  38. </td>
  39. <td width='50%' style='padding: 6px;'>
  40. <div id='vboxStoragePaneRight'>
  41. <table class='vboxSettingsHeadingLine'
  42. style='width: 100%; border-spacing: 0; border: 0px; margin: 0px; padding: 0px;'>
  43. <tr style='vertical-align: middle'>
  44. <td style='white-space: nowrap; width: auto;'><span
  45. class='translate vboxRunningEnabled'>Attributes</span></td>
  46. <td style='width: 100%; white-space: nowrap;'><hr style='width: 100%;' class='vboxSeparatorLine'/></td>
  47. </tr>
  48. </table>
  49. <!-- Controller Settings -->
  50. <div id='vboxSettingsController' style='width: 100%; display: none;'>
  51. <table style='width: 100%' class='vboxVertical'>
  52. <tr>
  53. <th><span class='translate'>Name:</span></th>
  54. <td style='width: 100%'><input type='text' class='vboxText'
  55. name='vboxSettingsStorageItemName' style='width: 99%' /></td>
  56. </tr>
  57. <tr>
  58. <th><span class='translate'>Type:</span></th>
  59. <td><select name='vboxSettingsStorageControllerType'
  60. style='width: 100%'>
  61. <option value='ICH6'>ICH6</option>
  62. </select></td>
  63. </tr>
  64. <tr id='vboxSettingsControllerPortCountRow' style='display: none'>
  65. <th><span class='translate'>Port Count:</span></th>
  66. <td>
  67. <select name='vboxSettingsControllerPortCount'>
  68. </select>
  69. </td>
  70. </tr>
  71. <tr>
  72. <th></th>
  73. <td style='width: 100%'>
  74. <label><input type='checkbox' class='vboxCheckbox'
  75. name='vboxSettingsStorageHostCache'/> <span class='translate'>Use Host I/O Cache</span></label></td>
  76. </tr>
  77. </table>
  78. </div>
  79. <!-- Attachment Settings -->
  80. <div id='vboxSettingsStorageAttachment' style='display: none'>
  81. <table class='vboxVertical'>
  82. <tr style='vertical-align: middle;'>
  83. <th><span class='translate vboxRunningEnabled' id='vboxSettingsControllerSlotLabel'>HardDisk</span></th>
  84. <td style='width: 100%'>
  85. <table class='vboxInvisible' style='width: 100%'>
  86. <tr style='vertical-align: middle'>
  87. <td style='width: 100%'>
  88. <select name='vboxSettingsControllerSlot' style='width: 100%'></select>
  89. </td>
  90. <td>
  91. <div id='vboxSettingsAddAttachmentsMenuHDDiv' style='display: none'></div>
  92. <div id='vboxSettingsAddAttachmentsMenuFDDiv' style='display: none'></div>
  93. <div id='vboxSettingsAddAttachmentsMenuCDDiv' style='display: none'></div>
  94. </td>
  95. </tr>
  96. </table>
  97. </td>
  98. </tr>
  99. </table>
  100. </div>
  101. <!-- Selected Media Info -->
  102. <div id='vboxSettingsMediaInfo' style='display: none'>
  103. <table class='vboxSettingsHeadingLine'
  104. style='width: 100%; border-spacing: 0; border: 0px; margin: 0px; padding: 0px;'>
  105. <tr style='vertical-align: middle'>
  106. <td style='white-space: nowrap; width: auto;'><span
  107. class='translate vboxRunningEnabled'>Information</span></td>
  108. <td style='width: 100%'>
  109. <hr style='width: 100%; ' class='vboxSeparatorLine'/>
  110. </td>
  111. </tr>
  112. </table>
  113. <!-- HardDisk Media -->
  114. <div id='vboxSettingsHDInfo'>
  115. <table class='vboxVertical'>
  116. <tr>
  117. <th><span class='translate vboxRunningEnabled'>Type (Format):</span></th>
  118. <td><span id='vboxSettingsHDtype' class='vboxRunningEnabled'>Image</span></td>
  119. </tr>
  120. <tr>
  121. <th><span class='translate vboxRunningEnabled'>Virtual Size:</span></th>
  122. <td><span id='vboxSettingsHDvsize' class='vboxRunningEnabled'>30 GB</span></td>
  123. </tr>
  124. <tr>
  125. <th><span class='translate vboxRunningEnabled'>Actual Size:</span></th>
  126. <td><span id='vboxSettingsHDasize' class='vboxRunningEnabled'>30 GB</span></td>
  127. </tr>
  128. <tr>
  129. <th><span class='translate vboxRunningEnabled'>Details:</span></th>
  130. <td><span id='vboxSettingsHDDetails' class='vboxRunningEnabled'>Dynamic</span></td>
  131. </tr>
  132. <tr>
  133. <th><span class='translate vboxRunningEnabled'>Location:</span></th>
  134. <td><span id='vboxSettingsHDlocation' class='vboxRunningEnabled'>/usr/local/blah/etc..</span></td>
  135. </tr>
  136. <tr>
  137. <th><span class='translate vboxRunningEnabled'>Attached to:</span></th>
  138. <td><span id='vboxSettingsHDattached' class='vboxRunningEnabled'>Some Virtual
  139. Machine Name</span></td>
  140. </tr>
  141. <tr>
  142. <th><span class='translate vboxRunningEnabled'>Encrypted with key:</span></th>
  143. <td><span id='vboxSettingsHDEncrypted' class='vboxRunningEnabled'>--</span></td>
  144. </tr>
  145. </table>
  146. </div>
  147. <!-- DVD/CD Media and Floppy -->
  148. <div id='vboxSettingsImageInfo'>
  149. <table class='vboxVertical'>
  150. <tr>
  151. <th><span class='translate vboxRunningEnabled'>Type:</span></th>
  152. <td><span id='vboxSettingsImageType' class='vboxRunningEnabled'>Image</span></td>
  153. </tr>
  154. <tr>
  155. <th><span class='translate vboxRunningEnabled'>Size:</span></th>
  156. <td><span id='vboxSettingsImageSize' class='vboxRunningEnabled'>30 GB</span></td>
  157. </tr>
  158. <tr>
  159. <th><span class='translate vboxRunningEnabled'>Location:</span></th>
  160. <td><span id='vboxSettingsImageLocation' class='vboxRunningEnabled'>/usr/local/blah/etc..</span></td>
  161. </tr>
  162. <tr>
  163. <th><span class='translate vboxRunningEnabled'>Attached to:</span></th>
  164. <td><span id='vboxSettingsImageAttached' class='vboxRunningEnabled'>Some Virtual
  165. Machine Name</span></td>
  166. </tr>
  167. </table>
  168. </div>
  169. </div>
  170. </div>
  171. </td>
  172. </tr>
  173. </table>
  174. <script type='text/javascript'>
  175. /*
  176. *
  177. * Storage controller helper object
  178. *
  179. *
  180. */
  181. var vboxSettingsStorageObj = function() {
  182. this.busTypes = vboxStorage.getBusTypes();
  183. this.attachedDirectMedia = {};
  184. this.attachedIndirectMedia = {};
  185. /* Return slots available on controller, including incl (device currently on slot) */
  186. this.availableSlots = function(conElm,incl) {
  187. var bus = $(conElm).children('table').first().data('controller').bus;
  188. var slots = vboxStorage[bus].slots();
  189. var atts = $(conElm).find('table.vboxSettingsStorageAttachment');
  190. for(var i = 0; i < atts.length; i++) {
  191. slot = $(atts[i]).data('attachment').port+'-'+$(atts[i]).data('attachment').device;
  192. if(incl && (incl == slot)) continue;
  193. delete slots[slot];
  194. }
  195. return slots;
  196. };
  197. this.addAttached = function(m) {
  198. if(!m || !m.id) return;
  199. var medium = vboxMedia.getMediumById(m.id);
  200. // SafeGuard
  201. if(!medium) {
  202. alert('A medium listed as attached to this machine was not found in the media registry. phpVirtualBox will now reload.');
  203. location.reload(true);
  204. }
  205. this.attachedDirectMedia[medium.id] = medium;
  206. if(medium.base) {
  207. this.attachedIndirectMedia[medium.base] = medium;
  208. }
  209. };
  210. this.isAttached = function(m,directOnly) {
  211. if(!m || !m.id) return false;
  212. if(this.attachedDirectMedia[m.id]) return this.attachedDirectMedia[m.id];
  213. if(!directOnly) {
  214. return (m.base ? this.attachedIndirectMedia[m.base] : null);
  215. }
  216. return false;
  217. };
  218. this.isAttachedDirect = function(m) { return this.attachedDirectMedia[m.id]; };
  219. this.isAttachedIndirect = function(m) { return (m.base ? this.attachedIndirectMedia[m.base] : null); };
  220. };
  221. /*
  222. *
  223. *
  224. * Initialization logic
  225. *
  226. *
  227. */
  228. /* Storage Obj */
  229. var vboxSettingsStorageBusses = new vboxSettingsStorageObj(); // defined below
  230. /* Setup SATA port count */
  231. var sel = document.forms['frmVboxSettings'].vboxSettingsControllerPortCount;
  232. for(var i = 1; i <= vboxStorage.SATA.maxPortCount; i++) {
  233. sel.options[sel.options.length] = new Option(i,i);
  234. }
  235. $(sel).change(function(){
  236. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().data('controller').portCount = $(this).val();
  237. });
  238. /* Pre-load storage images */
  239. var imgs = new Array();
  240. for(var i=0;i<vboxSettingsStorageBusses.busTypes.length;i++){
  241. var imgName = vboxStorage.getBusIconName(vboxSettingsStorageBusses.busTypes[i]);
  242. imgs[i] = new Array();
  243. imgs[i][0] = new Image();
  244. imgs[i][0].src = 'images/vbox/'+imgName+'_expand_16px.png';
  245. imgs[i][1] = new Image();
  246. imgs[i][1].src = 'images/vbox/'+imgName+'_collapse_16px.png';
  247. imgs[i][2] = new Image();
  248. imgs[i][2].src = 'images/vbox/'+imgName+'_add_16px.png';
  249. imgs[i][3] = new Image();
  250. imgs[i][3].src = 'images/vbox/'+imgName+'_add_disabled_16px.png';
  251. }
  252. var imgs2 = new Array();
  253. var imgsToLoad = ['fd','hd','cd'];
  254. for(var i=0;i<imgsToLoad.length;i++){
  255. imgs2[i] = new Image();
  256. imgs2[i].src = 'images/vbox/'+imgsToLoad[i]+'_16px.png';
  257. }
  258. /*
  259. *
  260. * Init Storage Controller menus and toolbar
  261. *
  262. */
  263. /* Menu for adding controllers */
  264. var vboxSettingsCMenu = new vboxMenu({id: 'vboxSettingsAddControllerMenu',
  265. language_context: 'UIMachineSettingsStorage'});
  266. var vboxSettingsCMenuItems = [];
  267. var bustypes = vboxStorage.getBusTypes();
  268. for(var i = 0; i < bustypes.length; i++) {
  269. var bt = bustypes[i];
  270. var icon = vboxStorage.getBusIconName(bt);
  271. vboxSettingsCMenuItems[vboxSettingsCMenuItems.length] = {'name':'add'+bt,'icon':icon+"_add",'label':'Add '+bt+' Controller'};
  272. }
  273. vboxSettingsCMenu.addMenu(vboxSettingsCMenuItems);
  274. /* Storage tree context menu to add controllers */
  275. $('#vboxSettingsStorageTree').contextMenu({
  276. menu: vboxSettingsCMenu.menuId()
  277. },
  278. function(action, el, pos) {
  279. var bus = action.substring(3);
  280. var c = {'bus':bus,'mediumAttachments':[],'controllerType':vboxStorage[bus].types[0],'useHostIOCache':1,
  281. 'maxPortCount':vboxStorage[bus]['maxPortCount'],'maxDevicesPerPortCount':vboxStorage[bus]['maxDevicesPerPortCount']};
  282. vboxSettingsAddController(c, $('#vboxSettingsStorageTree').children('ul').first());
  283. $('#vboxSettingsStorageTree').trigger('itemselect',$('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first());
  284. }
  285. );
  286. /* Storage tree tool bar */
  287. var vboxSettingsStorageButtons = new Array(
  288. {
  289. /* Add Attachment Button */
  290. 'name' : 'addattach',
  291. 'label' : 'Add Attachment',
  292. 'icon' : 'attachment_add',
  293. 'enabled' : function (item) {
  294. if(!$(item).data('controller')) return false;
  295. // Determine how max and how many are used
  296. if(!($(item).data('controller').maxPortCount && ($(item).parent().find('ul').children('li').length < ($(item).data('controller').maxPortCount * $(item).data('controller').maxDevicesPerPortCount))))
  297. return false;
  298. // Enable / Disable CD/DVD menu
  299. var c = $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first();
  300. if(jQuery.inArray('dvd', vboxStorage[$(c).data('controller').bus].driveTypes) > -1) {
  301. scToolbar.getButtonElement("addattach").data('busType',$(c).data('controller').bus);
  302. scToolbar.getButtonElement("addattach").enableContextMenu();
  303. } else {
  304. scToolbar.getButtonElement("addattach").disableContextMenu();
  305. }
  306. return true;
  307. },
  308. 'click' : function (item) {
  309. // Let context menu handle IDE and Sata
  310. var c = $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first();
  311. if(vboxStorage[$(c).data('controller').bus].driveTypes.length > 1) {
  312. return;
  313. }
  314. vboxSettingsStorageAddMedium($(c).parent(),($(c).data('controller').bus == 'Floppy' ? 'Floppy' : 'HardDisk'));
  315. }
  316. },
  317. {
  318. /* Remove Attachment Button */
  319. 'name' : 'removeattach',
  320. 'label' : 'Remove Attachment',
  321. 'icon' : 'attachment_remove',
  322. 'enabled' : function (item) { return (item && $(item).data('attachment')); },
  323. 'click' : function () {
  324. // Set previous item to last?
  325. var cur = $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent();
  326. if($(cur).hasClass('last')) {
  327. $(cur).prev().addClass('last');
  328. }
  329. var next = $(cur).next().find('table.vboxListItem').first();
  330. if(!$(next).html()) {
  331. var con = $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().data('controller');
  332. if(con) next = $('#vboxSettingsController'+con.bus).find('table.vboxListItem').first();
  333. }
  334. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent().remove();
  335. if(!$(next).trigger('click').html()) $('#vboxSettingsStorageTree').trigger('itemselect',null);
  336. }
  337. },
  338. {
  339. /* Add Controller Button */
  340. 'name' : 'addcontroller',
  341. 'label' : 'Add Controller',
  342. 'icon' : 'controller_add',
  343. 'enabled' : function (item) {
  344. // Draw menu items
  345. var cons = $('#vboxSettingsStorageTree').find('table.vboxSettingsController');
  346. var avail = vboxStorage.getBusTypes();
  347. var used = {};
  348. for(var i = 0; i < avail.length; i++) {
  349. used[avail[i]] = false;
  350. }
  351. for(var i = 0; i < cons.length; i++) {
  352. used[$(cons[i]).data('controller').bus] = true;
  353. }
  354. var oneEnabled = false;
  355. for(var i in used) {
  356. if(used[i]) { // && vboxStorage[i].limitOneInstance) {
  357. vboxSettingsCMenu.disableItem('add'+i);
  358. } else {
  359. vboxSettingsCMenu.enableItem('add'+i);
  360. oneEnabled = true;
  361. }
  362. }
  363. // If at least one item is enabled
  364. return oneEnabled;
  365. },
  366. 'click' : function (item) { return true; }
  367. },
  368. {
  369. /* Remove Controller Button */
  370. 'name' : 'removecontroller',
  371. 'label' : 'Remove Controller',
  372. 'icon' : 'controller_remove',
  373. 'enabled' : function (item) { if(item && $(item).data('controller')) return true; },
  374. 'click' : function () {
  375. var next = $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent().next().find('table.vboxListItem').first();
  376. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent().remove();
  377. if(!$(next).html()) {next = $('#vboxSettingsStorageTree').find('table.vboxListItem').first();}
  378. if(!$(next).trigger('click').html()) $('#vboxSettingsStorageTree').trigger('itemselect',null);
  379. }
  380. }
  381. );
  382. var scToolbar = new vboxToolbarSmall({buttons: vboxSettingsStorageButtons,
  383. language_context: 'UIMachineSettingsStorage', renderTo: 'vboxSettingsControllersButtons'});
  384. /* Add controller button menu initialization */
  385. scToolbar.getButtonElement("addcontroller").contextMenu({
  386. menu: vboxSettingsCMenu.menuId(),
  387. mode:'menu',
  388. button: 0
  389. },
  390. function(action, el, pos) {
  391. var bus = action.substring(3);
  392. var c = {'bus':bus,'mediumAttachments':[],'controllerType':vboxStorage[bus].types[0],'useHostIOCache':1,
  393. 'maxPortCount':vboxStorage[bus]['maxPortCount'],'maxDevicesPerPortCount':vboxStorage[bus]['maxDevicesPerPortCount']};
  394. vboxSettingsAddController(c, $('#vboxSettingsStorageTree').children('ul').first());
  395. $('#vboxSettingsStorageTree').trigger('itemselect',$('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first());
  396. }
  397. );
  398. /* Menu for adding attachment */
  399. var mAttachMenu = new vboxMenu({id: 'vboxSettingsAddAttachmentsMenu',
  400. language_context: 'UIMachineSettingsStorage',
  401. menuItems: [{name: 'addCD', icon: 'cd_add', label: 'Add Optical Drive'},
  402. {name: 'addHD', icon: 'hd_add', label: 'Add Hard Disk'}]});
  403. /* Add attachment button menu initialization */
  404. scToolbar.getButtonElement("addattach").contextMenu({
  405. menu: mAttachMenu.menuId(),
  406. mode:'menu',
  407. button: 0
  408. },
  409. function(action, el, pos) {
  410. vboxSettingsStorageAddMedium($('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent(),(action == 'addCD' ? 'DVD' : 'HardDisk'));
  411. }
  412. );
  413. $('#vboxSettingsStorageTree').on('itemselect',function(e,el) {scToolbar.update(el); });
  414. /* Medium attachment context menu */
  415. var vboxSettingsMAMenu = new vboxMenu({'name':'vboxSettingsMAMenuL',
  416. 'menuItems': [vboxSettingsStorageButtons[1]],
  417. 'language_context': 'UIMachineSettingsStorage'});
  418. /*
  419. * Medium menu buttons
  420. */
  421. var mAttachToolbarHD = new vboxButtonMediaMenu('HardDisk',vboxSettingsControllerAttach);
  422. mAttachToolbarHD.renderTo('vboxSettingsAddAttachmentsMenuHDDiv');
  423. var mAttachToolbarCD = new vboxButtonMediaMenu('DVD',vboxSettingsControllerAttach);
  424. mAttachToolbarCD.renderTo('vboxSettingsAddAttachmentsMenuCDDiv');
  425. var mAttachToolbarFD = new vboxButtonMediaMenu('Floppy',vboxSettingsControllerAttach);
  426. mAttachToolbarFD.renderTo('vboxSettingsAddAttachmentsMenuFDDiv');
  427. /*
  428. * Controller actions and menus for each bus type
  429. */
  430. var vboxStorageBusTypes = vboxStorage.getBusTypes();
  431. var vboxStorageAttachmentMenus = new Array();
  432. for(var i = 0; i < vboxStorageBusTypes.length; i++) {
  433. var btype = vboxStorageBusTypes[i];
  434. var menuItems = [];
  435. for(var a = 0; a < vboxStorage[btype].driveTypes.length; a++) {
  436. switch(vboxStorage[btype].driveTypes[a]) {
  437. case 'dvd':
  438. b = {
  439. 'name' : btype+'addcd',
  440. 'label' : 'Add Optical Drive',
  441. 'icon' : 'cd_add',
  442. 'click' : function () {
  443. vboxSettingsStorageAddMedium($('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent(),'DVD');
  444. }
  445. };
  446. break;
  447. case 'disk':
  448. b = {
  449. 'name' : btype+'adddrive',
  450. 'label' : 'Add Hard Disk',
  451. 'icon' : 'hd_add',
  452. 'click' : function (item) {
  453. vboxSettingsStorageAddMedium($('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent());
  454. }
  455. };
  456. break;
  457. case 'floppy':
  458. b = {
  459. 'name' : btype + 'addfloppy',
  460. 'label':trans('Add Floppy Drive','UIMachineSettingsStorage'),
  461. 'icon' : 'fd_add',
  462. 'click' : function (item) {
  463. vboxSettingsStorageAddMedium($('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent(),'Floppy'); }
  464. };
  465. break;
  466. }
  467. b['enabled'] = function(a) {
  468. return ($('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent().find('li').length < (vboxStorage[a].maxPortCount * vboxStorage[a].maxDevicesPerPortCount));
  469. };
  470. menuItems[menuItems.length] = b;
  471. }
  472. // Add seperator and "remove controller"
  473. menuItems[menuItems.length] = $.extend(true, {}, vboxSettingsStorageButtons[3]); // "Remove"
  474. menuItems[(menuItems.length-1)].separator = true;
  475. menuItems[(menuItems.length-1)].enabled = null; // always enabled
  476. vboxStorageAttachmentMenus[btype] = new vboxMenu({name: 'vboxSettingsController'+btype+'AttachmentsMenu',
  477. language_context: 'UIMachineSettingsStorage',
  478. 'menuItems': menuItems});
  479. }
  480. $('#vboxSettingsStorageTree').on('itemselect',function(e,item){
  481. for(var i = 0; i < vboxStorageBusTypes.length; i++)
  482. vboxStorageAttachmentMenus[vboxStorageBusTypes[i]].update(vboxStorageBusTypes[i]);
  483. });
  484. /*
  485. *
  486. * Form helper functions that listen for form change events
  487. *
  488. *
  489. */
  490. /*
  491. * Changing the slot changes the object
  492. */
  493. document.forms['frmVboxSettings'].vboxSettingsControllerSlot.onchange = function(){
  494. // change port / device
  495. var pd = this.value.split('-');
  496. var attachment = $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first();
  497. $(attachment).data('attachment').port = pd[0];
  498. $(attachment).data('attachment').device = pd[1];
  499. };
  500. /*
  501. *
  502. * Controller form elements
  503. *
  504. */
  505. /* onChange of controller type */
  506. $(document.forms['frmVboxSettings'].vboxSettingsStorageControllerType).change(function(){
  507. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().data('controller').controllerType = $(this).val();
  508. });
  509. /* change storage controller label on keydown in text box */
  510. $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).keyup(function(){
  511. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().find('span.vboxSettingsControllerTitle').first().text(this.value);
  512. });
  513. /* Set storage controller name on blur of textbox */
  514. $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).on('blur',function(e){
  515. var bus = $('#vboxSettingsStorageTree').find('.vboxListItemSelected').first();
  516. if(!$(bus).data('controller')) return;
  517. var newName = $(this).val();
  518. // no change?
  519. if(newName == $(bus).data('controller').name) return true;
  520. if(jQuery.trim($(this).val().toString()).length < 1) {
  521. $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).val($(bus).data('controller').name);
  522. } else {
  523. $('#vboxSettingsStorageTree').find('table.vboxSettingsController').each(function(idx,elm) {
  524. if($(elm).data('controller').name == newName) {
  525. $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).val($(bus).data('controller').name);
  526. conflictFound = true;
  527. return false;
  528. }
  529. });
  530. }
  531. $(bus).data('controller').name = $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).val();
  532. $(bus).find('span.vboxSettingsControllerTitle').first().text($(bus).data('controller').name);
  533. }).keyup(function(){
  534. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().find('span.vboxSettingsControllerTitle').text(this.value);
  535. });
  536. /* Change host cache value onClick of checkbox */
  537. $(document.forms['frmVboxSettings'].vboxSettingsStorageHostCache).click(function(){
  538. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().data('controller').useHostIOCache = this.checked;
  539. });
  540. /*
  541. * Update menu items on select and display
  542. */
  543. $('#vboxSettingsStorageTree').on('itemselect',function(e,item){
  544. $('#vboxSettingsAddAttachmentsMenuCDDiv').hide();
  545. $('#vboxSettingsAddAttachmentsMenuHDDiv').hide();
  546. $('#vboxSettingsAddAttachmentsMenuFDDiv').hide();
  547. // Null selection hides everything
  548. if(!item) {
  549. $('#vboxSettingsController').css('display','none');
  550. $('#vboxSettingsMediaInfo').css('display','none');
  551. $('#vboxSettingsStorageAttachment').css('display','none');
  552. // Update label widths
  553. vboxStorageResizeTreeItemLabels();
  554. return;
  555. }
  556. if(!$(item).data('attachment')) {
  557. // Update label widths
  558. vboxStorageResizeTreeItemLabels();
  559. return;
  560. }
  561. switch($(item).data('attachment').type) {
  562. case 'HardDisk':
  563. $('#vboxSettingsAddAttachmentsMenuHDDiv').show();
  564. break;
  565. case 'Floppy':
  566. // Update media menu...
  567. mAttachToolbarFD.menuUpdateMedia($(item).data('attachment').medium);
  568. $('#vboxSettingsAddAttachmentsMenuFDDiv').show();
  569. break;
  570. default:
  571. // Update media menu...
  572. mAttachToolbarCD.menuUpdateMedia($(item).data('attachment').medium);
  573. $('#vboxSettingsAddAttachmentsMenuCDDiv').show();
  574. }
  575. // Update label widths
  576. vboxStorageResizeTreeItemLabels();
  577. });
  578. /*
  579. *
  580. * OnSave and OnShow for dialog
  581. *
  582. *
  583. */
  584. /* Change settings onSave() */
  585. $('#vboxSettingsDialog').on('save',function(){
  586. $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).trigger('blur');
  587. $('#vboxSettingsDialog').data('vboxMachineData').storageControllers = new Array();
  588. var storageList = $('#vboxSettingsStorageTree').children('ul').first();
  589. $(storageList).find('table.vboxSettingsController').each(function(i,con){
  590. var attachments = new Array();
  591. $(con).parent().find('table.vboxSettingsStorageAttachment').each(function(i,elm) {
  592. var attch = $(elm).data('attachment');
  593. if(attch.medium && attch.medium.id) {
  594. var med = vboxMedia.getMediumById(attch.medium.id);
  595. attch.medium = {'id':med.id,'hostDrive':med.hostDrive,'location':med.location};
  596. }
  597. attachments[attachments.length] = attch;
  598. });
  599. var curCon = $('#vboxSettingsDialog').data('vboxMachineData').storageControllers.length;
  600. $('#vboxSettingsDialog').data('vboxMachineData').storageControllers[curCon] = $(this).data('controller');
  601. $('#vboxSettingsDialog').data('vboxMachineData').storageControllers[curCon]['mediumAttachments'] = attachments;
  602. });
  603. });
  604. /* WHen data is loaded */
  605. $('#vboxSettingsDialog').on('dataLoaded',function(){
  606. /*
  607. *
  608. * Fill form and storage list items
  609. *
  610. */
  611. /* Fill List by calling helper functions for each controller */
  612. var storageList = $('#vboxSettingsStorageTree').children('ul').first();
  613. $(storageList).children().remove();
  614. var cons = $('#vboxSettingsDialog').data('vboxMachineData').storageControllers;
  615. for(var a = 0; a < cons.length; a++) {
  616. var attch = cons[a].mediumAttachments;
  617. var conElm = vboxSettingsAddController(cons[a], $(storageList));
  618. for(var b = 0; b < cons[a].mediumAttachments.length; b++) {
  619. vboxSettingsStorageBusses.addAttached(cons[a].mediumAttachments[b].medium);
  620. vboxSettingsAddAttachment(cons[a].mediumAttachments[b], conElm);
  621. }
  622. }
  623. //Select first item in storage tree list
  624. $('#vboxSettingsStorageTree').find('table.vboxListItem').first().trigger('click').html();
  625. /* Disable non-editable items when VM is running */
  626. var p = $('#vboxSettingsStorageTableWrapper');
  627. if(!$('#vboxSettingsDialog').data('vboxFullEdit')) {
  628. scToolbar.disable();
  629. $('#vboxSettingsStorageTree').disableContextMenu()
  630. p.find('span:not(.vboxRunningEnabled)').addClass('disabled');
  631. p.find('input:not(.vboxRunningEnabled),select,textarea').prop('disabled',true);
  632. // Storage tree toolbars
  633. $('#vboxSettingsStorageTree').find('.vboxControllerAttachmentButton').trigger('disable');
  634. // Hard Disk Media menu button
  635. $('#vboxSettingsAddAttachmentsMenuHDDiv').trigger('disable');
  636. } else {
  637. $('#vboxSettingsStorageTree').enableContextMenu();
  638. p.find('span:not(.vboxRunningEnabled)').removeClass('disabled');
  639. p.find('input:not(.vboxRunningEnabled),select,textarea').prop('disabled',false);
  640. // Storage tree toolbars
  641. $('#vboxSettingsStorageTree').find('.vboxControllerAttachmentButton').trigger('enable');
  642. // Hard Disk Media menu button
  643. $('#vboxSettingsAddAttachmentsMenuHDDiv').trigger('enable');
  644. // initial toolbar update
  645. scToolbar.enable();
  646. scToolbar.update();
  647. }
  648. });
  649. /* Respond to UP / Down arrow events */
  650. $('#vboxSettingsStorageTree').click(function(){$(this).focus();}).keydown(function(e){
  651. var keynum = 0;
  652. if(e.keyCode)
  653. keynum = e.keyCode;
  654. else if(e.which)
  655. keynum = e.which;
  656. switch(keynum) {
  657. // up
  658. case 38:
  659. var cur = $(this).find('table.vboxListItemSelected').parent();
  660. // Try previous med attachment
  661. if($(cur).prev('li.vboxSettingsMediumAttachment').children('table.vboxListItem').trigger('click')[0]) {
  662. return;
  663. }
  664. // If we're a medium, click our parent controller
  665. if($(cur).hasClass('vboxSettingsMediumAttachment')) {
  666. $(cur).parent().parent('li.vboxSettingsController').children('table.vboxListItem').trigger('click');
  667. return;
  668. }
  669. // Must be a controller, try previous controller's last medium attachment
  670. if($(cur).prev().children('ul:not([class~="vboxHidden"])').find('table.vboxListItem:last').trigger('click')[0])
  671. return;
  672. // No med attachment, try previous controller
  673. $(cur).prev('li.vboxSettingsController').children('table.vboxListItem').trigger('click');
  674. break;
  675. // right / expand
  676. case 39:
  677. var tbl = $(this).find('table.vboxListItemSelected');
  678. var con = $(tbl).data('controller');
  679. if(!con) return;
  680. $(tbl).find('td.vboxSettingsController' + con.bus).click();
  681. break;
  682. // left / contract
  683. case 37:
  684. var tbl = $(this).find('table.vboxListItemSelected');
  685. var con = $(tbl).data('controller');
  686. if(!con) return;
  687. $(tbl).find('td.vboxSettingsController' + con.bus + 'Expanded').click();
  688. break;
  689. // down
  690. case 40:
  691. var cur = $(this).find('table.vboxListItemSelected').parent();
  692. // Try next med attachment
  693. if($(cur).next('li.vboxSettingsMediumAttachment').children('table.vboxListItem').trigger('click')[0]) {
  694. return;
  695. }
  696. // Select first medium of current controller?
  697. if($(cur).children('ul:not([class~="vboxHidden"])').find('table.vboxListItem:first').trigger('click')[0])
  698. return;
  699. // Try next controller
  700. $(cur).closest('li.vboxSettingsController').next('li.vboxSettingsController').children('table.vboxListItem').trigger('click');
  701. break;
  702. }
  703. }).css('outline','none');;
  704. /*
  705. *
  706. * Change media attachment helper function
  707. *
  708. */
  709. function vboxSettingsControllerAttach(m) {
  710. var tbl = $('#vboxSettingsStorageTree').find('table.vboxListItemSelected');
  711. $(tbl).data('attachment').medium = m;
  712. $(tbl).parent().tipped({'source':vboxSettingsMediumTip(m),'position':'mouse','delay':1000});
  713. // Re-select attachment to update display info
  714. vboxSettingsSelectAttachment(tbl);
  715. }
  716. /*
  717. *
  718. * Called when controller is selected helper function
  719. *
  720. */
  721. function vboxSettingsSelectController(tbl) {
  722. // Null selection?
  723. if(!tbl) {
  724. $('#vboxSettingsController').css('display','none');
  725. $('#vboxSettingsMediaInfo').css('display','none');
  726. $('#vboxSettingsStorageAttachment').css('display','none');
  727. return;
  728. }
  729. $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).trigger('blur');
  730. /* set classes for selected / unselected */
  731. $('#vboxSettingsStorageTree').find('table[class]').removeClass('vboxListItemSelected').addClass('vboxListItem');
  732. $(tbl).removeClass('vboxListItem').addClass('vboxListItemSelected');
  733. /* set name text box value */
  734. document.forms['frmVboxSettings'].vboxSettingsStorageItemName.value = $(tbl).data('controller').name;
  735. /* Set host cache checkbox */
  736. document.forms['frmVboxSettings'].vboxSettingsStorageHostCache.checked = $(tbl).data('controller').useHostIOCache ? 'checked' : '';
  737. var busType = $(tbl).data('controller').bus;
  738. /* controller type */
  739. document.forms['frmVboxSettings'].vboxSettingsStorageControllerType.options.length = 0;
  740. $(document.forms['frmVboxSettings'].vboxSettingsStorageControllerType).children().remove();
  741. for(var i = 0; i < vboxStorage[busType].types.length; i++) {
  742. document.forms['frmVboxSettings'].vboxSettingsStorageControllerType.options[i] = new Option(trans(vboxStorageControllerType(vboxStorage[busType].types[i]),'VBoxGlobal'),vboxStorage[busType].types[i]);
  743. }
  744. /* Set default type */
  745. document.forms['frmVboxSettings'].vboxSettingsStorageControllerType.value = $(tbl).data('controller').controllerType;
  746. $('#vboxSettingsController').css('display','block');
  747. $('#vboxSettingsStorageAttachment').css('display','none');
  748. $('#vboxSettingsMediaInfo').css('display','none');
  749. $('#vboxSettingsHDInfo').css('display','none');
  750. // Show SATA port count
  751. if(busType == 'SATA') {
  752. $(document.forms['frmVboxSettings'].vboxSettingsControllerPortCount).val($(tbl).data('controller').portCount);
  753. $('#vboxSettingsControllerPortCountRow').css('display','');
  754. } else {
  755. $('#vboxSettingsControllerPortCountRow').css('display','none');
  756. }
  757. /* Enable / disable buttons */
  758. if($(tbl).parent().find('ul').children('li').length < ($(tbl).data('controller').maxPortCount * $(tbl).data('controller').maxDevicesPerPortCount)) {
  759. if($('#vboxSettingsDialog').data('vboxFullEdit')) {
  760. $(tbl).find('.vboxToolbarSmall').trigger('enable', [true]);
  761. }
  762. } else {
  763. $(tbl).find('.vboxToolbarSmall').trigger('disable');
  764. }
  765. /* Trigger Event */
  766. $('#vboxSettingsStorageTree').trigger('itemselect',tbl);
  767. }
  768. /*
  769. * Generate tooltip for medium helper function
  770. */
  771. function vboxSettingsMediumTip(m) {
  772. if(!m || !m.id) return trans('Empty','VBoxGlobal');
  773. if(m.hostDrive) return vboxMedia.getName(m);
  774. // DVD / Floppy images
  775. if(m.deviceType != 'HardDisk') {
  776. return '<b>'+m.location+'</b><p>'+trans('Attached to:','UIMachineSettingsStorage')+' '+vboxMedia.attachedTo(m)+'</p>';
  777. }
  778. var mbase = m;
  779. if(m.base != m.id) {
  780. mbase = vboxMedia.getMediumById(m.base);
  781. }
  782. var tip = '<b>'+mbase.location+'</b><p>'+trans('Type (Format):','UIMachineSettingsStorage')+' '+vboxMedia.getType(mbase)+' ('+mbase.format+')</p><p>'+trans('Attached to:','UIMachineSettingsStorage')+' '+vboxMedia.attachedTo(mbase)+'</p>';
  783. // Is this a medium that is attached indirectly
  784. if(vboxSettingsStorageBusses.isAttachedIndirect(m) && m.base != m.id) {
  785. var p = vboxSettingsStorageBusses.isAttached(m);
  786. tip += '<hr />'+trans('This base hard disk is indirectly attached using the following differencing hard disk:','VBoxGlobal')+'<br /><b>'+p.location+'</b></p><p>'+trans('Type (Format):','UIMachineSettingsStorage')+' '+vboxMedia.getType(p) + ' (' + p.format + ')'+'</p><p>'+trans('Attached to:','UIMachineSettingsStorage')+' '+vboxMedia.attachedTo(p)+'</p>';
  787. } else if(m.readOnly) {
  788. tip += '<hr />'+trans('Attaching this hard disk will be performed indirectly using a newly created differencing hard disk.','VBoxGlobal');
  789. }
  790. return tip;
  791. }
  792. /*
  793. *
  794. * Add disk medium to bus helper function
  795. *
  796. */
  797. function vboxSettingsStorageAddMedium(conElm, type) {
  798. // get controller name
  799. var controller = $(conElm).find('span.vboxSettingsControllerTitle').first().text();
  800. if(!type) type = 'HardDisk';
  801. // Find first target slot (vboxSettingsStorageBusses created above)
  802. var slots = vboxSettingsStorageBusses.availableSlots(conElm);
  803. var slot = null;
  804. for(var i in slots) {
  805. if(typeof i == 'function') continue;
  806. slot = i;
  807. break;
  808. }
  809. if(slot === null) return;
  810. slot = slot.split('-');
  811. var port = slot[0];
  812. var device = slot[1];
  813. // Add new attachment dialog
  814. ////////////////////////////
  815. var buttons = {};
  816. var msg = '';
  817. // Hard Disk buttons
  818. if (type == 'HardDisk') {
  819. buttons[trans('Create new disk','UIMessageCenter')] = function() {
  820. $.when(new vboxWizardNewHDDialog({'path':vboxDirname($('#vboxSettingsDialog').data('vboxMachineData').settingsFilePath)+$('#vboxPane').data('vboxConfig').DSEP,vmName:$('#vboxSettingsDialog').data('vboxMachineData').name}).run())
  821. .done(function(id){
  822. if(!id) return;
  823. mAttachToolbarHD.mediaMenu.menuUpdateRecent();
  824. vboxSettingsAddAttachment({'controller':controller,'port':port,'device':device,'type':type,'medium':vboxMedia.getMediumById(id),'ignoreFlush':1}, conElm);
  825. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().click();
  826. });
  827. $(this).remove();
  828. };
  829. buttons[trans('Choose existing disk','UIMessageCenter')] = function() {
  830. var dlg = $(this);
  831. vboxMedia.actions.choose(null,'HardDisk',function(med){
  832. if(med) {
  833. mAttachToolbarHD.mediaMenu.menuUpdateRecent();
  834. vboxSettingsAddAttachment({'controller':controller,'port':port,'device':device,'type':type,'medium':med,'ignoreFlush':1}, conElm);
  835. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().click();
  836. }
  837. $(dlg).remove();
  838. });
  839. };
  840. msg = trans('<p>You are about to add a virtual hard disk to controller <b>%1</b>.</p><p>Would you like to create a new, empty file to hold the disk contents or select an existing one?</p>','UIMessageCenter').replace('%1',controller);
  841. // Floppy buttons
  842. } else if(type == 'Floppy') {
  843. buttons[trans('Choose disk','UIMessageCenter')] = function() {
  844. var dlg = $(this);
  845. vboxMedia.actions.choose(null,'Floppy',function(med){
  846. if(med) {
  847. mAttachToolbarFD.mediaMenu.menuUpdateRecent();
  848. vboxSettingsAddAttachment({'controller':controller,'port':port,'device':device,'type':type,'medium':med}, conElm);
  849. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().click();
  850. }
  851. $(dlg).remove();
  852. });
  853. };
  854. buttons[trans('Leave empty','UIMessageCenter')] = function() {
  855. vboxSettingsAddAttachment({'controller':controller,'port':port,'device':device,'type':type,'medium':null}, conElm);
  856. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().click();
  857. $(this).remove();
  858. };
  859. msg = trans('<p>You are about to add a new floppy drive to controller <b>%1</b>.</p><p>Would you like to choose a virtual floppy disk to put in the drive or to leave it empty for now?</p>','UIMessageCenter').replace('%1',controller);
  860. // CD/DVD buttons
  861. } else {
  862. buttons[trans('Choose disk','UIMessageCenter')] = function() {
  863. var dlg = $(this);
  864. vboxMedia.actions.choose(null,'DVD',function(med){
  865. if(med) {
  866. mAttachToolbarCD.mediaMenu.menuUpdateRecent();
  867. vboxSettingsAddAttachment({'controller':controller,'port':port,'device':device,'type':type,'medium':med}, conElm);
  868. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().click();
  869. }
  870. $(dlg).remove();
  871. });
  872. };
  873. buttons[trans('Leave empty','UIMessageCenter')] = function() {
  874. vboxSettingsAddAttachment({'controller':controller,'port':port,'device':device,'type':type,'medium':null}, conElm);
  875. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().click();
  876. $(this).remove();
  877. };
  878. msg = trans('<p>You are about to add a new CD/DVD drive to controller <b>%1</b>.</p><p>Would you like to choose a virtual CD/DVD disk to put in the drive or to leave it empty for now?</p>','UIMessageCenter').replace('%1',controller);
  879. }
  880. buttons[trans('Cancel','QIMessageBox')] = function() {
  881. $(this).remove();
  882. };
  883. $('<div />').attr({'id':'vboxSettingsStorageUnavailable','style':'display: none'}).html(
  884. '<div><img src="images/50px-Question_icon.svg.png" style="float: left; padding: 10px; " />'+msg+'</div>'
  885. ).dialog({'closeOnEscape':false,'width':600,'height':200,'buttons':buttons,'modal':true,'autoOpen':true,'dialogClass':'vboxDialogContent','title':'<img src="images/vbox/OSE/about_16px.png" class="vboxDialogTitleIcon" /> phpVirtualBox'});
  886. }
  887. /*
  888. *
  889. * Add controller to list helper function
  890. *
  891. */
  892. function vboxSettingsAddController(con,list) {
  893. // Elect name if none exists
  894. if(!con.name) {
  895. var count = $(list).children('li.vboxSettingsController'+con.bus).length + 1;
  896. var name = trans(con.bus,'UIMachineSettingsStorage');
  897. if(count == 1) {
  898. con.name = name;
  899. } else {
  900. var electedName = name + ' ' + count;
  901. var conflictFound = false;
  902. do {
  903. conflictFound = false;
  904. $(list).children('li.vboxSettingsController'+con.bus).each(function(idx,elm) {
  905. if($(elm).children('table').first().data('controller').name == electedName) {
  906. conflictFound = true;
  907. electedName = name + ' ' + (++count);
  908. return false;
  909. }
  910. });
  911. con.name = electedName;
  912. } while(conflictFound);
  913. }
  914. }
  915. var li = $('<li />').attr({'title':con.name,'class':'vboxSettingsController vboxSettingsController' + con.bus});
  916. var tbl = $('<table />').attr({'class':'vboxListItem vboxSettingsController'}).on('click',function(){
  917. vboxSettingsSelectController(this);
  918. });
  919. // filter out any dummy medium attachments
  920. var mas = new Array();
  921. for(var i = 0; i < con.mediumAttachments.length; i++) {
  922. if(con.mediumAttachments[i].controller)
  923. mas[mas.length] = con.mediumAttachments[i];
  924. }
  925. con.mediumAttachments = mas;
  926. // Assign data
  927. $(tbl).data('controller',con);
  928. var tr = $('<tr />');
  929. var iconName = vboxStorage.getBusIconName(con.bus);
  930. $('<td />').attr({'class':'vboxSettingsStorageTypeIcon vboxSettingsController' + con.bus + 'Expanded'})
  931. .css({
  932. 'background-image':'url(images/vbox/'+iconName+'_collapse_16px.png)'
  933. }).html('<div style="width:22px" />').click(function(){
  934. if(!$(this).data('toggleClicked')) {
  935. $(this).data('toggleClicked', true);
  936. var n = $(this).closest('li');
  937. $(n).children('ul').addClass('vboxHidden').css('display','none');
  938. $(this).removeClass('vboxSettingsController'+con.bus+'Expanded').addClass('vboxSettingsController'+con.bus)
  939. .css({'background-image':'url(images/vbox/'+iconName+'_expand_16px.png)'});
  940. } else {
  941. $(this).data('toggleClicked', false);
  942. var n = $(this).closest('li');
  943. $(n).children('ul').removeClass('vboxHidden').css('display','');
  944. $(this).removeClass('vboxSettingsController'+con.bus).addClass('vboxSettingsController'+con.bus+'Expanded')
  945. .css({'background-image':'url(images/vbox/'+iconName+'_collapse_16px.png)'})
  946. }
  947. return false;
  948. }).appendTo(tr);
  949. // Controller name
  950. $(tr).append($('<td />').css({'width':'100%'}).html('<div class="vboxFitToContainer">'+trans('Controller: %1','UIMachineSettingsStorage').replace('%1','<span class="vboxSettingsControllerTitle vboxRunningEnabled">'+$('<div/>').text(con.name).html())+"</span>"+"</div>"));
  951. // Buttons
  952. $(tr).append($('<td />').attr({'style':'width: 22px;','class':'vboxControllerAttachmentButton'}));
  953. $(tbl).append(tr).appendTo(li);
  954. /* Attachments list holder */
  955. $(li).append($('<ul />').attr({'class':'vboxSettingsControllerAttachments'})).dblclick(function(e){
  956. $(this).children('table.vboxSettingsController').find('td.vboxSettingsStorageTypeIcon').trigger('click',e);
  957. }).disableSelection().appendTo(list);
  958. /* Generate Toolbars */
  959. var dtypes = vboxStorage[con.bus].driveTypes;
  960. for(var i = 0; i < dtypes.length; i++) {
  961. var b = null;
  962. if(dtypes[i] == 'dvd') {
  963. b = {
  964. 'name' : con.bus+'addcd',
  965. 'label' : trans('Add Optical Drive','UIMachineSettingsStorage'),
  966. 'icon' : 'cd_add',
  967. 'click' : function () { vboxSettingsStorageAddMedium(li,'DVD'); }
  968. };
  969. } else if(dtypes[i] == 'disk') {
  970. b = {
  971. 'name' : con.bus+'adddrive',
  972. 'label' : trans('Add Hard Disk','UIMachineSettingsStorage'),
  973. 'icon' : 'hd_add',
  974. 'click' : function (item) { vboxSettingsStorageAddMedium(li); }
  975. };
  976. } else if(dtypes[i] == 'floppy') {
  977. b = {'label':trans('Add Floppy Drive','UIMachineSettingsStorage'),
  978. 'icon' : 'fd_add',
  979. 'click' : function (item) { vboxSettingsStorageAddMedium(li,'Floppy'); }
  980. };
  981. }
  982. b['enabled'] = function() {
  983. return (li.find('li').length < (vboxStorage[con.bus].maxPortCount * vboxStorage[con.bus].maxDevicesPerPortCount));
  984. };
  985. var tb = new vboxToolbarSmall({buttons: [b],
  986. buttonStyle: 'margin:0px;padding:0px;border:0px;background-repeat:no-repeat;background-position:0px 0px;',
  987. noHover: true,
  988. renderTo: li.find('td.vboxControllerAttachmentButton')});
  989. tb.disable();
  990. }
  991. // Only if machine is not running
  992. if($('#vboxSettingsDialog').data('vboxFullEdit')) {
  993. $(li).contextMenu({menu: vboxStorageAttachmentMenus[con.bus].menuId(),
  994. menusetup: function() {$(li).children('table').first().trigger('click')}},
  995. vboxStorageAttachmentMenus[con.bus].menuClickCallback
  996. );
  997. }
  998. // Return controller element list item
  999. return li;
  1000. }
  1001. /*
  1002. *
  1003. * Add a medium attachment to a controller helper function
  1004. *
  1005. */
  1006. function vboxSettingsAddAttachment(d,conElm) {
  1007. var con = (conElm ? conElm : $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().parent());
  1008. // Save bus
  1009. d.bus = $(con).find('table.vboxSettingsController').data('controller').bus;
  1010. // remove any 'last' classes
  1011. $(con).children('ul').children().removeClass('last');
  1012. var li = $('<li />').attr({'class':'last vboxSettingsMediumAttachment'});
  1013. var tbl = $('<table />').attr({'class':'vboxListItem vboxSettingsStorageAttachment'})
  1014. .data({'attachment':d}).on('click',function(){
  1015. vboxSettingsSelectAttachment(this);
  1016. });
  1017. var m = vboxMedia.getMediumById(((d.medium && d.medium.id) ? d.medium.id : null));
  1018. var tr = $('<tr />');
  1019. // Storage type icon
  1020. $(tr).append($('<td />').attr({'class':'vboxSettingsStorageTypeIcon vboxSettingsMediaType' + d.type,'style':'width:22px'}).html('<img src="images/vbox/blank.gif" style="width:22px" />'));
  1021. // Medium name
  1022. $(tr).append($('<td />').css({'width':'100%'}).append($('<div />').attr({'class':'vboxSettingsStorageMediumName vboxFitToContainer'}).html(vboxMedia.getName(vboxMedia.getMediumById((m && m.base ? m.base : (m && m.id ? m.id : null)))))));
  1023. $(tbl).append(tr).appendTo(li);
  1024. // Only if not running
  1025. if($('#vboxSettingsDialog').data('vboxFullEdit')) {
  1026. $(li).contextMenu({
  1027. menu: vboxSettingsMAMenu.menuId(),
  1028. menusetup : function(el) {
  1029. vboxSettingsSelectAttachment($(el).find('table.vboxSettingsStorageAttachment'));
  1030. }
  1031. },
  1032. function(action, el, pos) {
  1033. vboxSettingsStorageButtons[1].click();
  1034. }
  1035. );
  1036. }
  1037. $(li).tipped({'source':vboxSettingsMediumTip(m),'position':'mouse','delay':1000}).appendTo(con.children('ul'));
  1038. }
  1039. /*
  1040. *
  1041. * Called when selecting a medium attachment
  1042. *
  1043. */
  1044. function vboxSettingsSelectAttachment(tbl) {
  1045. // Null selection?
  1046. if(!tbl) {
  1047. $('#vboxSettingsController').css('display','none');
  1048. $('#vboxSettingsMediaInfo').css('display','none');
  1049. $('#vboxSettingsStorageAttachment').css('display','none');
  1050. return;
  1051. }
  1052. $(document.forms['frmVboxSettings'].vboxSettingsStorageItemName).trigger('blur');
  1053. /* Display Changes */
  1054. if(!$(tbl).hasClass('vboxListItemSelected')) {
  1055. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').removeClass('vboxListItemSelected').addClass('vboxListItem');
  1056. $(tbl).removeClass('vboxListItem').addClass('vboxListItemSelected');
  1057. }
  1058. $('#vboxSettingsController').css('display','none');
  1059. $('#vboxSettingsMediaInfo').css('display','block');
  1060. $('#vboxSettingsStorageAttachment').css('display','block');
  1061. var ma = $(tbl).data('attachment');
  1062. /* Get / Set Medium */
  1063. if(ma.medium && ma.medium.id)
  1064. ma.medium = vboxMedia.getMediumById(ma.medium.id);
  1065. (function(){
  1066. var sc = $(tbl).closest('li.vboxSettingsController').children('table').first().data('controller');
  1067. var tblSA = $('#vboxSettingsStorageAttachment').find('table').first();
  1068. $(tblSA).find('tr.vboxSettingsControllerDeviceOptionRow').empty().remove();
  1069. switch(ma.type) {
  1070. case 'HardDisk':
  1071. label = 'Hard Disk:';
  1072. break;
  1073. case 'DVD':
  1074. label = 'CD/DVD Drive:';
  1075. break;
  1076. case 'Floppy':
  1077. label = 'Floppy Drive:';
  1078. break;
  1079. }
  1080. var maOptions = vboxStorage.getMAOptions(ma)
  1081. .concat(vboxStorage.getMAOptionsForSC(sc));
  1082. for(var i = 0; i < maOptions.length; i++) {
  1083. var opt = maOptions[i];
  1084. var cbox = $('<input />').attr('type','checkbox').prop('checked', ma[opt.attrib] ? true : false)
  1085. .on('click', {attrib: opt.attrib}, function(event){
  1086. var attachment = $(tbl).data('attachment');
  1087. attachment[event.data.attrib] = this.checked ? true : false;
  1088. $(tbl).data('attachment', attachment);
  1089. }).addClass('vboxCheckbox');
  1090. $('<tr />').addClass('vboxSettingsControllerDeviceOptionRow')
  1091. .append($('<th />'))
  1092. .append(
  1093. $('<td />')
  1094. .append($('<label />')
  1095. .append(cbox)
  1096. .append($('<span />').css({'margin-left':'4px'}).text(opt.label))
  1097. )
  1098. ).appendTo($(tblSA));
  1099. }
  1100. })();
  1101. $('#vboxSettingsControllerSlotLabel').html(trans(label,'UIMachineSettingsStorage'));
  1102. /* Show / Hide HD/Media Info */
  1103. $('#vboxSettingsImageInfo').css('display',(ma.type == 'HardDisk' ? 'none' : 'block'));
  1104. $('#vboxSettingsHDInfo').css('display',(ma.type == 'HardDisk' ? 'block' : 'none'));
  1105. /* Populate slot select box */
  1106. document.forms['frmVboxSettings'].vboxSettingsControllerSlot.options.length = 0;
  1107. $(document.forms['frmVboxSettings'].vboxSettingsControllerSlot).children().remove();
  1108. slots = vboxSettingsStorageBusses.availableSlots($(tbl).parent().parent().parent(), ma.port+'-'+ma.device);
  1109. for(var s in slots) {
  1110. var opt = new Option(slots[s], s);
  1111. document.forms['frmVboxSettings'].vboxSettingsControllerSlot.options[document.forms['frmVboxSettings'].vboxSettingsControllerSlot.options.length] = opt;
  1112. }
  1113. document.forms['frmVboxSettings'].vboxSettingsControllerSlot.value = ma.port+'-'+ma.device;
  1114. /* Trigger Event */
  1115. $('#vboxSettingsStorageTree').trigger('itemselect',tbl);
  1116. var m = ma.medium;
  1117. var name = vboxMedia.getName(m);
  1118. // Read-only medium selected
  1119. if(ma.medium && ma.medium.readOnly) {
  1120. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().find('td').first().addClass('vboxMediumReadOnly');
  1121. } else {
  1122. $('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().find('td').first().removeClass('vboxMediumReadOnly');
  1123. }
  1124. // Show medium info
  1125. if(m && m.deviceType == 'HardDisk') {
  1126. var disp = vboxMedia.getMediumById(m.base);
  1127. name = vboxMedia.getName(disp);
  1128. var encSettings = vboxMedia.getEncryptionSettings(disp);
  1129. $('#vboxSettingsHDvsize').html(vboxMbytesConvert(disp.logicalSize));
  1130. $('#vboxSettingsHDasize').html(vboxBytesConvert(disp.size));
  1131. $('#vboxSettingsHDDetails').html(vboxMedia.getHardDiskVariant(disp));
  1132. $('#vboxSettingsHDlocation').html(disp.location);
  1133. $('#vboxSettingsHDtype').html(trans(disp.type,'VBoxGlobal') + ' (' + disp.format + ')');
  1134. $('#vboxSettingsHDattached').html(vboxMedia.attachedTo(disp));
  1135. $('#vboxSettingsHDEncrypted').html(encSettings && encSettings.id ? encSettings.id : '--');
  1136. } else {
  1137. $('#vboxSettingsImageType').html(m ? trans((m.hostDrive ? 'Host Drive' : 'Image'),'UIMachineSettingsStorage'): '--');
  1138. $('#vboxSettingsImageSize').html((m && !m.hostDrive ? vboxBytesConvert(m.size):'--'));
  1139. $('#vboxSettingsImageLocation').html((m && !m.hostDrive ? m.location:'--'));
  1140. $('#vboxSettingsImageAttached').html((m && !m.hostDrive ? vboxMedia.attachedTo(m) :'--'));
  1141. }
  1142. $(tbl).data('attachment').medium = m;
  1143. $(tbl).find('div.vboxSettingsStorageMediumName').first().html($('<div />').text(name).html());
  1144. }
  1145. /*
  1146. * Focus storage controller list when showing this pane
  1147. */
  1148. $('#vboxSettingsStorageTableWrapper').on('show',function(){
  1149. $('#vboxSettingsStorageTree').focus();
  1150. });
  1151. /*
  1152. *
  1153. *
  1154. * Storage pane resize and draggable resize bar logic
  1155. *
  1156. *
  1157. */
  1158. /*
  1159. * Resize storage pane
  1160. */
  1161. function vboxSettingsStorageResize() {
  1162. // Hide storage tree
  1163. $('#vboxSettingsStorageTree').css({'display':'none'});
  1164. // Get and set size
  1165. $('#vboxStoragePaneLeft').css({'display':'none'});
  1166. $('#vboxStoragePaneRight').css({'display':'none'});
  1167. // Main table height
  1168. $('#vboxSettingsStorageTableWrapper').css({'display':'none'});
  1169. var h = $('#vboxSettingsStorageTableWrapper').css({'display':'none'}).parent().parent().innerHeight()-4;
  1170. // IE needs to account for bordering
  1171. if($.browser.msie) h-= 4;
  1172. // Set height
  1173. $('#vboxSettingsStorageTableWrapper').css({'display':''}).height(h);
  1174. // Pane width
  1175. var bothWidth = ($('#vboxStoragePaneLeft').parent().innerWidth() + $('#vboxStoragePaneRight').parent().innerWidth() - 24) / 2;
  1176. $('#vboxStoragePaneLeft').css({'width':bothWidth+'px','display':''}).parent().css({'width':'auto','padding':'6px'});
  1177. $('#vboxStoragePaneRight').css({'width':bothWidth+'px','display':''}).parent().css({'width':'auto','padding':'6px'});
  1178. // Unsnap.. sorry..
  1179. $('#vboxStorageResizeBar').data('vboxSnapped',0);
  1180. // Get inner height of storage tree parent - padding
  1181. var h = $('#vboxStoragePaneLeft').parent().innerHeight() - 24;
  1182. // subtract sibling heights
  1183. $('#vboxSettingsStorageTree').siblings().each(function(){
  1184. h -= $(this).outerHeight(true);
  1185. });
  1186. $('#vboxSettingsStorageTree').height(h).css({'display':''});
  1187. vboxStorageResizeTreeItemLabels();
  1188. }
  1189. /*
  1190. * Resize controller labels
  1191. */
  1192. function vboxStorageResizeTreeItemLabels() {
  1193. $('#vboxSettingsStorageTree div.vboxFitToContainer').each(function(){
  1194. $(this).css({'display':'none'});
  1195. var w = $(this).parent().innerWidth() - 2;
  1196. $(this).css({'width':w+'px','display':''});
  1197. });
  1198. };
  1199. /*
  1200. * Set pane sizes and resize bar
  1201. */
  1202. $('#vboxSettingsStorageTableWrapper').one('show',function(){
  1203. // Resize everything on dialog resize
  1204. $('#vboxSettingsDialog').on('dialogresizestop',function(){
  1205. vboxSettingsStorageResize();
  1206. });
  1207. $('#vboxSettingsStorageTableWrapper').on('show',function(){
  1208. vboxSettingsStorageResize();
  1209. });
  1210. // Hide children to get true size
  1211. $('#vboxStoragePaneLeft').children().css({'display':'none'});
  1212. $('#vboxStoragePaneRight').children().css({'display':'none'});
  1213. var h = $('#vboxSettingsStorageTableWrapper').parent().css({'padding':'0px','margin':'0px'}).parent().innerHeight();
  1214. // IE needs to account for bordering
  1215. if($.browser.msie) h-= 4;
  1216. $('#vboxSettingsStorageTableWrapper').height(h-4);
  1217. // Get and set size
  1218. var bothWidth = ($('#vboxStoragePaneLeft').parent().innerWidth() + $('#vboxStoragePaneRight').parent().innerWidth() - 24) / 2;
  1219. $('#vboxStoragePaneLeft').css({'width':bothWidth+'px','overflow':'hidden'}).parent().css({'width':'auto'});
  1220. $('#vboxStoragePaneRight').css({'width':bothWidth+'px','overflow':'hidden'}).parent().css({'width':'auto'});
  1221. // Show children again
  1222. $('#vboxStoragePaneLeft').children().css({'display':''});
  1223. $('#vboxStoragePaneRight').children().css({'display':''});
  1224. // Re-trigger list selection to show correct info
  1225. if(!$('#vboxSettingsStorageTree').find('table.vboxListItemSelected').first().click().hasClass('vboxListItemSelected'))
  1226. $('#vboxSettingsStorageTree').trigger('itemselect',null);
  1227. // Don't allow selection of text in storage tree. This looks funny when dragging the resize bar
  1228. $('#vboxSettingsStorageTree').disableSelection();
  1229. // Resize
  1230. vboxSettingsStorageResize();
  1231. // Draggable resize bar
  1232. $('#vboxStorageResizeBar').draggable({cursor:(jQuery.browser.opera ? 'e-resize' : 'col-resize'),axis:'x',zIndex:99,helper:function(){
  1233. return $('<span />'); // dummy element
  1234. },scroll:false,'start':function(e,ui){
  1235. $('#vboxStorageResizeBar').data('vboxX',e.pageX);
  1236. $('#vboxResizeOverlay').remove();
  1237. $('body').disableSelection().css({'cursor':(jQuery.browser.opera ? 'e-resize' : 'col-resize')});
  1238. $('#vboxSettingsDialog').append($('<div />').attr({'id':'vboxResizeOverlay','style':'width:99%;height:99%;border:0px;margin:0px;padding:0px;position:absolute;top:0px;left:0px;cursor:'+(jQuery.browser.opera ? 'e-resize' : 'col-resize')}));
  1239. },'drag':function(e){
  1240. var sStart = $('#vboxStorageResizeBar').data('vboxX');
  1241. var sStop = e.pageX;
  1242. var sWidth = Math.abs(sStop - sStart);
  1243. if(sWidth == 0) return;
  1244. var lWidth = parseInt($('#vboxStoragePaneLeft').css('width'));
  1245. var rWidth = parseInt($('#vboxStoragePaneRight').css('width'));
  1246. var snapped = $('#vboxStorageResizeBar').data('vboxSnapped');
  1247. // Left to right
  1248. if(sStop > sStart) {
  1249. // Check for snapping
  1250. if(snapped) {
  1251. if(snapped > sStop || (rWidth - sWidth < 150)) { return; }
  1252. else if(snapped && snapped <= sStop) {
  1253. // Unsnap left pane
  1254. $('#vboxStoragePaneRight').parent().css({'width':'auto'});
  1255. $('#vboxStoragePaneLeft').css({'display':''}).parent().css({'padding':'6px'});
  1256. $('#vboxStorageResizeBar').data('vboxSnapped',0);
  1257. lWidth = $('#vboxStorageResizeBar').data('vboxSnappedWidthL');
  1258. rWidth = $('#vboxStorageResizeBar').data('vboxSnappedWidthR');
  1259. sWidth = Math.abs(sStop - snapped);
  1260. }
  1261. }
  1262. if(rWidth - sWidth < 150) {
  1263. $('#vboxStoragePaneLeft').css({'width':'100%'}).parent().css({'width':'100%'});
  1264. $('#vboxStoragePaneRight').css({'display':'none','width':'10px'}).parent().css({'padding':'0px'});
  1265. $('#vboxStorageResizeBar').data('vboxSnapped',e.pageX);
  1266. $('#vboxStorageResizeBar').data('vboxSnappedWidthL', (lWidth + sWidth));
  1267. $('#vboxStorageResizeBar').data('vboxSnappedWidthR', (rWidth - sWidth));
  1268. } else {
  1269. $('#vboxStoragePaneLeft').css({'width':(lWidth + sWidth)+'px','display':''});
  1270. $('#vboxStoragePaneRight').css({'width':(rWidth - sWidth)+'px','display':''});
  1271. }
  1272. // Right to left
  1273. } else {
  1274. // Check for snapping
  1275. if(snapped) {
  1276. if(snapped < sStop || (lWidth - sWidth < 150)) { return; }
  1277. else if(snapped && snapped >= sStop) {
  1278. // Unsnap right pane
  1279. $('#vboxStoragePaneLeft').parent().css({'width':'auto'});
  1280. $('#vboxStoragePaneRight').css({'display':''}).parent().css({'width':'100%','padding':'6px'}); // 100% to fix webkit
  1281. $('#vboxStorageResizeBar').data('vboxSnapped',0);
  1282. lWidth = $('#vboxStorageResizeBar').data('vboxSnappedWidthL');
  1283. rWidth = $('#vboxStorageResizeBar').data('vboxSnappedWidthR');
  1284. sWidth = Math.abs(sStop-snapped);
  1285. }
  1286. }
  1287. if(lWidth - sWidth < 150) {
  1288. $('#vboxStoragePaneRight').css({'width':'100%'}).parent().css({'width':'100%'});
  1289. $('#vboxStoragePaneLeft').css({'display':'none','width':'10px'}).parent().css({'padding':'0px'});
  1290. $('#vboxStorageResizeBar').data('vboxSnapped',e.pageX);
  1291. $('#vboxStorageResizeBar').data('vboxSnappedWidthL', (lWidth - sWidth));
  1292. $('#vboxStorageResizeBar').data('vboxSnappedWidthR', (rWidth + sWidth));
  1293. } else {
  1294. $('#vboxStoragePaneLeft').css({'width':(lWidth - sWidth)+'px'});
  1295. $('#vboxStoragePaneRight').css({'width':(rWidth + sWidth)+'px'});
  1296. }
  1297. }
  1298. $('#vboxStorageResizeBar').data('vboxX',e.pageX);
  1299. // resize labels
  1300. vboxStorageResizeTreeItemLabels();
  1301. },'stop':function(e) {
  1302. // resize labels
  1303. vboxStorageResizeTreeItemLabels();
  1304. $('body').enableSelection().css({'cursor':'default'});
  1305. $('#vboxResizeOverlay').remove();
  1306. }}).css({'cursor':(jQuery.browser.opera ? 'e-resize' : 'col-resize'),'height':'98%'});
  1307. });
  1308. </script>