[pve-devel] r6292 - in pve-manager/pve2: . www/manager www/manager/dc www/manager/form www/manager/node www/manager/panel www/manager/qemu www/manager/window

svn-commits at proxmox.com svn-commits at proxmox.com
Wed Jul 13 07:38:48 CEST 2011


Author: dietmar
Date: 2011-07-13 07:38:48 +0200 (Wed, 13 Jul 2011)
New Revision: 6292

Added:
   pve-manager/pve2/www/manager/form/ControllerSelector.js
   pve-manager/pve2/www/manager/panel/InputPanel.js
   pve-manager/pve2/www/manager/qemu/CDEdit.js
   pve-manager/pve2/www/manager/qemu/DisplayEdit.js
   pve-manager/pve2/www/manager/qemu/HDEdit.js
   pve-manager/pve2/www/manager/qemu/KeyboardEdit.js
   pve-manager/pve2/www/manager/qemu/MemoryEdit.js
   pve-manager/pve2/www/manager/qemu/NetworkEdit.js
   pve-manager/pve2/www/manager/qemu/OSTypeEdit.js
   pve-manager/pve2/www/manager/qemu/ProcessorEdit.js
Modified:
   pve-manager/pve2/ChangeLog
   pve-manager/pve2/www/manager/Makefile.am
   pve-manager/pve2/www/manager/dc/UserEdit.js
   pve-manager/pve2/www/manager/dc/UserView.js
   pve-manager/pve2/www/manager/form/BusTypeSelector.js
   pve-manager/pve2/www/manager/form/ComboGrid.js
   pve-manager/pve2/www/manager/node/NetworkEdit.js
   pve-manager/pve2/www/manager/qemu/CreateWizard.js
   pve-manager/pve2/www/manager/qemu/HardwareView.js
   pve-manager/pve2/www/manager/qemu/Options.js
   pve-manager/pve2/www/manager/window/Edit.js
   pve-manager/pve2/www/manager/window/Wizard.js
Log:
	* www/manager/window/Edit.js: do not automatically instanziate an
	'inputpanel' (you need to do that yourself now). removed getParams
	method (you can use an inputpanel with onGetValues() instead).

	* www/manager/panel/InputPanel.js: moved into separate file, add
	two column layout code, set setValues() method

	* www/manager/qemu/*: use new Edit.js/InputPanel.js code
	everwhere. That way I removed most code duplication.

	* www/manager/qemu/HardwareView.js: split out code to separate
	files.

	* www/manager/dc/UserView.js: s/enabled/enable/ (thanks to Seth),
	adoptions for new Edit.js



Modified: pve-manager/pve2/ChangeLog
===================================================================
--- pve-manager/pve2/ChangeLog	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/ChangeLog	2011-07-13 05:38:48 UTC (rev 6292)
@@ -1,3 +1,21 @@
+2011-07-13  Proxmox Support Team  <support at proxmox.com>
+
+	* www/manager/window/Edit.js: do not automatically instanziate an
+	'inputpanel' (you need to do that yourself now). removed getParams
+	method (you can use an inputpanel with onGetValues() instead).
+
+	* www/manager/panel/InputPanel.js: moved into separate file, add
+	two column layout code, set setValues() method
+
+	* www/manager/qemu/*: use new Edit.js/InputPanel.js code
+	everwhere. That way I removed most code duplication.
+
+	* www/manager/qemu/HardwareView.js: split out code to separate
+	files.
+
+	* www/manager/dc/UserView.js: s/enabled/enable/ (thanks to Seth),
+	adoptions for new Edit.js
+
 2011-07-11  Proxmox Support Team  <support at proxmox.com>
 
 	* www/manager/window/Wizard.js: also verify top level

Modified: pve-manager/pve2/www/manager/Makefile.am
===================================================================
--- pve-manager/pve2/www/manager/Makefile.am	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/Makefile.am	2011-07-13 05:38:48 UTC (rev 6292)
@@ -21,6 +21,7 @@
 	form/NetworkCardSelector.js			\
 	form/DiskFormatSelector.js			\
 	form/BusTypeSelector.js				\
+	form/ControllerSelector.js			\
 	form/RealmComboBox.js				\
 	form/BondModeSelector.js			\
 	form/ViewSelector.js				\
@@ -36,6 +37,7 @@
 	dc/Log.js					\
 	panel/StatusPanel.js				\
 	panel/RRDView.js				\
+	panel/InputPanel.js				\
 	window/Edit.js					\
 	window/LoginWindow.js				\
 	window/TaskViewer.js				\
@@ -59,6 +61,14 @@
 	node/Config.js					\
 	qemu/StatusView.js				\
 	qemu/Summary.js					\
+	qemu/OSTypeEdit.js				\
+	qemu/ProcessorEdit.js				\
+	qemu/MemoryEdit.js				\
+	qemu/NetworkEdit.js				\
+	qemu/CDEdit.js					\
+	qemu/HDEdit.js					\
+	qemu/DisplayEdit.js				\
+	qemu/KeyboardEdit.js				\
 	qemu/HardwareView.js				\
 	qemu/Options.js					\
 	qemu/Config.js					\

Modified: pve-manager/pve2/www/manager/dc/UserEdit.js
===================================================================
--- pve-manager/pve2/www/manager/dc/UserEdit.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/dc/UserEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -18,7 +18,7 @@
             method = 'PUT';
         }
 
-        me.column1 = [
+        var column1 = [
             {
                 xtype: me.create ? 'textfield' : 'displayfield',
                 name: 'userid',
@@ -40,7 +40,7 @@
             }
         ];
 
-        me.column2 = [
+        var column2 = [
             {
                 xtype: 'textfield',
                 name: 'firstname',
@@ -54,7 +54,7 @@
         ];
 
         if (!me.create) {
-            me.column1.push({
+            column1.push({
                 xtype: 'pvecheckbox',
                 fieldLabel: 'Enable',
                 name: 'enable',
@@ -65,7 +65,12 @@
         Ext.applyIf(me, {
             title: me.create ? "Create User" : "Edit User '" + me.userid + "'",
             url: url,
-            method: method
+            method: method,
+	    items: {
+                xtype: 'inputpanel',
+		column1: column1,
+		column2: column2
+ 	    }
         });
 
         me.callParent();

Modified: pve-manager/pve2/www/manager/dc/UserView.js
===================================================================
--- pve-manager/pve2/www/manager/dc/UserView.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/dc/UserView.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -141,7 +141,7 @@
 		    header: 'Enabled',
 		    width: 80,
 		    sortable: true,
-		    dataIndex: 'enabled'
+		    dataIndex: 'enable'
 		},
 		{
 		    header: 'Expire',
@@ -178,7 +178,7 @@
 	extend: 'Ext.data.Model',
 	fields: [ 
 	    'userid', 'firstname', 'lastname' , 'email', 'comment',
-	    { type: 'boolean', name: 'enabled' }, 
+	    { type: 'boolean', name: 'enable' }, 
 	    { type: 'date', dateFormat: 'timestamp', name: 'expire' }
 	],
 	idProperty: 'userid'

Modified: pve-manager/pve2/www/manager/form/BusTypeSelector.js
===================================================================
--- pve-manager/pve2/www/manager/form/BusTypeSelector.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/form/BusTypeSelector.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -2,6 +2,10 @@
     extend: 'PVE.form.KVComboBox',
     alias: ['widget.PVE.form.BusTypeSelector'],
   
+    noVirtio: false,
+
+    noScsi: false,
+
     initComponent: function() {
 	var me = this;
 

Modified: pve-manager/pve2/www/manager/form/ComboGrid.js
===================================================================
--- pve-manager/pve2/www/manager/form/ComboGrid.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/form/ComboGrid.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -69,6 +69,8 @@
 	    matchFieldWidth: false
 	});
 
+	Ext.applyIf(me, { value: ''}); // hack: avoid ExtJS validate() bug
+
 	Ext.applyIf(me.listConfig, { width: 400 });
 
         me.callParent();

Added: pve-manager/pve2/www/manager/form/ControllerSelector.js
===================================================================
--- pve-manager/pve2/www/manager/form/ControllerSelector.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/form/ControllerSelector.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,109 @@
+Ext.define('PVE.form.ControllerSelector', {
+    extend: 'Ext.form.FieldContainer',
+    alias: ['widget.PVE.form.ControllerSelector'],
+   
+    statics: {
+	maxIds: {
+	    ide: 3,
+	    virtio: 15,
+	    scsi: 15
+	}
+    },
+
+    noVirtio: false,
+
+    noScsi: false,
+
+    vmconfig: {}, // used to check for existing devices
+
+    setVMConfig: function(vmconfig, autoSelect) {
+	var me = this;
+
+	me.vmconfig = Ext.apply({}, vmconfig);
+	if (autoSelect) {
+	    var clist = ['ide', 'virtio', 'scsi'];
+	    if (autoSelect === 'cdrom') {
+		clist = ['ide', 'scsi'];
+		if (!Ext.isDefined(me.vmconfig.ide2)) {
+		    me.down('field[name=controller]').setValue('ide');
+		    me.down('field[name=deviceid]').setValue(2);
+		    return;
+		}
+	    } else if (me.vmconfig.ostype === 'l26') {
+		clist = ['virtio', 'ide', 'scsi'];
+	    }
+
+	    Ext.Array.each(clist, function(controller) {
+		var confid, i;
+		if ((controller === 'virtio' && me.noVirtio) ||
+		    (controller === 'scsi' && me.noScsi)) {
+		    return; //continue
+		}
+		me.down('field[name=controller]').setValue(controller);
+		for (i = 0; i <= PVE.form.ControllerSelector.maxIds[controller]; i++) {
+		    confid = controller + i.toString();
+		    if (!Ext.isDefined(me.vmconfig[confid])) {
+			me.down('field[name=deviceid]').setValue(i);
+			return false; // break
+		    }
+		}
+	    });
+	}
+	me.down('field[name=deviceid]').validate();
+    },
+
+    initComponent: function() {
+	var me = this;
+
+	Ext.apply(me, {
+	    fieldLabel: 'Bus/Device',
+	    layout: 'hbox',
+	    height: 22, // hack: set to same height as other fields
+	    defaults: {
+                flex: 1,
+                hideLabel: true
+	    },
+	    items: [
+		{
+		    xtype: 'PVE.form.BusTypeSelector',
+		    name: 'controller',
+		    value: 'ide',
+		    noVirtIO: me.noVirtio,
+		    allowBlank: false,
+		    listeners: {
+			change: function(t, value) {
+			    if (!me.rendered || !value) {
+				return;
+			    }
+			    var field = me.down('field[name=deviceid]');
+			    field.setMaxValue(PVE.form.ControllerSelector.maxIds[value]);
+			    field.validate();
+			}
+		    }
+		},
+		{
+		    xtype: 'numberfield',
+		    name: 'deviceid',
+		    minValue: 0,
+		    maxValue: PVE.form.ControllerSelector.maxIds.ide,
+		    value: '0',
+		    validator: function(value) {
+			/*jslint confusion: true */
+			if (!me.rendered) {
+			    return;
+			}
+			var field = me.down('field[name=controller]');
+			var controller = field.getValue();
+			var confid = controller + value;
+			if (Ext.isDefined(me.vmconfig[confid])) {
+			    return "This device is already in use.";
+			}
+			return true;
+		    }
+		}
+	    ]
+	});
+
+	me.callParent();
+    }
+});   
\ No newline at end of file

Modified: pve-manager/pve2/www/manager/node/NetworkEdit.js
===================================================================
--- pve-manager/pve2/www/manager/node/NetworkEdit.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/node/NetworkEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -33,7 +33,7 @@
 	    title = "Edit network device '" + me.iface + "'";
 	}
 
-	me.column2 = [
+	var column2 = [
 	    {
 		xtype: 'pvecheckbox',
 		fieldLabel: 'Autostart',
@@ -44,18 +44,18 @@
 	];
 
 	if (me.iftype === 'bridge') {
-	    me.column2.push({
+	    column2.push({
 		xtype: 'textfield',
 		fieldLabel: 'Bridge ports',
 		name: 'bridge_ports'
 	    });	  
 	} else if (me.iftype === 'bond') {
-	    me.column2.push({
+	    column2.push({
 		xtype: 'textfield',
 		fieldLabel: 'Slaves',
 		name: 'slaves'
 	    });
-	    me.column2.push({
+	    column2.push({
 		xtype: 'bondModeSelector',
 		fieldLabel: 'Mode',
 		name: 'bond_mode',
@@ -75,10 +75,11 @@
 	    method = 'PUT';
 	}
 
-	me.column1 = [
+	var column1 = [
 	    {
 		xtype: me.create ? 'textfield' : 'displayfield',
 		fieldLabel: 'Name',
+		height: 22, // hack: set same height as text fields
 		name: 'iface',
 		value: me.iface,
 		vtype: iface_vtype,
@@ -128,7 +129,12 @@
 	Ext.applyIf(me, {
 	    title: title,
 	    url: url,
-	    method: method
+	    method: method,
+	    items: {
+                xtype: 'inputpanel',
+		column1: column1,
+		column2: column2
+ 	    }
 	});
 
 	me.callParent();

Added: pve-manager/pve2/www/manager/panel/InputPanel.js
===================================================================
--- pve-manager/pve2/www/manager/panel/InputPanel.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/panel/InputPanel.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,103 @@
+Ext.define('PVE.panel.InputPanel', {
+    extend: 'Ext.panel.Panel',
+    requires: [
+	'PVE.Utils'
+    ],
+    alias: ['widget.inputpanel'],
+
+    border: false,
+
+    // overwrite this to modify submit data
+    onGetValues: function(values) {
+	return values;
+    },
+
+    getValues: function(dirtyOnly) {
+	var me = this;
+
+	if (Ext.isFunction(me.onGetValues)) {
+	    dirtyOnly = false;
+	}
+
+	var values = {};
+
+	Ext.Array.each(me.query('[isFormField]'), function(field) {
+            if (!dirtyOnly || field.isDirty()) {
+                PVE.Utils.assemble_field_data(values, field.getSubmitData());
+	    }
+	});
+
+	return me.onGetValues(values);
+    },
+
+    setValues: function(values) {
+	var me = this;
+
+	var form = me.up('form');
+
+        Ext.iterate(values, function(fieldId, val) {
+	    var field = me.query('[isFormField][name=' + fieldId + ']')[0];
+            if (field) {
+               field.setValue(val);
+                if (form.trackResetOnLoad) {
+                    field.resetOriginalValue();
+                }
+            }
+	});
+    },
+
+    initComponent: function() {
+	var me = this;
+
+	var items;
+	
+	if (me.items) {
+	    me.columns = 1;
+	    items = [
+		{
+		    columnWidth: 1,
+		    layout: 'anchor',
+		    items: me.items
+		}
+	    ];
+	    me.items = undefined;
+	} else if (me.column1) {
+	    me.columns = 2;
+	    items = [
+		{
+		    columnWidth: 0.5,
+		    padding: '0 10 0 0',
+		    layout: 'anchor',
+		    items: me.column1
+		},
+		{
+		    columnWidth: 0.5,
+		    padding: '0 0 0 10',
+		    layout: 'anchor',
+		    items: me.column2 || [] // allow empty column
+		}
+	    ];
+	} else {
+	    throw "unsupported config";
+	}
+
+	if (me.useFieldContainer) {
+	    Ext.apply(me, {
+		layout: 'fit',
+		items: Ext.apply(me.useFieldContainer, { 
+		    layout: 'column',
+		    defaultType: 'container',
+		    items: items
+		})
+	    });
+	} else {
+	    Ext.apply(me, {
+		layout: 'column',
+		defaultType: 'container',
+		items: items
+	    });
+	}
+	
+	me.callParent();
+    }
+});

Added: pve-manager/pve2/www/manager/qemu/CDEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/CDEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/CDEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,192 @@
+// fixme: howto avoid jslint type confusion?
+/*jslint confusion: true */
+Ext.define('PVE.qemu.CDInputPanel', {
+    extend: 'PVE.panel.InputPanel',
+    alias: 'widget.PVE.qemu.CDInputPanel',
+
+    insideWizard: false,
+
+    onGetValues: function(values) {
+	var me = this;
+
+	var confid = me.confid || (values.controller + values.deviceid);
+	
+	me.drive.media = 'cdrom';
+	if (values.mediaType === 'iso') {
+	    me.drive.file = values.cdimage;
+	} else if (values.mediaType === 'cdrom') {
+	    me.drive.file = 'cdrom';
+	} else {
+	    me.drive.file = 'none';
+	}
+
+	var params = {};
+		
+	params[confid] = PVE.Parser.printQemuDrive(me.drive);
+	
+	return params;	
+    },
+
+    setVMConfig: function(vmconfig) {
+	var me = this;
+
+	if (me.bussel) {
+	    me.bussel.setVMConfig(vmconfig, 'cdrom');
+	}
+    },
+
+    setDrive: function(drive) {
+	var me = this;
+
+	var values = {};
+	if (drive.file === 'cdrom') {
+	    values.mediaType = 'cdrom';
+	} else if (drive.file === 'none') {
+	    values.mediaType = 'none';
+	} else {
+	    values.mediaType = 'iso';
+	    var match = drive.file.match(/^([^:]+):/);
+	    if (match) {
+		values.cdstorage = match[1];
+		values.cdimage = drive.file;
+	    }
+	}
+
+	me.drive = drive;
+
+	me.setValues(values);
+    },
+
+    setNodename: function(nodename) {
+	var me = this;
+
+	me.cdstoragesel.setNodename(nodename);
+	me.cdfilesel.setStorage(undefined, nodename);
+    },
+
+    initComponent : function() {
+	var me = this;
+
+	me.drive = {};
+
+	var items = [];
+
+	if (!me.confid) {
+	    me.bussel = Ext.createWidget('PVE.form.ControllerSelector', {
+		noVirtIO: true
+	    });
+	    items.push(me.bussel);
+	}
+
+	items.push({
+	    xtype: 'radiofield',
+	    name: 'mediaType',
+	    inputValue: 'iso',
+	    boxLabel: 'Use CD/DVD disc image file (iso)',
+	    checked: true,
+	    listeners: {
+		change: function(f, value) {
+		    if (!me.rendered) {
+			return;
+		    }
+		    me.down('field[name=cdstorage]').setDisabled(!value);
+		    me.down('field[name=cdimage]').setDisabled(!value);
+		    me.down('field[name=cdimage]').validate();
+		}
+	    }
+	});
+
+	me.cdfilesel = Ext.create('PVE.form.FileSelector', {
+	    name: 'cdimage',
+	    nodename: me.nodename,
+	    storageContent: 'iso',
+	    fieldLabel: 'ISO Image',
+	    labelAlign: 'right',
+	    allowBlank: false
+	});
+	
+	me.cdstoragesel = Ext.create('PVE.form.StorageSelector', {
+	    name: 'cdstorage',
+	    nodename: me.nodename,
+	    fieldLabel: 'Storage',
+	    labelAlign: 'right',
+	    storageContent: 'iso',
+	    allowBlank: false,
+	    autoSelect: me.insideWizard,
+	    listeners: {
+		change: function(f, value) {
+		    me.cdfilesel.setStorage(value);
+		}
+	    }
+	});
+
+	items.push(me.cdstoragesel);
+	items.push(me.cdfilesel);
+
+	items.push({
+	    xtype: 'radiofield',
+	    name: 'mediaType',
+	    inputValue: 'cdrom',
+	    boxLabel: 'Use physical CD/DVD Drive'
+	});
+
+	items.push({
+	    xtype: 'radiofield',
+	    name: 'mediaType',
+	    inputValue: 'none',
+	    boxLabel: 'Do not use any media'
+	});
+
+	if (me.insideWizard) {
+	    me.column1 = items;
+	} else {
+	    me.items = items;
+	}
+
+	me.callParent();
+    }
+});
+
+Ext.define('PVE.qemu.CDEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	var me = this;
+
+	var nodename = me.pveSelNode.data.node;
+	if (!nodename) { 
+	    throw "no node name specified";	    
+	}
+
+	me.create = me.confid ? false : true;
+
+	var ipanel = Ext.create('PVE.qemu.CDInputPanel', {
+	    confid: me.confid,
+	    nodename: nodename
+	});
+
+	Ext.applyIf(me, {
+	    title: me.create ? 'Add CD/DVD Drive' : 
+		'Change CD/DVD settings (' + me.confid + ')',
+	    items: [ ipanel ]
+	});
+
+	me.callParent();
+	
+	me.load({
+	    success: function(form, action) {
+		ipanel.setVMConfig(action.result.data);
+		if (me.confid) {
+		    var value = action.result.data[me.confid];
+		    var drive = PVE.Parser.parseQemuDrive(me.confid, value);
+		    if (!drive) {
+			Ext.Msg.alert('Error', 'Unable to parse drive options');
+			me.close();
+			return;
+		    }
+		    ipanel.setDrive(drive);
+		}
+	    }
+	});
+    }
+});

Modified: pve-manager/pve2/www/manager/qemu/CreateWizard.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/CreateWizard.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/qemu/CreateWizard.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -20,25 +20,17 @@
 	    ]
 	});
 
-	var cdfilesel = Ext.create('PVE.form.FileSelector', {
-	    name: 'cdimage',
-	    storageContent: 'iso',
-	    fieldLabel: 'ISO Image',
-	    labelAlign: 'right',
-	    allowBlank: false
+	var cdpanel = Ext.create('PVE.qemu.CDInputPanel', {
+	    title: 'Installation Media',
+	    confid: 'ide2',
+	    insideWizard: true
 	});
 
-	var cdstoragesel = Ext.create('PVE.form.StorageSelector', {
-	    name: 'cdstorage',
-	    fieldLabel: 'Storage',
-	    storageContent: 'iso',
-	    labelAlign: 'right',
-	    allowBlank: false,
-	    listeners: {
-		change: function(f, value) {
-		    cdfilesel.setStorage(value);
-		}
-	    }
+	var hdpanel = Ext.create('PVE.qemu.HDInputPanel', {
+	    title: 'Harddisk',
+	    confid: 'ide0',
+	    create: true,
+	    insideWizard: true
 	});
 
 	var hdstoragesel = Ext.create('PVE.form.StorageSelector', {
@@ -49,12 +41,9 @@
 	    allowBlank: false
 	});
 
-	var bridgesel = Ext.create('PVE.form.BridgeSelector', {
-	    name: 'bridge',
-	    value: 'vmbr0',
-	    fieldLabel: 'Bridge',
-	    labelAlign: 'right',
-	    allowBlank: false
+	var networkpanel =  Ext.create('PVE.qemu.NetworkInputPanel', {
+	    title: 'Network',
+	    insideWizard: true
 	});
 
 	Ext.applyIf(me, {
@@ -63,7 +52,7 @@
 		{
 		    xtype: 'inputpanel',
 		    title: 'General',
-		    items: [
+		    column1: [
 			{
 			    xtype: 'PVE.form.NodeSelector',
 			    name: 'nodename',
@@ -71,10 +60,9 @@
 			    allowBlank: false,
 			    listeners: {
 				change: function(f, value) {
-				    bridgesel.setNodename(value);
-				    hdstoragesel.setNodename(value);
-				    cdstoragesel.setNodename(value);
-				    cdfilesel.setStorage(undefined, value);
+				    networkpanel.setNodename(value);
+				    hdpanel.setNodename(value);
+				    cdpanel.setNodename(value);
 				}
 			    }
 			},
@@ -111,315 +99,21 @@
 		},
 		{
 		    title: 'OS Type',
-		    xtype: 'radiogroup',
-		    allowBlank: false,
-		    layout: 'column',
-		    defaultType: 'container',
-		    items: [{
-			columnWidth: 0.5,
-			items: [
-			    {
-				xtype: 'component', 
-				html: 'Microsoft Windows', 
-				cls:'x-form-check-group-label'
-			    },
-			    {
-				xtype: 'radiofield',
-				name: 'ostype',
-				inputValue: 'win7',
-				boxLabel: 'Microsoft Windows 7/2008r2'
-			    },
-			    {
-				xtype: 'radiofield',
-				name: 'ostype',
-				inputValue: 'w2k8',
-				boxLabel: 'Microsoft Windows Vista/2008'
-			    },
-			    {
-				xtype: 'radiofield',
-				name: 'ostype',
-				inputValue: 'wxp',
-				boxLabel: 'Microsoft Windows XP/2003'
-			    },
-			    {
-				xtype: 'radiofield',
-				name: 'ostype',
-				inputValue: 'w2k',
-				boxLabel: 'Microsoft Windows 2000'
-			    }
-			]
-		    },{
-			columnWidth: 0.5,
-			items: [
-			    {
-				xtype: 'component', 
-				html: 'Linux/Other', 
-				cls:'x-form-check-group-label'
-			    },
-			    {
-				xtype: 'radiofield',
-				name: 'ostype',
-				inputValue: 'l26',
-				boxLabel: 'Linux 2.6 Kernel'
-			    },
-			    {
-				xtype: 'radiofield',
-				name: 'ostype',
-				inputValue: 'l24',
-				boxLabel: 'Linux 2.4 Kernel'
-			    },
-			    {
-				xtype: 'radiofield',
-				name: 'ostype',
-				inputValue: 'other',
-				boxLabel: 'Other'
-			    }
-			]
-		    }]
+		    xtype: 'PVE.qemu.OSTypeInputPanel'
 		},
+		cdpanel,
+		hdpanel,
 		{
-		    xtype: 'inputpanel',
-		    title: 'Installation Media',
-		    items: [
-			{
-			    xtype: 'radiofield',
-			    name: 'mediaType',
-			    inputValue: 'iso',
-			    boxLabel: 'Use CD/DVD disc image file (iso)',
-			    checked: true,
-			    listeners: {
-				change: function(f, value) {
-				    me.down('field[name=cdstorage]').setDisabled(!value);
-				    me.down('field[name=cdimage]').setDisabled(!value);
-				    me.down('field[name=cdimage]').validate();
-				}
-			    }
-			},
-			cdstoragesel, 
-			cdfilesel,
-			{
-			    xtype: 'radiofield',
-			    name: 'mediaType',
-			    inputValue: 'cdrom',
-			    boxLabel: 'Use physical CD/DVD Drive'
-			},
-			{
-			    xtype: 'radiofield',
-			    name: 'mediaType',
-			    inputValue: 'none',
-			    boxLabel: 'Do not use any installation media'
-			}
-		    ],
-		    onGetValues: function(values) {
-			if (values.mediaType === 'iso') {
-			    return { cdrom: values.cdimage };
-			} else if (values.mediaType === 'cdrom') {
-			    return { cdrom: 'cdrom' };
-			}
-			return { cdrom: 'none' };
-		    }
+		    xtype: 'PVE.qemu.ProcessorInputPanel',
+		    title: 'CPU'
 		},
 		{
-		    xtype: 'inputpanel',
-		    title: 'Harddisk',
-		    items: [
-			{
-			    xtype: 'radiofield',
-			    name: 'hdType',
-			    inputValue: 'image',
-			    boxLabel: 'Create new disk image',
-			    checked: true,
-			    listeners: {
-				change: function(f, value) {
-				    me.down('field[name=hdstorage]').setDisabled(!value);
-				    me.down('field[name=disksize]').setDisabled(!value);
-				    me.down('field[name=controller]').setDisabled(!value);
-				    me.down('field[name=diskformat]').setDisabled(!value);
-				}
-			    }
-			},
-			{
-			    xtype: 'PVE.form.BusTypeSelector',
-			    name: 'controller',
-			    labelAlign: 'right',
-			    fieldLabel: 'Controller',
-			    value: 'ide',
-			    allowBlank: false
-			},
-			hdstoragesel,
-			{
-			    xtype: 'numberfield',
-			    name: 'disksize',
-			    labelAlign: 'right',
-			    minValue: 1,
-			    maxValue: 128*1024,
-			    value: '32',
-			    fieldLabel: 'Disk size (GB)',
-			    allowBlank: false
-			},
-			{
-			    xtype: 'PVE.form.DiskFormatSelector',
-			    name: 'diskformat',
-			    labelAlign: 'right',
-			    fieldLabel: 'Image format',
-			    value: 'raw',
-			    allowBlank: false
-			},
-			{
-			    xtype: 'radiofield',
-			    name: 'hdType',
-			    inputValue: 'none',
-			    boxLabel: 'Do not attach a hard disk'
-			}
-		    ],
-		    onGetValues: function(values) {
-			if (values.hdType === 'none') {
-			    return {};
-			}
-
-			var str = values.hdstorage + ':' + values.disksize +
-			    ',format=' + values.diskformat;
-			var key = values.controller + "0";
-			var res = {};
-			res[key] = str;
-			return res;
-		    }
-		},	
-		{
-		    xtype: 'inputpanel',
-		    title: 'CPU',
-		    column1: [
-			{
-			    xtype: 'numberfield',
-			    name: 'sockets',
-			    minValue: 1,
-			    maxValue: 4,
-			    value: '1',
-			    fieldLabel: 'Sockets',
-			    allowBlank: false,
-			    listeners: {
-				change: function(f, value) {
-				    var sockets = me.down('field[name=sockets]').getValue();
-				    var cores = me.down('field[name=cores]').getValue();
-				    me.down('field[name=totalcores]').setValue(sockets*cores);
-				}
-			    }
-			},
-			{
-			    xtype: 'numberfield',
-			    name: 'cores',
-			    minValue: 1,
-			    maxValue: 32,
-			    value: '1',
-			    fieldLabel: 'Cores',
-			    allowBlank: false,
-			    listeners: {
-				change: function(f, value) {
-				    var sockets = me.down('field[name=sockets]').getValue();
-				    var cores = me.down('field[name=cores]').getValue();
-				    me.down('field[name=totalcores]').setValue(sockets*cores);
-				}
-			    }
-			}
-		    ],
-		    column2: [
-			{
-			    xtype: 'displayfield',
-			    fieldLabel: 'Total cores',
-			    name: 'totalcores',
-			    value: '1'
-			}
-		    ]
+		    xtype: 'PVE.qemu.MemoryInputPanel',
+		    insideWizard: true,
+		    title: 'Memory'
 		},
+		networkpanel,
 		{
-		    xtype: 'inputpanel',
-		    title: 'Memory',
-		    items: [
-			{
-			    xtype: 'numberfield',
-			    name: 'memory',
-			    minValue: 32,
-			    maxValue: 128*1024,
-			    value: '512',
-			    step: 32,
-			    fieldLabel: 'Memory (MB)',
-			    allowBlank: false
-			}
-		    ]
-		},
-		{
-		    xtype: 'inputpanel',
-		    title: 'Network',
-		    column1: [
-			{
-			    xtype: 'radiofield',
-			    name: 'networkmode',
-			    height: 22, // hack: set same height as text fields
-			    inputValue: 'bridge',
-			    boxLabel: 'Bridged mode',
-			    checked: true,
-			    listeners: {
-				change: function(f, value) {
-				    if (!me.rendered) {
-					return;
-				    }
-				    me.down('field[name=bridge]').setDisabled(!value);
-				    me.down('field[name=bridge]').validate();
-				}
-			    }
-			},
-			bridgesel,
-			{
-			    xtype: 'radiofield',
-			    name: 'networkmode',
-			    height: 22, // hack: set same height as text fields
-			    inputValue: 'nat',
-			    boxLabel: 'NAT mode'
-			},
-			{
-			    xtype: 'radiofield',
-			    name: 'networkmode',
-			    height: 22, // hack: set same height as text fields
-			    inputValue: 'none',
-			    boxLabel: 'No network device'
-			}
-		    ],
-		    column2: [
-			{
-			    xtype: 'PVE.form.NetworkCardSelector',
-			    name: 'netcard',
-			    fieldLabel: 'Network card',
-			    value: 'rtl8139',
-			    allowBlank: false
-			},
-			{
-			    xtype: 'textfield',
-			    name: 'mac',
-			    fieldLabel: 'MAC address',
-			    vtype: 'MacAddress',
-			    allowBlank: true,
-			    emptyText: 'auto'
-			}
-		    ],
-
-		    onGetValues: function(values) {
-			if (values.networkmode === 'none') {
-			    return {};
-			}
-
-			var str = values.netcard;
-			if (values.mac) {
-			    str += '=' + values.mac;
-			}
-
-			if (values.networkmode === 'bridge') {
-			    str += ',bridge=' + values.bridge;
-			}
-
-			return { net0: str };
-		    }
-		},
-		{
 		    title: 'Confirm',
 		    layout: 'fit',
 		    items: [
@@ -437,19 +131,26 @@
 			show: function(panel) {
 			    var form = me.down('form').getForm();
 			    var kv = me.getValues();
-			    console.dir(kv);
 			    var data = [];
 			    Ext.Object.each(kv, function(key, value) {
+				if (key === 'delete') { // ignore
+				    return;
+				}
 				var html = Ext.htmlEncode(Ext.JSON.encode(value));
 				data.push({ key: key, value: value });
 			    });
+			    summarystore.suspendEvents();
 			    summarystore.removeAll();
 			    summarystore.add(data);
 			    summarystore.sort();
+			    summarystore.resumeEvents();
+			    summarystore.fireEvent('datachanged', summarystore);
+
 			}
 		    },
 		    onSubmit: function() {
 			var kv = me.getValues();
+			delete kv['delete'];
 
 			var nodename = kv.nodename;
 			delete kv.nodename;

Added: pve-manager/pve2/www/manager/qemu/DisplayEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/DisplayEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/DisplayEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,22 @@
+Ext.define('PVE.qemu.DisplayEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	var me = this;
+
+	Ext.applyIf(me, {
+	    title: "Edit display settings",
+	    width: 350,
+	    items: {
+		xtype: 'DisplaySelector',
+		name: 'vga',
+		value: '',
+		fieldLabel: 'Graphic card'
+	    }
+	});
+
+	me.callParent();
+
+	me.load();
+    }
+});

Added: pve-manager/pve2/www/manager/qemu/HDEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/HDEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/HDEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,221 @@
+Ext.define('PVE.qemu.HDInputPanel', {
+    extend: 'PVE.panel.InputPanel',
+    alias: 'widget.PVE.qemu.HDInputPanel',
+
+    insideWizard: false,
+
+    unused: false, // ADD usused disk imaged
+
+    vmconfig: {}, // used to select usused disks
+
+    onGetValues: function(values) {
+	var me = this;
+
+	var confid = me.confid || (values.controller + values.deviceid);
+	
+	if (me.unused) {
+	    me.drive.file = me.vmconfig[values.unusedId];
+	    confid = values.controller + values.deviceid;
+	} else if (me.create) {
+	    me.drive.file = values.hdstorage + ":" + values.disksize;
+	    me.drive.format = values.diskformat;
+	}
+	
+	if (values.cache) {
+	    me.drive.cache = values.cache;
+	} else {
+	    delete me.drive.cache;
+	}
+
+	if (values.nobackup) {
+	    me.drive.backup = 'no';
+	} else {
+	    delete me.drive.backup;
+	}
+
+	var params = {};
+		
+	params[confid] = PVE.Parser.printQemuDrive(me.drive);
+	
+	return params;	
+    },
+
+    setVMConfig: function(vmconfig) {
+	var me = this;
+
+	me.vmconfig = vmconfig;
+
+	if (me.bussel) {
+	    me.bussel.setVMConfig(vmconfig, true);
+	}
+	if (me.unusedDisks) {
+	    var disklist = [];	    
+	    Ext.Object.each(vmconfig, function(key, value) {
+		if (key.match(/^unused\d+$/)) {
+		    disklist.push([key, value]);
+		}
+	    });
+	    me.unusedDisks.store.loadData(disklist);
+	    me.unusedDisks.setValue(me.confid);
+	}
+    },
+
+    setDrive: function(drive) {
+	var me = this;
+
+	me.drive = drive;
+
+	var values = {};
+	var match = drive.file.match(/^([^:]+):/);
+	if (match) {
+	    values.hdstorage = match[1];
+	}
+
+	values.hdimage = drive.file;
+	values.nobackup = (drive.backup === 'no');
+	values.diskformat = drive.format || 'raw';
+	values.cache = drive.cache || '';
+
+	me.setValues(values);
+    },
+
+    setNodename: function(nodename) {
+	var me = this;
+	me.hdstoragesel.setNodename(nodename);
+    },
+
+    initComponent : function() {
+	var me = this;
+
+	me.drive = {};
+
+	me.column1 = [];
+	me.column2 = [];
+
+	if (!me.confid || me.unused) {
+	    me.bussel = Ext.createWidget('PVE.form.ControllerSelector', {});
+	    me.column1.push(me.bussel);
+	}
+
+	if (me.unused) {
+	    me.unusedDisks = Ext.create('PVE.form.KVComboBox', {
+		name: 'unusedId',	
+		fieldLabel: 'Disk image',
+		matchFieldWidth: false,
+		listConfig: {
+		    width: 350
+		},
+		data: [],
+		allowBlank: false
+	    });
+	    me.column1.push(me.unusedDisks);
+	} else if (me.create) {
+	    me.hdstoragesel = Ext.create('PVE.form.StorageSelector', {
+		name: 'hdstorage',
+		nodename: me.nodename,
+		fieldLabel: 'Storage',
+		storageContent: 'images',
+		autoSelect: me.insideWizard,
+		allowBlank: false
+	    });
+	    me.column1.push(me.hdstoragesel);
+
+	    me.column1.push({
+		xtype: 'numberfield',
+		name: 'disksize',
+		minValue: 1,
+		maxValue: 128*1024,
+		value: '32',
+		fieldLabel: 'Disk size (GB)',
+		allowBlank: false
+	    });
+	} else {
+	    me.column1.push({
+		xtype: 'displayfield',
+                fieldLabel: 'Image',
+		labelWidth: 50,
+                name: 'hdimage'
+	    });
+	}
+
+	if (!me.unused) {
+	    me.column2.push({
+		xtype: 'PVE.form.DiskFormatSelector',
+		name: 'diskformat',
+		fieldLabel: 'Image format',
+		value: 'raw',
+		allowBlank: false
+	    });
+	}
+
+	me.column2.push({
+	    xtype: 'CacheTypeSelector',
+	    name: 'cache',
+	    value: '',
+	    fieldLabel: 'Cache'
+	});
+
+	if (!me.insideWizard) {
+	    me.column2.push({
+		xtype: 'pvecheckbox',
+		fieldLabel: 'No backup',
+		name: 'nobackup'
+	    });
+	}
+
+	me.callParent();
+    }
+});
+
+Ext.define('PVE.qemu.HDEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	var me = this;
+
+	var nodename = me.pveSelNode.data.node;
+	if (!nodename) { 
+	    throw "no node name specified";	    
+	}
+
+	var unused = me.confid && me.confid.match(/^unused\d+$/);
+
+	me.create = me.confid ? unused : true;
+
+	var ipanel = Ext.create('PVE.qemu.HDInputPanel', {
+	    confid: me.confid,
+	    nodename: nodename,
+	    unused: unused,
+	    create: me.create
+	});
+
+	var title;
+	if (unused) {
+	    me.title = 'Add (previously unused) Harddisk';
+	} else if (me.create) {
+            me.title = 'Add Harddisk';
+	} else {
+	    me.title = 'Edit Harddisk settings (' + me.confid + ')';
+	}
+
+	me.items = [ ipanel ];
+
+	me.callParent();
+	
+	me.load({
+	    success: function(form, action) {
+		ipanel.setVMConfig(action.result.data);
+		if (me.confid) {
+		    var value = action.result.data[me.confid];
+		    var drive = PVE.Parser.parseQemuDrive(me.confid, value);
+		    if (!drive) {
+			Ext.Msg.alert('Error', 'Unable to parse drive options');
+			me.close();
+			return;
+		    }
+		    ipanel.setDrive(drive);
+		}
+	    }
+	});
+    }
+});

Modified: pve-manager/pve2/www/manager/qemu/HardwareView.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/HardwareView.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/qemu/HardwareView.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -1,772 +1,5 @@
 // fixme: howto avoid jslint type confusion?
 /*jslint confusion: true */
-Ext.define('PVE.qemu.CDEdit', {
-    extend: 'PVE.window.Edit',
-
-    getParams: function(values) {
-	var me = this;
-
-	var params = {};
-
-	if (values.mediaType  === 'iso') {
-	    me.drive.file = values.cdimage;
-	} else if (values.mediaType === 'cdrom') {
-	    me.drive.file = 'cdrom';
-	} else {
-	    me.drive.file = 'none';
-	}
-
-	params[me.confid] = PVE.Parser.printQemuDrive(me.drive);
-
-	return params;
-    },
-
-    initComponent : function() {
-	var me = this;
-
-	var nodename = me.pveSelNode.data.node;
-	if (!nodename) {
-	    throw "no node name specified";
-	}
-
-	if (!me.confid) {
-	    throw "create not implemented";
-	}
-
-	var cdfilesel = Ext.create('PVE.form.FileSelector', {
-	    name: 'cdimage',
-	    nodename: nodename,
-	    storageContent: 'iso',
-	    fieldLabel: 'ISO Image',
-	    labelAlign: 'right',
-	    allowBlank: false
-	});
-
-	var cdstoragesel = Ext.create('PVE.form.StorageSelector', {
-	    name: 'storage',
-	    nodename: nodename,
-	    fieldLabel: 'Storage',
-	    labelAlign: 'right',
-	    storageContent: 'iso',
-	    allowBlank: false,
-	    autoSelect: false,
-	    listeners: {
-		change: function(f, value) {
-		    if (!value) {
-			return;
-		    }
-		    cdfilesel.setStorage(value);
-		}
-	    }
-	});
-
-	me.items = [ 
-	    {
-		xtype: 'radiofield',
-		name: 'mediaType',
-		inputValue: 'iso',
-		boxLabel: 'Use CD/DVD disc image file (iso)',
-		checked: true,
-		listeners: {
-		    change: function(f, value) {
-			if (!me.rendered) {
-			    return;
-			}
-			me.down('field[name=storage]').setDisabled(!value);
-			me.down('field[name=cdimage]').setDisabled(!value);
-			me.down('field[name=cdimage]').validate();
-		    }
-		}
-	    },
-	    cdstoragesel, 
-	    cdfilesel,
-	    {
-		xtype: 'radiofield',
-		name: 'mediaType',
-		inputValue: 'cdrom',
-		boxLabel: 'Use physical CD/DVD Drive'
-	    },
-	    {
-		xtype: 'radiofield',
-		name: 'mediaType',
-		inputValue: 'none',
-		boxLabel: 'Eject (no media).'
-	    }
-	];
-
-	Ext.applyIf(me, {
-	    title: "Change CD/DVD settings (" + me.confid + ")"
-	});
-
-	me.callParent();
-
-	me.load({
-	    success: function(form, action) {
-		var value = action.result.data[me.confid];
-		me.drive = PVE.Parser.parseQemuDrive(me.confid, value);
-		if (!me.drive) {
-		    Ext.Msg.alert('Error', 'Unable to parse drive options');
-		    me.close();
-		    return;
-		}
-
-		var values = {};
-		if (me.drive.file === 'cdrom') {
-		    values.mediaType = 'cdrom';
-		} else if (me.drive.file === 'none') {
-		    values.mediaType = 'none';
-	        } else {
-		    values.mediaType = 'iso';
-		    var match = me.drive.file.match(/^([^:]+):/);
-		    if (match) {
-			values.storage = match[1];
-			values.cdimage = me.drive.file;
-		    }
-		}
-
-		form.setValues(values);
-	    }
-	});
-    }
-});
-
-Ext.define('PVE.qemu.NetworkEdit', {
-    extend: 'PVE.window.Edit',
-
-    getParams: function(values) {
-	var me = this;
-
-	me.network.model = values.model;
-	if (values.mode === 'bridge') {
-	    me.network.bridge = values.bridge;
-	} else {
-	    me.network.bridge = undefined;
-	}
-	me.network.macaddr = values.macaddr;
-
-	var params = {};
-
-	params[me.confid] = PVE.Parser.printQemuNetwork(me.network);
-
-	return params;
-    },
-
-    initComponent : function() {
-	var me = this;
-
-	var nodename = me.pveSelNode.data.node;
-	if (!nodename) { 
-	    throw "no node name specified";	    
-	}
-
-	me.create = me.confid ? false : true;
-
-	Ext.applyIf(me, {
-	    title: me.create ? "Add network device" : 
-		"Edit network device settings"
-	});
-
-	me.column1 = [
-	    {
-		xtype: 'radiofield',
-		name: 'mode',
-		height: 22, // hack: set same height as text fields
-		inputValue: 'bridge',
-		boxLabel: 'Bridged mode',
-		checked: true,
-		listeners: {
-		    change: function(f, value) {
-			if (!me.rendered) {
-			    return;
-			}
-			me.down('field[name=bridge]').setDisabled(!value);
-			me.down('field[name=bridge]').validate();
-		    }
-		}
-	    },
-	    {
-		xtype: 'PVE.form.BridgeSelector',
-		name: 'bridge',
-		fieldLabel: 'Bridge',
-		nodename: nodename,
-		autoSelect: true,
-		labelAlign: 'right',
-		allowBlank: false
-	    },
-	    {
-		xtype: 'radiofield',
-		name: 'mode',
-		height: 22, // hack: set same height as text fields
-		inputValue: 'nat',
-		boxLabel: 'NAT mode'
-	    }
-	];
-
-	me.column2 = [
-	    {
-		xtype: 'PVE.form.NetworkCardSelector',
-		name: 'model',
-		fieldLabel: 'Network card',
-		value: 'rtl8139',
-		allowBlank: false
-	    },
-	    {
-		xtype: 'textfield',
-		name: 'macaddr',
-		fieldLabel: 'MAC address',
-		vtype: 'MacAddress',
-		allowBlank: true,
-		emptyText: 'auto'
-	    }
-	];
-
-	me.callParent();
-
-	me.load({
-	    success: function(form, action) {
-		var i, confid;
-		me.vmconfig = action.result.data;
-		if (!me.create) {
-		    var value = me.vmconfig[me.confid];
-		    me.network = PVE.Parser.parseQemuNetwork(me.confid, value);
-		    if (!me.network) {
-			Ext.Msg.alert('Error', 'Unable to parse network options');
-			me.close();
-			return;
-		    }
-		    var values = me.network;
-		    values.mode = values.bridge ? 'bridge' : 'nat';
-		    form.setValues(values);
-		    // hack: fix ExtJS bug
-		    Ext.Array.each(me.query('radiofield'), function(f) {
-			f.resetOriginalValue();
-		    });
-		} else {
-		    me.network = {};
-		    for (i = 0; i < 100; i++) {
-			confid = 'net' + i;
-			if (!Ext.isDefined(me.vmconfig[confid])) {
-			    me.confid = confid;
-			    break;
-			}
-		    }
-		}
-	    }
-	});
-    }
-});
-
-Ext.define('PVE.qemu.HDEdit', {
-    extend: 'PVE.window.Edit',
-
-    getParams: function(values) {
-	var me = this;
-
-	me.drive.cache = values.cache || undefined;	
-	me.drive.backup = values.nobackup ? 'no' : undefined;
-
-	var params = {};
-
-	params[me.confid] = PVE.Parser.printQemuDrive(me.drive);
-
-	return params;
-    },
-
-    initComponent : function() {
-	var me = this;
-
-	var nodename = me.pveSelNode.data.node;
-	if (!nodename) { 
-	    throw "no node name specified";
-	}
-
-	if (!me.confid) {
-	    throw "create not implemented";
-	}
-
-	me.column1 = [
-	    {
-		xtype: 'displayfield',
-                fieldLabel: 'Image',
-                name: 'file'
-	    }
-	];
-
-	me.column2 = [
-	    {
-		xtype: 'CacheTypeSelector',
-		name: 'cache',
-		value: '',
-		fieldLabel: 'Cache'
-	    },
-	    {
-		xtype: 'pvecheckbox',
-                fieldLabel: 'No backup',
-                name: 'nobackup'
-	    }
-	];
-
-	Ext.applyIf(me, {
-	    title: "Edit Harddisk settings (" + me.confid + ")",
-	    fieldDefaults: {
-		labelWidth: 70
-	    }
-	});
-
-	me.callParent();
-
-	me.load({
-	    success: function(form, action) {
-		var value = action.result.data[me.confid];
-		me.drive = PVE.Parser.parseQemuDrive(me.confid, value);
-		if (!me.drive) {
-		    Ext.Msg.alert('Error', 'Unable to parse drive options');
-		    me.close();
-		    return;
-		}
-
-		var values = {};
-
-		values.file = me.drive.file;
-		values.cache = me.drive.cache || '';
-		values.nobackup = (me.drive.backup === 'no');
-
-		form.setValues(values);
-	    }
-	});
-    }
-});
-
-Ext.define('PVE.qemu.HDCreate', {
-    extend: 'PVE.window.Edit',
-
-    create: true,
-
-    cdrom: false,
-
-    unused: false,
-
-    getParams: function(values) {
-	var me = this;
-
-	var drive = {};
-
-	var confid = values.controller + values.deviceid;
-	
-	if (me.cdrom) {
-	    drive.media = 'cdrom';
-	    if (values.mediaType  === 'iso') {
-		drive.file = values.cdimage;
-	    } else if (values.mediaType === 'cdrom') {
-		drive.file = 'cdrom';
-	    } else {
-		drive.file = 'none';
-	    }
-	} else {
-	    if (me.unused) {
-		drive.file = me.vmconfig[values.unusedId];
-	    } else {
-		drive.file = values.storage + ":" + values.disksize;
-		drive.format = values.diskformat;
-	    }
-
-	    if (values.cache) {
-		drive.cache = values.cache;
-	    }
-
-	    if (values.nobackup) {
-		drive.backup = 'no';
-	    }
-	}
-
-	var params = {};
-
-	params[confid] = PVE.Parser.printQemuDrive(drive);
-
-	return params;	
-    },
-
-    initComponent : function() {
-	var me = this;
-
-	var nodename = me.pveSelNode.data.node;
-	if (!nodename) { 
-	    throw "no node name specified";	    
-	}
-
-	if (!me.cdrom && me.confid && me.confid.match(/^unused\d+$/)) {
-	    me.unused = true;
-	}
-
-	var maxIds = {
-	    ide: 3,
-	    virtio: 15,
-	    scsi: 15
-	};
-
-	var unused_disks;
-
-	var bussel = Ext.createWidget('fieldcontainer', {
-	    fieldLabel: 'Bus/Device',
-	    layout: 'hbox',
-	    height: 22, // hack: set to same height as other fields
-	    defaults: {
-                flex: 1,
-                hideLabel: true
-	    },
-	    items: [
-		{
-		    xtype: 'PVE.form.BusTypeSelector',
-		    name: 'controller',
-		    value: 'ide',
-		    noVirtIO: me.cdrom,
-		    allowBlank: false,
-		    listeners: {
-			change: function(t, value) {
-			    if (!me.rendered || !value) {
-				return;
-			    }
-			    var field = me.down('field[name=deviceid]');
-			    field.setMaxValue(maxIds[value]);
-			    field.validate();
-			}
-		    }
-		},
-		{
-		    xtype: 'numberfield',
-		    name: 'deviceid',
-		    minValue: 0,
-		    maxValue: maxIds.ide,
-		    value: 0,
-		    validator: function(value) {
-			if (!me.rendered) {
-			    return;
-			}
-			var field = me.down('field[name=controller]');
-			var controller = field.getValue();
-			var confid = controller + value;
-			if (Ext.isDefined(me.vmconfig[confid])) {
-			    return "This device is already in use.";
-			}
-			return true;
-		    }
-		}
-	    ]
-	});
-
-	if (me.cdrom) {
-
-	    var cdfilesel = Ext.create('PVE.form.FileSelector', {
-		name: 'cdimage',
-		nodename: nodename,
-		storageContent: 'iso',
-		fieldLabel: 'ISO Image',
-		labelAlign: 'right',
-		allowBlank: false
-	    });
-
-	    var cdstoragesel = Ext.create('PVE.form.StorageSelector', {
-		name: 'storage',
-		nodename: nodename,
-		fieldLabel: 'Storage',
-		labelAlign: 'right',
-		storageContent: 'iso',
-		allowBlank: false,
-		listeners: {
-		    change: function(f, value) {
-			cdfilesel.setStorage(value);
-		    }
-		}
-	    });
-
-	    me.items = [ 
-		bussel, 
-		{
-		    xtype: 'radiofield',
-		    name: 'mediaType',
-		    inputValue: 'iso',
-		    boxLabel: 'Use CD/DVD disc image file (iso)',
-		    checked: true,
-		    listeners: {
-			change: function(f, value) {
-			    if (!me.rendered) {
-				return;
-			    }
-			    me.down('field[name=storage]').setDisabled(!value);
-			    me.down('field[name=cdimage]').setDisabled(!value);
-			    me.down('field[name=cdimage]').validate();
-			}
-		    }
-		},
-		cdstoragesel, 
-		cdfilesel,
-		{
-		    xtype: 'radiofield',
-		    name: 'mediaType',
-		    inputValue: 'cdrom',
-		    boxLabel: 'Use physical CD/DVD Drive'
-		},
-		{
-		    xtype: 'radiofield',
-		    name: 'mediaType',
-		    inputValue: 'none',
-		    boxLabel: 'Do not use any media'
-		}
-	    ];
-
-	} else {
-	    if (me.unused) {
-
-		unused_disks = Ext.create('PVE.form.KVComboBox', {
-		    name: 'unusedId',	
-		    fieldLabel: 'Disk image',
-		    matchFieldWidth: false,
-		    listConfig: {
-			width: 350
-		    },
-		    data: [],
-		    allowBlank: false
-		});
-
-		me.column1 = [ bussel, unused_disks ];
-	    } else {
-		me.column1 = [
-		    bussel,
-		    {
-			xtype: 'PVE.form.StorageSelector',
-			name: 'storage',
-			nodename: nodename,
-			fieldLabel: 'Storage',
-			storageContent: 'images',
-			allowBlank: false
-		    },
-		    {
-			xtype: 'numberfield',
-			name: 'disksize',
-			minValue: 1,
-			maxValue: 128*1024,
-			value: 32,
-			fieldLabel: 'Disk size (GB)',
-			allowBlank: false
-		    }
-		];
-	    }
-
-	    me.column2 = [
-		{
-		    xtype: 'CacheTypeSelector',
-		    name: 'cache',
-		    value: '',
-		    fieldLabel: 'Cache'
-		},
-		{
-		    xtype: 'pvecheckbox',
-                    fieldLabel: 'No backup',
-                    name: 'nobackup'
-		}
-	    ];
-
-	    if (!me.unused) {
-		me.column2.unshift({
-		    xtype: 'PVE.form.DiskFormatSelector',
-		    name: 'diskformat',
-		    fieldLabel: 'Image format',
-		    value: 'raw',
-		    allowBlank: false
-		});
-	    }
-	}
-
-	if (me.cdrom) {
-	    me.title = 'Add CD/DVD Drive';
-	} else if (me.unused) {
-	    me.title = 'Add (previously unused) Harddisk';	    
-	} else {
-	    me.title = 'Add Harddisk';
-	}
-
-	me.callParent();
-
-	me.load({
-	    success: function(form, action) {
-		var confid;
-		me.vmconfig = action.result.data;
-
-		if (me.cdrom && !Ext.isDefined(me.vmconfig.ide2)) {
-
-		    me.down('field[name=controller]').setValue('ide');
-		    me.down('field[name=deviceid]').setValue(2);
-		    return;
-		}
-
-		if (unused_disks) {
-		    var disklist = [];
-		    
-		    Ext.Object.each(me.vmconfig, function(key, value) {
-			if (key.match(/^unused\d+$/)) {
-			    disklist.push([key, value]);
-			}
-		    });
-		    unused_disks.store.loadData(disklist);
-		    unused_disks.setValue(me.confid);
-		}
-		var controller = 'ide';
-		if (me.vmconfig.ostype === 'l26') {
-		    controller = 'virtio';
-		}
-		me.down('field[name=controller]').setValue(controller);
-
-		var i;
-		for (i = 0; i <= maxIds[controller]; i++) {
-		    confid = controller + i;
-		    if (!Ext.isDefined(me.vmconfig[confid])) {
-			me.down('field[name=deviceid]').setValue(i);
-			break;
-		    }
-		}
-	    }
-	});
-    }
-});
-
-Ext.define('PVE.qemu.MemoryEdit', {
-    extend: 'PVE.window.Edit',
-
-    initComponent : function() {
-	var me = this;
-
-	Ext.applyIf(me, {
-	    title: "Edit memory settings",
-	    items: {
-		xtype: 'numberfield',
-		name: 'memory',
-		minValue: 32,
-		maxValue: 128*1024,
-		value: 512,
-		step: 32,
-		fieldLabel: 'Memory (MB)',
-		allowBlank: false
-	    }
-	});
-
-	me.callParent();
-
-	me.load();
-    }
-});
-
-Ext.define('PVE.qemu.DisplayEdit', {
-    extend: 'PVE.window.Edit',
-
-    initComponent : function() {
-	var me = this;
-
-	Ext.applyIf(me, {
-	    title: "Edit display settings",
-	    width: 350,
-	    items: {
-		xtype: 'DisplaySelector',
-		name: 'vga',
-		value: '',
-		fieldLabel: 'Graphic card'
-	    }
-	});
-
-	me.callParent();
-
-	me.load();
-    }
-});
-
-Ext.define('PVE.qemu.KeyboardEdit', {
-    extend: 'PVE.window.Edit',
-
-    initComponent : function() {
-	var me = this;
-
-	Ext.applyIf(me, {
-	    title: "Edit keyboard settings",
-	    items: {
-		xtype: 'VNCKeyboardSelector',
-		name: 'keyboard',
-		value: '',
-		fieldLabel: 'Keyboard Layout'
-	    }
-	});
-
-	me.callParent();
-
-	me.load();
-    }
-});
-
-Ext.define('PVE.qemu.ProcessorEdit', {
-    extend: 'PVE.window.Edit',
-
-    initComponent : function() {
-	var me = this;
-
-	me.column1 = [
-	    {
-		xtype: 'numberfield',
-		name: 'sockets',
-		minValue: 1,
-		maxValue: 4,
-		value: 1,
-		fieldLabel: 'Sockets',
-		allowBlank: false,
-		listeners: {
-		    change: function(f, value) {
-			var sockets = me.down('field[name=sockets]').getValue();
-			var cores = me.down('field[name=cores]').getValue();
-			me.down('field[name=totalcores]').setValue(sockets*cores);
-		    }
-		}
-	    },
-	    {
-		xtype: 'numberfield',
-		name: 'cores',
-		minValue: 1,
-		maxValue: 32,
-		value: 1,
-		fieldLabel: 'Cores',
-		allowBlank: false,
-		listeners: {
-		    change: function(f, value) {
-			var sockets = me.down('field[name=sockets]').getValue();
-			var cores = me.down('field[name=cores]').getValue();
-			me.down('field[name=totalcores]').setValue(sockets*cores);
-		    }
-		}
-	    },
-	    {
-		xtype: 'displayfield',
-		fieldLabel: 'Total cores',
-		name: 'totalcores',
-		value: 1
-	    }
-	];
-
-
-	me.column2 = [
-	    {
-		xtype: 'CPUModelSelector',
-		name: 'cpu',
-		value: '',
-		fieldLabel: 'CPU type'
-	    }
-	];
-
-	Ext.applyIf(me, {
-	    title: "Edit processor settings"
-	});
-
-	me.callParent();
-
-	me.load();
-    }
-});
-
 Ext.define('PVE.qemu.HardwareView', {
     extend: 'PVE.grid.ObjectGrid',
     alias: ['widget.PVE.qemu.HardwareView'],
@@ -895,7 +128,7 @@
 	    rows["unused" + i] = {
 		group: 3,
 		tdCls: 'pve-itype-icon-storage',
-		editor: 'PVE.qemu.HDCreate',
+		editor: 'PVE.qemu.HDEdit',
 		header: 'Unused Disk'
 	    };
 	}
@@ -1022,7 +255,7 @@
 				text: 'Hard Disk',
 				iconCls: 'pve-itype-icon-storage',
 				handler: function() {
-				    var win = Ext.create('PVE.qemu.HDCreate', {
+				    var win = Ext.create('PVE.qemu.HDEdit', {
 					url: '/api2/extjs/' + baseurl,
 					pveSelNode: me.pveSelNode
 				    });
@@ -1034,8 +267,7 @@
 				text: 'CD/DVD Drive',
 				iconCls: 'pve-itype-icon-cdrom',
 				handler: function() {
-				    var win = Ext.create('PVE.qemu.HDCreate', {
-					cdrom: true,
+				    var win = Ext.create('PVE.qemu.CDEdit', {
 					url: '/api2/extjs/' + baseurl,
 					pveSelNode: me.pveSelNode
 				    });
@@ -1071,9 +303,6 @@
 
 	me.callParent();
 
-	me.on('show', function() {
-	    reload();
-	});
-
+	me.on('show', reload);
     }
 });

Added: pve-manager/pve2/www/manager/qemu/KeyboardEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/KeyboardEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/KeyboardEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,21 @@
+Ext.define('PVE.qemu.KeyboardEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	var me = this;
+
+	Ext.applyIf(me, {
+	    title: "Edit keyboard settings",
+	    items: {
+		xtype: 'VNCKeyboardSelector',
+		name: 'keyboard',
+		value: '',
+		fieldLabel: 'Keyboard Layout'
+	    }
+	});
+
+	me.callParent();
+
+	me.load();
+    }
+});

Added: pve-manager/pve2/www/manager/qemu/MemoryEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/MemoryEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/MemoryEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,46 @@
+Ext.define('PVE.qemu.MemoryInputPanel', {
+    extend: 'PVE.panel.InputPanel',
+    alias: 'widget.PVE.qemu.MemoryInputPanel',
+
+    insideWizard: false,
+
+    initComponent : function() {
+	var me = this;
+
+	var items = {
+	    xtype: 'numberfield',
+	    name: 'memory',
+	    minValue: 32,
+	    maxValue: 128*1024,
+	    value: '512',
+	    step: 32,
+	    fieldLabel: 'Memory (MB)',
+	    allowBlank: false
+	};
+
+	if (me.insideWizard) {
+	    me.column1 = items;
+	} else {
+	    me.items = items;
+	}
+
+	me.callParent();
+    }
+});
+
+Ext.define('PVE.qemu.MemoryEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	var me = this;
+	
+	Ext.apply(me, {
+	    title: "Edit memory settings",
+	    items: Ext.create('PVE.qemu.MemoryInputPanel')
+	});
+
+	me.callParent();
+
+	me.load();
+    }
+});
\ No newline at end of file

Added: pve-manager/pve2/www/manager/qemu/NetworkEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/NetworkEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/NetworkEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,178 @@
+Ext.define('PVE.qemu.NetworkInputPanel', {
+    extend: 'PVE.panel.InputPanel',
+    alias: 'widget.PVE.qemu.NetworkInputPanel',
+
+    insideWizard: false,
+
+    onGetValues: function(values) {
+	var me = this;
+
+	me.network.model = values.model;
+	if (values.networkmode === 'none') {
+	    return {};
+	} else if (values.networkmode === 'bridge') {
+	    me.network.bridge = values.bridge;
+	} else {
+	    me.network.bridge = undefined;
+	}
+	me.network.mac = values.mac;
+
+	var params = {};
+
+	params[me.confid] = PVE.Parser.printQemuNetwork(me.network);
+
+	return params;
+    },
+
+    setNetwork: function(confid, data) {
+	var me = this;
+
+	me.confid = confid;
+
+	if (data) {
+	    data.networkmode = data.bridge ? 'bridge' : 'nat';
+	} else {
+	    data = {};
+	    data.networkmode = 'bridge';
+	}
+	me.network = data;
+	
+	me.setValues(me.network);
+    },
+
+    setNodename: function(nodename) {
+	var me = this;
+
+	me.bridgesel.setNodename(nodename);
+    },
+
+    initComponent : function() {
+	var me = this;
+
+	me.network = {};
+	me.confid = 'net0';
+
+	me.bridgesel = Ext.create('PVE.form.BridgeSelector', {
+	    name: 'bridge',
+	    fieldLabel: 'Bridge',
+	    nodename: me.nodename,
+	    labelAlign: 'right',
+	    autoSelect: true,
+	    allowBlank: false
+	});
+
+	me.column1 = [
+	    {
+		xtype: 'radiofield',
+		name: 'networkmode',
+		height: 22, // hack: set same height as text fields
+		inputValue: 'bridge',
+		boxLabel: 'Bridged mode',
+		checked: true,
+		listeners: {
+		    change: function(f, value) {
+			if (!me.rendered) {
+			    return;
+			}
+			me.down('field[name=bridge]').setDisabled(!value);
+			me.down('field[name=bridge]').validate();
+		    }
+		}
+	    },
+	    me.bridgesel,
+	    {
+		xtype: 'radiofield',
+		name: 'networkmode',
+		height: 22, // hack: set same height as text fields
+		inputValue: 'nat',
+		boxLabel: 'NAT mode'
+	    }
+	];
+
+	if (me.insideWizard) {
+	    me.column1.push({
+		xtype: 'radiofield',
+		name: 'networkmode',
+		height: 22, // hack: set same height as text fields
+		inputValue: 'none',
+		boxLabel: 'No network device'
+	    });
+	}
+
+	me.column2 = [
+	    {
+		xtype: 'PVE.form.NetworkCardSelector',
+		name: 'model',
+		fieldLabel: 'Network card',
+		value: 'rtl8139',
+		allowBlank: false
+	    },
+	    {
+		xtype: 'textfield',
+		name: 'mac',
+		fieldLabel: 'MAC address',
+		vtype: 'MacAddress',
+		allowBlank: true,
+		emptyText: 'auto'
+	    }
+	];
+
+	me.callParent();
+    }
+});
+
+Ext.define('PVE.qemu.NetworkEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	/*jslint confusion: true */
+
+	var me = this;
+
+	var nodename = me.pveSelNode.data.node;
+	if (!nodename) { 
+	    throw "no node name specified";	    
+	}
+
+	me.create = me.confid ? false : true;
+
+	var ipanel = Ext.create('PVE.qemu.NetworkInputPanel', {
+	    confid: me.confid,
+	    nodename: nodename
+	});
+
+	Ext.applyIf(me, {
+	    title: me.create ? "Add network device" : 
+		"Edit network device settings",
+	    items: ipanel
+	});
+
+	me.callParent();
+
+	me.load({
+	    success: function(form, action) {
+		var i, confid;
+		me.vmconfig = action.result.data;
+		if (!me.create) {
+		    var value = me.vmconfig[me.confid];
+		    var network = PVE.Parser.parseQemuNetwork(me.confid, value);
+		    if (!network) {
+			Ext.Msg.alert('Error', 'Unable to parse network options');
+			me.close();
+			return;
+		    }
+		    ipanel.setNetwork(me.confid, network);
+		} else {
+		    for (i = 0; i < 100; i++) {
+			confid = 'net' + i.toString();
+			if (!Ext.isDefined(me.vmconfig[confid])) {
+			    me.confid = confid;
+			    break;
+			}
+		    }
+		    ipanel.setNetwork(me.confid);		    
+		}
+	    }
+	});
+    }
+});

Added: pve-manager/pve2/www/manager/qemu/OSTypeEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/OSTypeEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/OSTypeEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,97 @@
+Ext.define('PVE.qemu.OSTypeInputPanel', {
+    extend: 'PVE.panel.InputPanel',
+    alias: 'widget.PVE.qemu.OSTypeInputPanel',
+
+    initComponent : function() {
+	var me = this;
+
+	me.column1 = [
+	    {
+		xtype: 'component', 
+		html: 'Microsoft Windows', 
+		cls:'x-form-check-group-label'
+	    },
+	    {
+		xtype: 'radiofield',
+		name: 'ostype',
+		inputValue: 'win7',
+		boxLabel: 'Microsoft Windows 7/2008r2'
+	    },
+	    {
+		xtype: 'radiofield',
+		name: 'ostype',
+		inputValue: 'w2k8',
+		boxLabel: 'Microsoft Windows Vista/2008'
+	    },
+	    {
+		xtype: 'radiofield',
+		name: 'ostype',
+		inputValue: 'wxp',
+		boxLabel: 'Microsoft Windows XP/2003'
+	    },
+	    {
+		xtype: 'radiofield',
+		name: 'ostype',
+		inputValue: 'w2k',
+		boxLabel: 'Microsoft Windows 2000'
+	    }
+	];
+
+	me.column2 = [
+	    {
+		xtype: 'component', 
+		html: 'Linux/Other', 
+		cls:'x-form-check-group-label'
+	    },
+	    {
+		xtype: 'radiofield',
+		name: 'ostype',
+		inputValue: 'l26',
+		boxLabel: 'Linux 2.6 Kernel'
+	    },
+	    {
+		xtype: 'radiofield',
+		name: 'ostype',
+		inputValue: 'l24',
+		boxLabel: 'Linux 2.4 Kernel'
+	    },
+	    {
+		xtype: 'radiofield',
+		name: 'ostype',
+		inputValue: 'other',
+		boxLabel: 'Other'
+	    }
+	];
+
+	Ext.apply(me, {
+	    useFieldContainer: {
+		xtype: 'radiogroup',
+		allowBlank: false
+	    }
+	});
+
+	me.callParent();
+    }   
+});
+
+Ext.define('PVE.qemu.OSTypeEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	var me = this;
+	
+	Ext.apply(me, {
+	    title: 'OS Type',
+	    items: Ext.create('PVE.qemu.OSTypeInputPanel')
+	});
+
+	me.callParent();
+
+	me.load({
+	    success: function(form, action) {
+		var value = action.result.data.ostype || 'other';
+		form.setValues({ ostype: value});
+	    }
+	});
+    }
+});

Modified: pve-manager/pve2/www/manager/qemu/Options.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/Options.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/qemu/Options.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -30,6 +30,7 @@
 	    },
 	    ostype: {
 		header: 'OS Type',
+		editor: 'PVE.qemu.OSTypeEdit',
 		defaultValue: 'other'
 	    },
 	    boot: {
@@ -65,13 +66,34 @@
 	    }
 	};
 
-	var run_editor = function() {
-	    
-	    console.log("TEST EDIT");
+	var baseurl = 'nodes/' + nodename + '/qemu/' + vmid + '/config';
 
+	var reload = function() {
 	    me.rstore.load();
 	};
 
+	var run_editor = function() {
+	    var sm = me.getSelectionModel();
+	    var rec = sm.getSelection()[0];
+	    if (!rec) {
+		return;
+	    }
+
+	    var rowdef = rows[rec.data.key];
+	    if (!rowdef.editor) {
+		return;
+	    }
+
+	    var win = Ext.create(rowdef.editor, {
+		pveSelNode: me.pveSelNode,
+		confid: rec.data.key,
+		url: '/api2/extjs/' + baseurl
+	    });
+
+	    win.show();
+	    win.on('destroy', reload);
+	};
+
 	var edit_btn = new Ext.Button({
 	    text: 'Edit',
 	    disabled: true,
@@ -81,7 +103,13 @@
 	var set_button_status = function() {
 	    var sm = me.getSelectionModel();
 	    var rec = sm.getSelection()[0];
-	    edit_btn.setDisabled(!rec);
+
+	    if (!rec) {
+		edit_btn.disable();
+		return;
+	    }
+	    var rowdef = rows[rec.data.key];
+	    edit_btn.setDisabled(!rowdef.editor);
 	};
 
 	Ext.applyIf(me, {
@@ -97,8 +125,6 @@
 
 	me.callParent();
 
-	me.on('show', function() {
-	    me.rstore.load();
-	});
+	me.on('show', reload);
     }
 });

Added: pve-manager/pve2/www/manager/qemu/ProcessorEdit.js
===================================================================
--- pve-manager/pve2/www/manager/qemu/ProcessorEdit.js	                        (rev 0)
+++ pve-manager/pve2/www/manager/qemu/ProcessorEdit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -0,0 +1,79 @@
+Ext.define('PVE.qemu.ProcessorInputPanel', {
+    extend: 'PVE.panel.InputPanel',
+    alias: 'widget.PVE.qemu.ProcessorInputPanel',
+
+    initComponent : function() {
+	var me = this;
+
+	me.column1 = [
+	    {
+		xtype: 'numberfield',
+		name: 'sockets',
+		minValue: 1,
+		maxValue: 4,
+		value: '1',
+		fieldLabel: 'Sockets',
+		allowBlank: false,
+		listeners: {
+		    change: function(f, value) {
+			var sockets = me.down('field[name=sockets]').getValue();
+			var cores = me.down('field[name=cores]').getValue();
+			me.down('field[name=totalcores]').setValue(sockets*cores);
+		    }
+		}
+	    },
+	    {
+		xtype: 'numberfield',
+		name: 'cores',
+		minValue: 1,
+		maxValue: 32,
+		value: '1',
+		fieldLabel: 'Cores',
+		allowBlank: false,
+		listeners: {
+		    change: function(f, value) {
+			var sockets = me.down('field[name=sockets]').getValue();
+			var cores = me.down('field[name=cores]').getValue();
+			me.down('field[name=totalcores]').setValue(sockets*cores);
+		    }
+		}
+	    }
+	];
+
+
+	me.column2 = [
+	    {
+		xtype: 'CPUModelSelector',
+		name: 'cpu',
+		value: '',
+		fieldLabel: 'CPU type'
+	    },
+	    {
+		xtype: 'displayfield',
+		fieldLabel: 'Total cores',
+		name: 'totalcores',
+		value: '1'
+	    }
+
+	];
+
+	me.callParent();
+    }
+});
+
+Ext.define('PVE.qemu.ProcessorEdit', {
+    extend: 'PVE.window.Edit',
+
+    initComponent : function() {
+	var me = this;
+	
+	Ext.apply(me, {
+	    title: "Edit processor settings",
+	    items: Ext.create('PVE.qemu.ProcessorInputPanel')
+	});
+
+	me.callParent();
+
+	me.load();
+    }
+});
\ No newline at end of file

Modified: pve-manager/pve2/www/manager/window/Edit.js
===================================================================
--- pve-manager/pve2/www/manager/window/Edit.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/window/Edit.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -10,18 +10,16 @@
     // OK and RESET) 
     create: false, 
 
-    // getParams: function(values): Object
-    // a way to modify parameters and use PVE.Utils.API2Request()
-    // to submit data
-
     submit: function(formpanel) {
 	var me = this;
 
-	if (Ext.isFunction(me.getParams)) {
+	var inputpanel = formpanel.child('inputpanel');
 
+	if (inputpanel) {
+
 	    var values = formpanel.getValues();
 
-	    var params = me.getParams(values);
+	    var params = inputpanel.onGetValues(values);
 
 	    PVE.Utils.API2Request({
 		url: me.url,
@@ -50,6 +48,19 @@
     load: function(options) {
 	var me = this;
 
+	options = options || {};
+
+	var orgSuccessFn = options.success;
+	options.success =  function(form, action) {
+	    if (orgSuccessFn) {
+		orgSuccessFn(form, action);
+	    }
+	    // hack: fix ExtJS bug
+	    Ext.Array.each(me.query('radiofield'), function(f) {
+		f.resetOriginalValue();
+	    });
+	};
+
 	var newopts = Ext.apply({}, options, {
 	    method: 'GET',
 	    failure: function(form, action) {
@@ -69,52 +80,26 @@
 	    throw "no url specified";
 	}
 
-	var items;
-	
-	if (me.items) {
-	    items = [
-		{
-		    columnWidth: 1,
-		    layout: 'anchor',
-		    items: me.items
-		}
-	    ];
-	    me.items = undefined;
-	} else if (me.column1 && me.column2) {
-	    items = [
-		{
-		    columnWidth: 0.5,
-		    padding: '0 10 0 0',
-		    layout: 'anchor',
-		    items: me.column1
-		},
-		{
-		    columnWidth: 0.5,
-		    padding: '0 0 0 10',
-		    layout: 'anchor',
-		    items: me.column2
-		}
-	    ];
-	} else {
-	    throw "unsupported config";
-	}
+	var items = Ext.isArray(me.items) ? me.items : [ me.items ];
 
+	me.items = undefined;
+
 	var formpanel = Ext.create('Ext.form.Panel', {
 	    url: me.url,
 	    method: me.method || 'PUT',
 	    trackResetOnLoad: true,
 	    bodyPadding: 10,
-	    border: false,	    
+	    border: false,
+	    defaults: {
+		border: false
+	    },
 	    fieldDefaults: Ext.apply({}, me.fieldDefaults, {
 		labelWidth: 100,
 		anchor: '100%'
             }),
-	    layout: 'column',
-	    defaultType: 'container',
 	    items: items
 	});
 
-
 	var form = formpanel.getForm();
 
 	var submitBtn = Ext.create('Ext.Button', {
@@ -147,11 +132,13 @@
 	if (me.fieldDefaults && me.fieldDefaults.labelWidth) {
 	    colwidth += me.fieldDefaults.labelWidth - 100;
 	}
- 
+	
+	var twoColumn = items[0].column1 || items[0].column2;
+
 	Ext.applyIf(me, {
 	    modal: true,
 	    layout: 'auto',
-	    width: me.column2 ? colwidth*2 : colwidth,
+	    width: twoColumn ? colwidth*2 : colwidth,
 	    border: false,
 	    items: [ formpanel ],
 	    buttons: me.create ? [ submitBtn ] : [ submitBtn, resetBtn ]

Modified: pve-manager/pve2/www/manager/window/Wizard.js
===================================================================
--- pve-manager/pve2/www/manager/window/Wizard.js	2011-07-11 04:57:41 UTC (rev 6291)
+++ pve-manager/pve2/www/manager/window/Wizard.js	2011-07-13 05:38:48 UTC (rev 6292)
@@ -1,75 +1,3 @@
-Ext.define('PVE.panel.InputPanel', {
-    extend: 'Ext.panel.Panel',
-    requires: [
-	'PVE.Utils'
-    ],
-    alias: ['widget.inputpanel'],
-
-    getValues: function(dirtyOnly) {
-	var me = this;
-
-	if (Ext.isFunction(me.onGetValues)) {
-	    dirtyOnly = false;
-	}
-
-	var values = {};
-
-	Ext.Array.each(me.query('[isFormField]'), function(field) {
-            if (!dirtyOnly || field.isDirty()) {
-                PVE.Utils.assemble_field_data(values, field.getSubmitData());
-	    }
-	});
-
-	if (Ext.isFunction(me.onGetValues)) {
-	    return me.onGetValues(values, dirtyOnly);
-	}
-
-	return values;	       
-    },
-
-    initComponent: function() {
-	var me = this;
-
-	var items;
-	
-	if (me.items) {
-	    items = [
-		{
-		    columnWidth: 0.5,
-		    layout: 'anchor',
-		    items: me.items
-		}
-	    ];
-	    me.items = undefined;
-	} else if (me.column1 && me.column2) {
-	    items = [
-		{
-		    columnWidth: 0.5,
-		    padding: '0 10 0 0',
-		    layout: 'anchor',
-		    items: me.column1
-		},
-		{
-		    columnWidth: 0.5,
-		    padding: '0 0 0 10',
-		    layout: 'anchor',
-		    items: me.column2
-		}
-	    ];
-	} else {
-	    throw "unsupported config";
-	}
-
-	Ext.apply(me, {
-	    layout: 'column',
-	    defaultType: 'container',
-	    items: items
-	});
-
-	me.callParent();
-    }
-});
-
 Ext.define('PVE.window.Wizard', {
     extend: 'Ext.window.Window',
     requires: [
@@ -217,7 +145,7 @@
 	    }
 	};
 
-	var tabchange = function(tp, newcard, oldcard) {	    
+	var tabchange = function(tp, newcard, oldcard) {
 	    if (newcard.onSubmit) {
 		me.down('#next').setVisible(false);
 		me.down('#submit').setVisible(true); 




More information about the pve-devel mailing list