選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

wizardImportApplianceAdvanced.html 20KB

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