Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

wizardImportAppliance.html 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. <!--
  2. Panes for import appliance wizard. Logic in vboxWizard() class
  3. Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com)
  4. $Id: wizardImportAppliance.html 595 2015-04-17 09:50:36Z imoore76 $
  5. -->
  6. <!-- Step 1 -->
  7. <div id='wizardImportApplianceStep1' title='Appliance to import' style='display: none'>
  8. <span class='translate'>&lt;p&gt;VirtualBox currently supports importing appliances saved in the Open Virtualization Format (OVF). To continue, select the file to import below.&lt;/p&gt;</span>
  9. <div class='vboxOptions'>
  10. <table style='width: 100%;' class='vboxOptions'>
  11. <tr>
  12. <td style='width: 100%; white-space: nowrap' class='vboxFileFolderInput'>
  13. <input type='text' class='vboxText' name='wizardImportApplianceLocation' style='width: 100%'/>
  14. </td>
  15. <td style='width:1%' id='wizardImportApplianceLocationButton'></td>
  16. </tr>
  17. </table>
  18. </div>
  19. </div>
  20. <!-- Step 2 -->
  21. <div id='wizardImportApplianceStep2' title='Appliance settings' style='display: none; width: 100%;'>
  22. <div class='translate' style='margin-bottom:8px;'>These are the virtual machines contained in the appliance and the suggested settings of the imported VirtualBox machines. You can change many of the properties shown by double-clicking on the items and disable others using the check boxes below.</div>
  23. <div class='vboxBordered' id='vboxImportPropsContainer' style='overflow: auto;'>
  24. <table style='width: 100%;' class='vboxHorizontal'>
  25. <!--
  26. <thead>
  27. <tr>
  28. <th style='text-align: left; width: 1%; padding-left: 10px' class='translate'>Description</th>
  29. <th style='text-align: left; padding-left: 10px;' class='translate'>Configuration</th>
  30. </tr>
  31. </thead>
  32. -->
  33. <tbody id='vboxImportProps'>
  34. </tbody>
  35. </table>
  36. </div>
  37. <div style='margin:2px;margin-top:4px;padding:0px;'><label><input type='checkbox' class='vboxCheckbox' name='vboxImportReinitNetwork' />
  38. <span class='translateglob'>Reinitialize the MAC address of all network cards</span></label>
  39. </div>
  40. </div>
  41. <script type='text/javascript'>
  42. /* Draw button */
  43. new vboxToolbarSingle({button: {
  44. 'name' : 'mselecthdbtn',
  45. 'label' : 'Choose a virtual appliance file to import...',
  46. 'language_context': 'UIWizardImportApp',
  47. 'icon' : 'select_file',
  48. 'click' : function () {
  49. wizardImportApplianceBrowseLocation()
  50. }
  51. }}).renderTo('wizardImportApplianceLocationButton');
  52. $('#wizardImportApplianceStep2').find('span.translateglob').html(function(i,h){
  53. return trans(h,'UIApplianceEditorWidget');
  54. });
  55. /*
  56. *
  57. * VM Properties to edit / import
  58. *
  59. */
  60. var vboxApplianceImportProps = {
  61. 'Name' : {'label':'Name','icon':'name','edit':'text'},
  62. 'Description' : {'label':'Description','icon':'description','edit':'textarea'},
  63. 'OS' : {'label':'Guest OS Type','icon':'os_type','edit':function(elm){
  64. var input = $('<input />').attr({'type':'button','class':'vboxbutton'}).css({'width':($(elm).innerWidth()-12)+'px','margin':'0px'}).val($(elm).find('span.vboxApplianceOSTitle').html());
  65. $(elm).children().hide();
  66. $(elm).append(input);
  67. $(elm).children('input:button').first().contextMenu({
  68. menu: 'vboxOSTypesMenu',
  69. button: 0,
  70. mode: 'menu',
  71. inSpeed : -1,
  72. outSpeed : -1
  73. },
  74. function(a, el, pos, srcEl) {
  75. $(elm).find('span.vboxApplianceOSTitle').html(vboxSettingsOSTypesObj[a]['description']);
  76. $(elm).find('img.vboxApplianceOSIcon').attr('src','images/vbox/'+vboxGuestOSTypeIcon(a));
  77. $(elm).closest('td').data('descValue',a);
  78. $('#vboxImportProps').trigger('selectProp');
  79. }).focus();
  80. $('#vboxImportProps').one('selectProp',function(){
  81. $(elm).children('input:button').first().hide().siblings().show();
  82. $(elm).children('input:button').first().remove();
  83. });
  84. },'display':function(val){
  85. return $('<span />').append('<img class="vboxApplianceOSIcon" src="images/vbox/'+vboxGuestOSTypeIcon(val)+'" style="height: 16px; width: 16px; float: left; margin-top: 2px; margin-right: 4px; " /> <span class="vboxApplianceOSTitle">' + vboxSettingsOSTypesObj[val].description +'</span>').disableSelection().on('selectstart',function(e){e.preventDefault();return false;});
  86. }},
  87. 'CPU' : {'label':'CPU','icon':'cpu','edit':'text','postEdit':function(val,old){
  88. val = parseInt(val);
  89. if(isNaN(val)) return old;
  90. return Math.min($('#vboxPane').data('vboxSystemProperties').maxGuestCPUCount,Math.max($('#vboxPane').data('vboxSystemProperties').minGuestCPUCount,val));
  91. }},
  92. 'Memory' : {'label':'RAM','icon':'ram','edit':'text','display':function(val){
  93. return Math.max(parseInt(val),0) + ' ' + trans('MB','VBoxGlobal');
  94. },'postEdit':function(val,old) {
  95. val = parseInt(val);
  96. if(isNaN(val)) return old;
  97. return Math.min($('#vboxPane').data('vboxSystemProperties').maxGuestRAM,Math.max($('#vboxPane').data('vboxSystemProperties').minGuestRAM,val));
  98. }},
  99. 'SoundCard' : {'label':'Sound Card','icon':'sound','checkbox':true,'edit':'options','display':function(val){
  100. return trans(vboxAudioController($('#vboxPane').data('vboxAudioControllerTypes')[val]),'VBoxGlobal');
  101. }},
  102. 'CDROM' : {'label':'DVD','icon':'cd','checkbox':true,'edit':'checkbox'},
  103. 'USBController' : {'label':'USB Controller','icon':'usb','checkbox':true},
  104. 'NetworkAdapter' : {'label':'Network Adapter','icon':'nw','checkbox':true,'edit':'options','option_offset':-1,'display':function(val){
  105. return trans(vboxNetworkAdapterType($('#vboxPane').data('vboxNetworkAdapterTypes')[val]),'VBoxGlobal');
  106. }},
  107. 'Floppy' : {'label':'Floppy','icon':'floppy','checkbox':true},
  108. 'HardDiskControllerIDE' : {'label':'Storage Controller (IDE)','icon':'ide','edit':''},
  109. 'HardDiskControllerSATA' : {'label':'Storage Controller (SATA)','icon':'sata','edit':null},
  110. 'HardDiskControllerSAS' : {'label':'Storage Controller (SAS)','icon':'scsi','edit':null},
  111. 'HardDiskControllerSCSI' : {'label':'Storage Controller (SCSI)','icon':'scsi','edit':null},
  112. 'HardDiskImage' : {'label':'Virtual Disk Image','icon':'hd','edit':'text'}
  113. };
  114. /*
  115. *
  116. * Add Property Options
  117. *
  118. */
  119. // Storage controllers
  120. var stTypes = vboxStorage.getBusTypes();
  121. for(var i = 0; i < stTypes.length; i++) {
  122. if(!vboxApplianceImportProps['HardDiskController'+stTypes[i]]) continue;
  123. // Translate value
  124. vboxApplianceImportProps['HardDiskController'+stTypes[i]]['display'] = function(val){return trans(vboxStorageControllerType(val),'VBoxGlobal');};
  125. var ctypes = vboxStorage[stTypes[i]].types;
  126. if(ctypes.length < 2) continue;
  127. var opts = {};
  128. for(var a = 0; a < ctypes.length; a++) {
  129. opts[ctypes[a]] = trans(vboxStorageControllerType(ctypes[a]),'VBoxGlobal');
  130. }
  131. vboxApplianceImportProps['HardDiskController'+stTypes[i]]['edit'] = 'options';
  132. vboxApplianceImportProps['HardDiskController'+stTypes[i]]['options'] = opts;
  133. }
  134. vboxApplianceImportProps['NetworkAdapter']['options'] = [];
  135. vboxApplianceImportProps['SoundCard']['options'] = [];
  136. // Network adapters
  137. var cs = $('#vboxPane').data('vboxNetworkAdapterTypes');
  138. for(var i = 1; i < cs.length; i++) {
  139. vboxApplianceImportProps['NetworkAdapter']['options'][(i-1)] = trans(vboxNetworkAdapterType(cs[i]),'VBoxGlobal');
  140. }
  141. // Sound cards
  142. var cs = $('#vboxPane').data('vboxAudioControllerTypes');
  143. for(var i = 0; i < cs.length; i++) {
  144. vboxApplianceImportProps['SoundCard']['options'][i] = trans(vboxAudioController(cs[i]),'VBoxGlobal');
  145. }
  146. // OS Types
  147. /////////////////////////
  148. $('ul.vboxOSTypesMenuList').remove();
  149. // shorthand
  150. var vboxOSTypes = $('#vboxPane').data('vboxOSTypes');
  151. var vboxSettingsOSTypes = {};
  152. var vboxSettingsOSTypesObj = {};
  153. for(var i in vboxOSTypes) {
  154. // Skip unsupported OS Types
  155. if(!vboxOSTypes[i].supported) continue;
  156. // create array of os family types
  157. if(!vboxSettingsOSTypes[vboxOSTypes[i].familyId]) {
  158. vboxSettingsOSTypes[vboxOSTypes[i].familyId] = {'id':vboxOSTypes[i].familyId,'description':vboxOSTypes[i].familyDescription,'osTypes':[]};
  159. }
  160. vboxSettingsOSTypes[vboxOSTypes[i].familyId].osTypes[vboxSettingsOSTypes[vboxOSTypes[i].familyId].osTypes.length] = {'id':vboxOSTypes[i].id,'description':vboxOSTypes[i].description };
  161. vboxSettingsOSTypesObj[vboxOSTypes[i].id] = vboxOSTypes[i];
  162. // Preload icons
  163. vboxOSTypes[i].icon = new Image();
  164. vboxOSTypes[i].icon.src = "images/vbox/" + vboxGuestOSTypeIcon(vboxOSTypes[i].id);
  165. }
  166. var ul = $('<ul />').attr({'id':'vboxOSTypesMenu','class':'contextMenu contextMenuNoBG vboxOSTypesMenuList'});
  167. for(var i in vboxSettingsOSTypes) {
  168. var li = $('<li />').html('<a href="#null-'+i+'">'+vboxSettingsOSTypes[i].description+'</a>');
  169. var ul2 = $('<ul />').addClass('vboxOSTypesMenuList');
  170. for(var a in vboxSettingsOSTypes[i]['osTypes']) {
  171. $('<li />').html('<a href="#'+vboxSettingsOSTypes[i]['osTypes'][a]['id']+'"><img style="height: 16px; width:16px; margin-left: -22px; margin-top: 2px; float: left; " src="images/vbox/'+vboxGuestOSTypeIcon(vboxSettingsOSTypes[i]['osTypes'][a]['id'])+'" /> '+vboxSettingsOSTypes[i]['osTypes'][a]['description']+"</a>").appendTo(ul2);
  172. }
  173. $(li).append(ul2).appendTo(ul);
  174. }
  175. $('#vboxPane').append(ul);
  176. /* Browse for import location */
  177. function wizardImportApplianceBrowseLocation() {
  178. var dsepRegEx = $('#vboxPane').data('vboxConfig').DSEP;
  179. if(dsepRegEx == '\\') dsepRegEx += '\\';
  180. var loc = $('#vboxPane').data('vboxSystemProperties').defaultMachineFolder;
  181. vboxFileBrowser(loc,function(f){
  182. if(!f) return;
  183. document.forms['frmwizardImportAppliance'].elements.wizardImportApplianceLocation.value = f;
  184. },false,trans('Select an appliance to import','UIWizardImportApp'),'images/vbox/os_type_16px.png');
  185. }
  186. /* When going to step2, make sure a file is selected and
  187. * appliance file was parsed
  188. */
  189. $('#wizardImportApplianceStep2').on('show',function(e,wiz){
  190. if(!$(document.forms['frmwizardImportAppliance'].elements.wizardImportApplianceLocation).val()) {
  191. $(document.forms['frmwizardImportAppliance'].elements.wizardImportApplianceLocation).addClass('vboxRequired');
  192. wiz.displayStep(1);
  193. return;
  194. }
  195. $(document.forms['frmwizardImportAppliance'].elements.wizardImportApplianceLocation).removeClass('vboxRequired').focus();
  196. wizardImportAppResize();
  197. // Remove any existing VMs from Back / Forward wizard navigation
  198. $('#vboxImportProps').children().remove();
  199. /* Parse appliance file */
  200. var l = new vboxLoader();
  201. l.add('applianceReadInterpret',function(d){
  202. if(d && d.responseData && d.responseData.descriptions && d.responseData.descriptions.length) { wizardImportApplianceParsed(d.responseData); }
  203. else if(!d) { vboxAlert(trans('Unkown Error')); wiz.displayStep(1);}
  204. else { wiz.displayStep(1); } // no data. assume error was displayed
  205. },{'file':$(document.forms['frmwizardImportAppliance'].elements.wizardImportApplianceLocation).val()});
  206. l.run();
  207. });
  208. function wizardImportAppResize(){
  209. // Resize properties
  210. $('#vboxImportPropsContainer').hide();
  211. var h = $('#wizardImportApplianceStep2').parent().innerHeight() - $('#wizardImportApplianceTitle').outerHeight(true);
  212. $('#vboxImportPropsContainer').siblings().each(function(){
  213. h -= $(this).outerHeight(true);
  214. });
  215. $('#vboxImportPropsContainer').width($('#vboxImportPropsContainer').parent().innerWidth()).height(h-4).show();
  216. }
  217. $('#wizardImportApplianceDialog').on('dialogresizestop',wizardImportAppResize);
  218. /* After appliance file is parsed */
  219. function wizardImportApplianceParsed(d) {
  220. // Remove any existing data
  221. $('#vboxImportProps').children().remove();
  222. var tbl = $('#vboxImportProps');
  223. if(!d) d = {'descriptions':$(tbl).data('descriptions')};
  224. else $(tbl).data('descriptions',d.descriptions);
  225. for(var vm = 0; vm < d.descriptions.length; vm++) {
  226. var tr = $('<tr />').data({'vmDesc':d.descriptions[vm]}).attr({'class':'vboxApplianceHeaderRow'});
  227. var td = $('<td />').attr({'colspan':'2','class':'vboxApplianceHeader'});
  228. $('<input />').data({'vboxOrder':vm}).attr({'type':'button','class':'vboxImgButton','style':'background-image: url(images/downArrow.png); width: 12px; height: 12px; margin-right: 4px;'}).click(function(){
  229. if(!$(this).data('toggleClicked')) {
  230. $(this).data('toggleClicked', true);
  231. $(this).css({'background-image':'url(images/rightArrow.png)'});
  232. $(this).parent().parent().parent().children('tr.vboxChildOf'+$(this).data('vboxOrder')).css('display','none');
  233. } else {
  234. $(this).data('toggleClicked', false);
  235. $(this).css({'background-image':'url(images/downArrow.png)'});
  236. $(this).parent().parent().parent().children('tr.vboxChildOf'+$(this).data('vboxOrder')).css('display','');
  237. }
  238. }).appendTo(td);
  239. $(td).append(trans('Virtual System %1','UIApplianceEditorWidget').replace('%1',(vm+1))).appendTo(tr);
  240. $(tbl).append(tr);
  241. // Hard Disks are handled differently
  242. var hds = [];
  243. for(var i = 0; i < d.descriptions[vm][0].length; i++) {
  244. var desc = vboxApplianceImportProps[d.descriptions[vm][0][i]];
  245. if(desc == undefined) continue;
  246. var tr = $('<tr />').data({'descType':d.descriptions[vm][0][i],'descOrder':i}).addClass('vboxChildOf'+vm, ' vboxListItem').attr({'id':'vboxVM-'+vm+'-item-'+i}).click(function(){
  247. $('#vboxImportProps').find('input').trigger('blur');
  248. if($(this).hasClass('vboxListItemSelected')) return;
  249. $(this).siblings('tr.vboxListItemSelected').removeClass('vboxListItemSelected');
  250. $(this).addClass('vboxListItemSelected');
  251. $(this).parent().trigger('selectProp',this);
  252. });
  253. $('<td />').css({'white-space':'nowrap','width':'1%'}).attr({'class':'vbox'+d.descriptions[vm][0][i]}).html('<img src="images/vbox/blank.gif" class="vboxSpacer" style="height:2px;"/><img src="images/vbox/'+desc.icon+'_16px.png" style="height: 16px; width: 16px;"/> ' + trans(desc.label,'UIApplianceEditorWidget')).appendTo(tr);
  254. var td = $('<td />').attr({'class':'vboxHideOverflow'}).css({'padding-left':'10px'});
  255. if(desc.checkbox) {
  256. $('<input />').attr({'type':'checkbox','class':'vboxCheckbox'}).prop('checked',true).css({'margin-right':'5px'}).click(function(){
  257. $(this).closest('tr').data('propdisabled',!(this.checked));
  258. if(this.checked) {
  259. $(this).siblings().removeClass('vboxDisabled');
  260. } else {
  261. $(this).siblings().addClass('vboxDisabled');
  262. }
  263. }).appendTo(td);
  264. }
  265. var sp = $('<span />').css({'display':'inline-block'}).attr({'class':'vboxImportAppProp'});
  266. if(desc.display) {
  267. $(sp).html(desc.display(d.descriptions[vm][3][i]));
  268. } else {
  269. $(sp).text(d.descriptions[vm][3][i]);
  270. }
  271. $(td).data({'descValue':d.descriptions[vm][3][i]}).append(sp).dblclick(function(){
  272. // Edit property function
  273. var desc = vboxApplianceImportProps[$(this).parent().data('descType')];
  274. // Check for checkbox
  275. if(desc.checkbox && !$(this).children('input:checkbox').first().prop('checked')) return;
  276. switch(desc.edit) {
  277. case 'options':
  278. vboxImportAppliancePropEditOptions(this,desc);
  279. break;
  280. case 'text':
  281. vboxImportAppliancePropEdit(this,desc);
  282. break;
  283. case 'textarea':
  284. vboxImportAppliancePropEditArea(this,desc);
  285. break;
  286. default:
  287. if(typeof desc.edit == 'function') desc.edit(this,desc);
  288. }
  289. }).disableSelection().appendTo(tr);
  290. // Hard Disks are handled differently
  291. if(d.descriptions[vm][0][i] == 'HardDiskImage') {
  292. var place = d.descriptions[vm][4][i].split(';');
  293. var con = parseInt(place[0].replace(/.*=/,''));
  294. var dev = parseInt(place[1].replace(/.*=/,''));
  295. hds[hds.length] = {'element':tr,'controller':con,'device':dev};
  296. } else {
  297. $(tbl).append(tr);
  298. }
  299. } // </ foreach description item >
  300. // Attach hard disks
  301. hds.sort(function(a,b){
  302. if(a.device == b.device) return 0;
  303. return (a.device < b.device ? 1 : -1); // Yes. Reverse order.
  304. });
  305. for(var i = 0; i < hds.length; i++) {
  306. $('#vboxVM-'+vm+'-item-'+hds[i].controller).after(hds[i].element);
  307. }
  308. } // </ foreach vm >
  309. vboxColorRows(tbl,false,'vboxApplianceHeaderRow');
  310. $('#vboxImportProps').disableSelection();
  311. // Check for import warnings
  312. if(d.warnings && d.warnings.length) {
  313. var div = $('<div />');
  314. $(div).append(trans('Warnings:','UIApplianceEditorWidget'));
  315. var ul = $('<ul />');
  316. for(var i = 0; i < d.warnings.length; i++) {
  317. $('<li />').html(d.warnings[i]).appendTo(ul);
  318. }
  319. $(div).append(ul);
  320. var buttons = {};
  321. buttons[trans('OK','QIMessageBox')] = function(){$(this).empty().remove();};
  322. $(div).dialog({'height':300,'width':300,'closeOnEscape':false,'modal':true,'resizable':true,'draggable':true,'buttons':buttons,'title':trans('Warnings:')});
  323. }
  324. };
  325. /*
  326. *
  327. * Edit property that has options
  328. *
  329. */
  330. function vboxImportAppliancePropEditOptions(elm,desc) {
  331. var s = $('<select />').attr({'id':'vboxImportAppSelect'}).css({'width':'100%'}).change(function(){
  332. $(this).parent().data('descValue',$(this).val());
  333. var txt = this.options[this.selectedIndex].text;
  334. $(this).siblings('span.vboxImportAppProp').text(txt);
  335. });
  336. var val = $(elm).data('descValue');
  337. if(desc.option_offset) {
  338. val = parseInt(val) + parseInt(desc.option_offset);
  339. val = ''+val;
  340. }
  341. selOpt = 0;
  342. var a = 0;
  343. for(var i in desc.options) {
  344. $(s).prop('options').add(new Option(desc.options[i],i,(i == val),(i == val)));
  345. if(i==val) selOpt = a;
  346. a++;
  347. }
  348. $(s).attr('selectedIndex',selOpt);
  349. $(elm).children().hide();
  350. $(elm).append(s);
  351. $('#vboxImportProps').one('selectProp',function(){
  352. $('#vboxImportAppSelect').hide().siblings().show();
  353. $('#vboxImportAppSelect').remove();
  354. });
  355. }
  356. /*
  357. *
  358. * Edit property that has a text area
  359. *
  360. */
  361. function vboxImportAppliancePropEditArea(elm) {
  362. $(elm).children().hide();
  363. $('<input />').attr({'type':'button','class':'vboxbutton'}).css({'width':($(elm).innerWidth()-12)+'px','margin':'0px'}).val(trans('Edit text','VBoxTextEditor')).click(function(){
  364. vboxImportAppliancePropEditDialog(elm);
  365. $('#vboxImportProps').trigger('selectProp');
  366. }).appendTo(elm);
  367. $(elm).children('input:button').first().focus();
  368. $('#vboxImportProps').one('selectProp',function(){
  369. $(elm).children('input:button').first().hide().siblings().show();
  370. $(elm).children('input:button').first().remove();
  371. });
  372. }
  373. /*
  374. *
  375. * Edit property dialog
  376. *
  377. */
  378. function vboxImportAppliancePropEditDialog(td) {
  379. var d = $('<div />').css({'display':'none'});
  380. var frm = $('<form />').attr({'onSubmit':'return false;'}).css({'margin':'0px','border':'0px','padding':'0px','width':'100%','height':'100%'});
  381. $('<textarea />').attr({'id':'vboxImportAppliancePropTextarea'}).css({'height':'99%','width':'99%'}).val($(td).data('descValue')).appendTo(frm);
  382. $(d).append(frm);
  383. var buttons = {};
  384. buttons[trans('OK','QIMessageBox')] = function(){
  385. $(td).data('descValue',$('#vboxImportAppliancePropTextarea').val());
  386. $(td).children('span.vboxImportAppProp').html($('<div />').text($('#vboxImportAppliancePropTextarea').val()).html());
  387. $(this).empty().remove();
  388. };
  389. buttons[trans('Cancel','QIMessageBox')] = function(){$(this).empty().remove();};
  390. $(d).dialog({'height':300,'width':300,'closeOnEscape':false,'modal':true,'resizable':true,'dialogClass':'vboxDialogContent','draggable':true,'buttons':buttons,'title':$(td).prev().html()});
  391. }
  392. /*
  393. *
  394. * Edit property that has a text box
  395. *
  396. */
  397. function vboxImportAppliancePropEdit(elm,desc) {
  398. $(elm).children().hide();
  399. $('<input />').attr({'type':'text','class':'vboxText'}).css({'width':($(elm).innerWidth()-12)+'px','margin':'0px'}).val($(elm).data('descValue')).blur(function(){
  400. var tbox = this;
  401. var val = (desc.postEdit ? desc.postEdit($(tbox).val(),$(tbox).parent().data('descValue')) : $(tbox).val());
  402. if(val != $(tbox).parent().data('descValue')) {
  403. $(tbox).parent().data('descValue',val);
  404. if(desc.display) {
  405. $(tbox).siblings('span.vboxImportAppProp').html(desc.display(val));
  406. } else {
  407. $(tbox).siblings('span.vboxImportAppProp').text(val);
  408. }
  409. $(tbox).parent().data('edited', true);
  410. // Special case for name
  411. if(desc.label == 'Name') {
  412. // Get ChildOf class
  413. var r = /(vboxChildOf\d+)/;
  414. var coClass = r.exec($(tbox).closest('tr').attr('class'));
  415. coClass = coClass[1];
  416. // Get unedited disk rows
  417. var diskRows = new Array();
  418. $.each($(tbox).parent().closest('tr').siblings('.'+coClass), function(i,e){
  419. if(!$(e).data('edited') && $(e).data('descType') == 'HardDiskImage') {
  420. diskRows[diskRows.length] = e;
  421. }
  422. });
  423. if(diskRows.length) {
  424. var mfd = new vboxLoader();
  425. mfd.add('vboxGetComposedMachineFilename',function(d){
  426. var mfolder = vboxDirname(d.responseData) + $("#vboxPane").data('vboxConfig').DSEP;
  427. for(var i = 0; i < diskRows.length; i++) {
  428. var tdc = $(diskRows[i]).children().eq(1);
  429. var dname = vboxBasename($(tdc).data('descValue'));
  430. $(tdc).data({'descValue':mfolder + dname}).find('span.vboxImportAppProp').text(mfolder + dname);
  431. }
  432. },{'name':val,'group':''});
  433. mfd.run();
  434. }
  435. }
  436. }
  437. $(tbox).hide();
  438. $(tbox).siblings().show();
  439. $(tbox).remove();
  440. }).keydown(function(e){if(e.keyCode == 13) $(this).trigger('blur');}).appendTo(elm);
  441. $(elm).children('input:text').first().focus();
  442. }
  443. </script>