Index: /CKEditor/trunk/_source/core/config.js
===================================================================
--- /CKEditor/trunk/_source/core/config.js	(revision 3113)
+++ /CKEditor/trunk/_source/core/config.js	(revision 3114)
@@ -148,5 +148,5 @@
 	 */
 
-	plugins : 'basicstyles,blockquote,button,clipboard,elementspath,find,flash,format,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,newpage,pagebreak,pastefromword,pastetext,preview,print,removeformat,smiley,showblocks,sourcearea,table,specialchar,tab,templates,toolbar,undo,wysiwygarea',
+	plugins : 'basicstyles,blockquote,button,clipboard,elementspath,find,flash,format,forms,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,newpage,pagebreak,pastefromword,pastetext,preview,print,removeformat,smiley,showblocks,sourcearea,table,specialchar,tab,templates,toolbar,undo,wysiwygarea',
 
 	/**
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/button.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/button.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/button.js	(revision 3114)
@@ -0,0 +1,111 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'button', function( editor )
+{
+	return {
+		title : editor.lang.button.title,
+		minWidth : 400,
+		minHeight : 230,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+			if ( element && element.getName() == "input" )
+			{
+				var type = element.getAttribute( 'type' );
+				if ( type == "button" || type == "reset" || type == "submit" )
+				{
+					this._element = element;
+					this.setupContent( element );
+				}
+			}
+		},
+		onOk : function()
+		{
+			var editor,
+				element = this._element,
+				isInsertMode = !element;
+
+			if ( isInsertMode )
+			{
+				editor = this.getParentEditor();
+				element = editor.document.createElement( 'input' );
+			}
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.button.title,
+				title : editor.lang.button.title,
+				elements : [
+					{
+						id : 'txtName',
+						type : 'text',
+						label : editor.lang.common.name,
+						'default' : '',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'name' ) );
+							this.focus();
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'name', this.getValue() );
+						}
+					},
+					{
+						id : 'txtValue',
+						type : 'text',
+						label : editor.lang.button.text,
+						accessKey : 'V',
+						'default' : '',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'value' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'value', this.getValue() );
+						}
+					},
+					{
+						id : 'txtType',
+						type : 'select',
+						label : editor.lang.button.type,
+						'default' : 'button',
+						accessKey : 'T',
+						items :
+						[
+							[ editor.lang.button.typeBtn, 'button' ],
+							[ editor.lang.button.typeSbm, 'submit' ],
+							[ editor.lang.button.typeRst, 'reset' ]
+						],
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'type' ) );
+						},
+						commit : function( element )
+						{
+							element.setAttribute( 'type', this.getValue() );
+						}
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/checkbox.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/checkbox.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/checkbox.js	(revision 3114)
@@ -0,0 +1,108 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'checkbox', function( editor )
+{
+	return {
+		title : editor.lang.checkboxAndRadio.checkboxTitle,
+		minWidth : 400,
+		minHeight : 230,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+
+			if ( element && element.getAttribute( 'type' ) == "checkbox" )
+			{
+				this._element = element;
+				this.setupContent( element );
+			}
+		},
+		onOk : function()
+		{
+			var editor,
+				element = this._element,
+				isInsertMode = !element;
+			
+			if ( isInsertMode )
+			{
+				editor = this.getParentEditor();
+				element = editor.document.createElement( 'input' );
+				element.setAttribute( 'type', 'checkbox' );
+			}
+
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.checkboxAndRadio.checkboxTitle,
+				title : editor.lang.checkboxAndRadio.checkboxTitle,
+				startupFocus : 'txtName',
+				elements : [
+					{
+						id : 'txtName',
+						type : 'text',
+						label : editor.lang.common.name,
+						'default' : '',
+						accessKey : 'N',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'name' ) );
+							this.focus();
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'name', this.getValue() );
+						}
+					},
+					{
+						id : 'txtValue',
+						type : 'text',
+						label : editor.lang.checkboxAndRadio.value,
+						'default' : '',
+						accessKey : 'V',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'value' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'value', this.getValue() );
+						}
+					},
+					{
+						id : 'cmbSelected',
+						type : 'checkbox',
+						label : editor.lang.checkboxAndRadio.selected,
+						'default' : '',
+						accessKey : 'S',
+						value : "checked",
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'checked' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() == true || this.isChanged() )
+								element.setAttribute( 'checked', this.getValue() );
+						}
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/form.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/form.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/form.js	(revision 3114)
@@ -0,0 +1,186 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'form', function( editor )
+{
+	return {
+		title : editor.lang.form.title,
+		minWidth : 400,
+		minHeight : 270,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+			if ( element && element.getName() == "form" )
+			{
+				this._element = element;
+				this.setupContent( element );
+			}
+		},
+		onOk : function()
+		{
+			var editor,
+				element = this._element,
+				isInsertMode = !element;
+
+			if ( isInsertMode )
+			{
+				editor = this.getParentEditor();
+				element = CKEDITOR.dom.element.createFromHtml( '<form><br></form>' );
+			}
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.form.title,
+				title : editor.lang.form.title,
+				elements : [
+					{
+						id : 'txtName',
+						type : 'text',
+						label : editor.lang.common.name,
+						'default' : '',
+						accessKey : 'N',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'name' ) );
+							this.focus();
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'name', this.getValue() );
+						}
+					},
+					{
+						id : 'txtAction',
+						type : 'text',
+						label : editor.lang.form.action,
+						'default' : '',
+						accessKey : 'A',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'action' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'action', this.getValue() );
+						}
+					},
+					{
+						type : 'hbox',
+						widths : [ '45%', '55%' ],
+						children :
+						[
+							{
+								id : 'txtId',
+								type : 'text',
+								label : editor.lang.common.id,
+								'default' : '',
+								accessKey : 'I',
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'id' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'id', this.getValue() );
+								}
+							},
+							{
+								id : 'cmbEncoding',
+								type : 'select',
+								label : editor.lang.form.encoding,
+								style : 'width:100%',
+								accessKey : 'E',
+								'default' : '',
+								items :
+								[
+									[ '' ],
+									[ 'text/plain' ],
+									[ 'multipart/form-data' ],
+									[ 'application/x-www-form-urlencoded' ]
+								],
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'encoding' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'encoding', this.getValue() );
+								}
+							}
+						]
+					},
+					{
+						type : 'hbox',
+						widths : [ '45%', '55%' ],
+						children :
+						[
+							{
+								id : 'cmbTarget',
+								type : 'select',
+								label : editor.lang.form.target,
+								style : 'width:100%',
+								accessKey : 'M',
+								'default' : '',
+								items :
+								[
+									[ editor.lang.form.targetNotSet, '' ],
+									[ editor.lang.form.targetNew, '_blank' ],
+									[ editor.lang.form.targetTop, '_top' ],
+									[ editor.lang.form.targetSelf, '_self' ],
+									[ editor.lang.form.targetParent, '_parent' ]
+								],
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'target' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'target', this.getValue() );
+								}
+							},
+							{
+								id : 'cmbMethod',
+								type : 'select',
+								label : editor.lang.form.method,
+								accessKey : 'M',
+								'default' : 'GET',
+								items :
+								[
+									[ 'GET', 'get' ],
+									[ 'POST', 'post' ]
+								],
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'method' ) );
+								},
+								commit : function( element )
+								{
+									element.setAttribute( 'method', this.getValue() );
+								}
+							}
+						]
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/hiddenfield.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/hiddenfield.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/hiddenfield.js	(revision 3114)
@@ -0,0 +1,88 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'hiddenfield', function( editor )
+{
+	return {
+		title : editor.lang.hidden.title,
+		minWidth : 400,
+		minHeight : 200,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+			if ( element && element.getName() == "input" && element.getAttribute( 'type' ) == "checkbox" )
+			{
+				this._element = element;
+				this.setupContent( element );
+			}
+		},
+		onOk : function()
+		{
+			var editor,
+				element = this._element,
+				isInsertMode = !element;
+
+			if ( isInsertMode )
+			{
+				editor = this.getParentEditor();
+				element = editor.document.createElement( 'input' );
+				element.setAttribute( 'type', 'hidden' );
+			}
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.hidden.title,
+				title : editor.lang.hidden.title,
+				elements : [
+					{
+						id : 'txtName',
+						type : 'text',
+						label : editor.lang.hidden.name,
+						'default' : '',
+						accessKey : 'N',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'name' ) );
+							this.focus();
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'name', this.getValue() );
+						}
+					},
+					{
+						id : 'txtValue',
+						type : 'text',
+						label : editor.lang.hidden.value,
+						'default' : '',
+						accessKey : 'V',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'value' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'value', this.getValue() );
+						}
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/radio.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/radio.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/radio.js	(revision 3114)
@@ -0,0 +1,105 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'radio', function( editor )
+{
+	return {
+		title : editor.lang.checkboxAndRadio.radioTitle,
+		minWidth : 400,
+		minHeight : 200,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+			if ( element && element.getName() == "input" && element.getAttribute( 'type' ) == "radio" )
+			{
+				this._element = element;
+				this.setupContent( element );
+			}
+		},
+		onOk : function()
+		{
+			var editor,
+				element = this._element,
+				isInsertMode = !element;
+
+			if ( isInsertMode )
+			{
+				editor = this.getParentEditor();
+				element = editor.document.createElement( 'input' );
+				element.setAttribute( 'type', 'radio' );
+			}
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.checkboxAndRadio.radioTitle,
+				title : editor.lang.checkboxAndRadio.radioTitle,
+				elements : [
+					{
+						id : 'txtName',
+						type : 'text',
+						label : editor.lang.common.name,
+						'default' : '',
+						accessKey : 'N',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'name' ) );
+							this.focus();
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'name', this.getValue() );
+						}
+					},
+					{
+						id : 'txtValue',
+						type : 'text',
+						label : editor.lang.checkboxAndRadio.value,
+						'default' : '',
+						accessKey : 'V',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'value' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'value', this.getValue() );
+						}
+					},
+					{
+						id : 'cmbSelected',
+						type : 'checkbox',
+						label : editor.lang.checkboxAndRadio.selected,
+						'default' : '',
+						accessKey : 'S',
+						value : "checked",
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'checked' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() == true || this.isChanged() )
+								element.setAttribute( 'checked', this.getValue() );
+						}
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/select.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/select.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/select.js	(revision 3114)
@@ -0,0 +1,524 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'select', function( editor )
+{
+	// Add a new option to a SELECT object (combo or list).
+	function addOption( combo, optionText, optionValue, documentObject, index )
+	{
+		combo = getSelect( combo );
+		var oOption;
+		if ( documentObject )
+			oOption = documentObject.createElement( "OPTION" );
+		else
+			oOption = document.createElement( "OPTION" );
+
+		if ( combo && oOption && oOption.getName() == 'option' )
+		{
+			if ( CKEDITOR.env.ie ) {
+				if ( !isNaN( parseInt( index, 10) ) )
+					combo.$.options.add( oOption.$, index );
+				else
+					combo.$.options.add( oOption.$ );
+
+				oOption.$.innerHTML = optionText.length > 0 ? optionText : '';
+				oOption.$.value     = optionValue;
+			}
+			else
+			{
+				if ( index != null && index < combo.getChildCount() )
+					combo.getChild( index < 0 ? 0 : index ).insertBeforeMe( oOption );
+				else
+					combo.append( oOption );
+
+				oOption.setText( optionText.length > 0 ? optionText : '' );
+				oOption.setValue( optionValue );
+			}
+		}
+		else
+			return false;
+
+		return oOption;
+	}
+	// Remove all selected options from a SELECT object.
+	function removeSelectedOptions( combo )
+	{
+		combo = getSelect( combo );
+
+		// Save the selected index
+		var iSelectedIndex = getSelectedIndex( combo );
+
+		// Remove all selected options.
+		for ( var i = combo.getChildren().count() - 1 ; i >= 0 ; i-- )
+		{
+			if ( combo.getChild( i ).$.selected )
+				combo.getChild( i ).remove();
+		}
+
+		// Reset the selection based on the original selected index.
+		setSelectedIndex( combo, iSelectedIndex );
+	}
+	//Modify option  from a SELECT object.
+	function modifyOption( combo, index, title, value )
+	{
+		combo = getSelect( combo );
+		if ( index < 0 )
+			return false;
+		var child = combo.getChild( index );
+		child.setText( title );
+		child.setValue( value );
+		return child;
+	}
+	function removeAllOptions( combo )
+	{
+		combo = getSelect( combo );
+		while( combo.getChild( 0 ) && combo.getChild( 0 ).remove() );
+	}
+	// Moves the selected option by a number of steps (also negative).
+	function changeOptionPosition( combo, steps, documentObject )
+	{
+		combo = getSelect( combo );
+		var iActualIndex = getSelectedIndex( combo );
+		if ( iActualIndex < 0 )
+			return false;
+
+		var iFinalIndex = iActualIndex + steps;
+		iFinalIndex = ( iFinalIndex < 0 ) ? 0 : iFinalIndex;
+		iFinalIndex = ( iFinalIndex >= combo.getChildCount() ) ? combo.getChildCount() - 1 : iFinalIndex;
+
+		if ( iActualIndex == iFinalIndex )
+			return false;
+
+		var oOption = combo.getChild( iActualIndex ),
+			sText	= oOption.getText(),
+			sValue	= oOption.getValue();
+
+		oOption.remove();
+
+		oOption = addOption( combo, sText, sValue, ( !documentObject ) ? null : documentObject, iFinalIndex );
+		setSelectedIndex( combo, iFinalIndex );
+		return oOption;
+	}
+	function getSelectedIndex( combo )
+	{
+		combo = getSelect( combo );
+		return combo ? combo.$.selectedIndex : -1;
+	}
+	function setSelectedIndex( combo, index )
+	{
+		combo = getSelect( combo );
+		if ( index < 0 )
+			return ;
+		var count = combo.getChildren().count();
+		combo.$.selectedIndex = ( index >= count ) ? ( count - 1 ) : index;
+		return combo;
+	}
+	function getOptions( combo )
+	{
+		combo = getSelect( combo );
+		return combo ? combo.getChildren() : false;
+	}
+	function getSelect( obj )
+	{
+		if ( obj && obj.domId && obj.getInputElement().$ )				// Dialog element.
+			return  obj.getInputElement();
+		else if ( obj && obj.$ )
+			return obj;
+		return false;
+	}
+
+	return {
+		title : editor.lang.select.title,
+		minWidth : 400,
+		minHeight : 370,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			this.setupContent( 'clear' );
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+			if ( element && element.getName() == "select" )
+			{
+				this._element = element;
+				this.setupContent( element.getName(), element );
+
+				//Load Options into dialog.
+				var objOptions = getOptions( element );
+				for ( var i = 0 ; i < objOptions.count() ; i++ )
+					this.setupContent( 'option', objOptions.getItem( i ) );
+			}
+		},
+		onOk : function()
+		{
+			var editor = this.getParentEditor(),
+				element = this._element,
+				isInsertMode = !element;
+
+			if ( isInsertMode )
+				element = editor.document.createElement( 'select' );
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.select.selectInfo,
+				title : editor.lang.select.selectInfo,
+				accessKey : '',
+				elements : [
+					{
+						id : 'txtName',
+						type : 'text',
+						widths : [ '25%','75%' ],
+						labelLayout : 'horizontal',
+						label : editor.lang.common.name,
+						'default' : '',
+						accessKey : 'N',
+						align : 'center',
+						style : 'width:350px',
+						setup : function( name, element )
+						{
+							if ( name == 'select' )
+							{
+								this.setValue( element.getAttribute( 'name' ) );
+								this.focus();
+							}
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'name', this.getValue() );
+						}
+					},
+					{
+						id : 'txtValue',
+						type : 'text',
+						widths : [ '25%','75%' ],
+						labelLayout : 'horizontal',
+						label : editor.lang.select.value,
+						style : 'width:350px',
+						'default' : '',
+						readonly : true,		// TODO: make it readonly somehow.
+						disabled : true
+					},
+					{
+						type : 'hbox',
+						widths : [ '175px', '170px' ],
+						align : 'center',
+						children :
+						[
+							{
+								id : 'txtSize',
+								type : 'text',
+								align : 'center',
+								labelLayout : 'horizontal',
+								label : editor.lang.select.size,
+								'default' : '',
+								accessKey : 'S',
+								style : 'width:175px',
+								validate: function()
+								{
+									var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
+									return ( ( this.getValue() == '' ) || func.apply( this ) );
+								},
+								setup : function( name, element )
+								{
+									if ( name == 'select' )
+										this.setValue( element.getAttribute( 'size' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'size', this.getValue() );
+								}
+							},
+							{
+								type : 'html',
+								html : '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.select.lines ) + '</span>'
+							}
+						]
+					},
+					{
+						type : 'html',
+						html : '<span>' + CKEDITOR.tools.htmlEncode( editor.lang.select.opAvail ) + '</span>'
+					},
+					{
+						type : 'hbox',
+						widths : [ '115px', '115px' ,'100px' ],
+						align : 'top',
+						children :
+						[
+							{
+								type : 'vbox',
+								children :
+								[
+									{
+										id : 'txtOptName',
+										type : 'text',
+										label : editor.lang.select.opText,
+										style : 'width:115px',
+										setup : function( name, element )
+										{
+											if ( name == 'clear' )
+												this.setValue( "" );
+										}
+									},
+									{
+										type : 'select',
+										id : 'cmbName',
+										label : '',
+										title : '',
+										size : 5,
+										style : 'width:115px;height:75px',
+										items : [],
+										onChange : function()
+										{
+											var dialog = this.getDialog(),
+												values = dialog.getContentElement( 'info', 'cmbValue' ),
+												optName = dialog.getContentElement( 'info', 'txtOptName' ),
+												optValue = dialog.getContentElement( 'info', 'txtOptValue' ),
+												iIndex = getSelectedIndex( this );
+
+											setSelectedIndex( values, iIndex );
+											optName.setValue( this.getValue() );
+											optValue.setValue( values.getValue() );
+										},
+										setup : function( name, element )
+										{
+											if ( name == 'clear' )
+												removeAllOptions( this );
+											else if ( name == 'option' )
+												addOption( this, element.getText(), element.getText(), 
+													this.getDialog().getParentEditor().document );
+										},
+										commit : function( element )
+										{
+											var dialog = this.getDialog(),
+												optionsNames = getOptions( this ),
+												optionsValues = getOptions( dialog.getContentElement( 'info', 'cmbValue' ) ),
+												selectValue = dialog.getContentElement( 'info', 'txtValue' ).getValue();
+
+											removeAllOptions( element );
+
+											for ( var i = 0 ; i < optionsNames.count() ; i++ )
+											{
+												var oOption = addOption( element, optionsNames.getItem( i ).getValue(), 
+													optionsValues.getItem( i ).getValue(), dialog.getParentEditor().document );	
+												if ( optionsValues.getItem( i ).getValue() == selectValue )
+												{
+													oOption.setAttribute( 'selected', 'selected' );
+													oOption.selected = true;
+												}
+											}
+										}
+									}
+								]
+							},
+							{
+								type : 'vbox',
+								children :
+								[
+									{
+										id : 'txtOptValue',
+										type : 'text',
+										label : editor.lang.select.opValue,
+										style : 'width:115px',
+										setup : function( name, element )
+										{
+											if ( name == 'clear' )
+												this.setValue( "" );
+										}
+									},
+									{
+										type : 'select',
+										id : 'cmbValue',
+										label : '',
+										size : 5,
+										style : 'width:115px;height:75px',
+										items : [],
+										onChange : function()
+										{
+											var dialog = this.getDialog(),
+												names = dialog.getContentElement( 'info', 'cmbName' ),
+												optName = dialog.getContentElement( 'info', 'txtOptName' ),
+												optValue = dialog.getContentElement( 'info', 'txtOptValue' ),
+												iIndex = getSelectedIndex( this );
+												
+											setSelectedIndex( names, iIndex );
+											optName.setValue( names.getValue() );
+											optValue.setValue( this.getValue() );
+										},
+										setup : function( name, element )
+										{
+											if ( name == 'clear' )
+												removeAllOptions( this );
+											else if ( name == 'option' )
+											{
+												var oValue	= element.getValue();
+												addOption( this, oValue, oValue, 
+													this.getDialog().getParentEditor().document );
+												if ( element.getAttribute( 'selected' ) == 'selected' )
+													this.getDialog().getContentElement( 'info', 'txtValue' ).setValue( oValue );
+											}
+										}
+									},
+								]
+							},
+							{
+								type : 'vbox',
+								padding : 5,
+								children :
+								[
+									{
+										type : 'button',
+										style : '',
+										label : editor.lang.select.btnAdd,
+										title : editor.lang.select.btnAdd,
+										style : 'width:100%;',
+										onClick : function()
+										{
+											//Add new option.
+											var dialog = this.getDialog();
+												parentEditor = dialog.getParentEditor(),
+												optName = dialog.getContentElement( 'info', 'txtOptName' ),
+												optValue = dialog.getContentElement( 'info', 'txtOptValue' ),
+												names = dialog.getContentElement( 'info', 'cmbName' ),
+												values = dialog.getContentElement( 'info', 'cmbValue' );
+
+											addOption(names, optName.getValue(), optName.getValue(), dialog.getParentEditor().document );
+											addOption(values, optValue.getValue(), optValue.getValue(), dialog.getParentEditor().document );
+
+											optName.setValue( "" );
+											optValue.setValue( "" );
+										}
+									},
+									{
+										type : 'button',
+										label : editor.lang.select.btnModify,
+										title : editor.lang.select.btnModify,
+										style : 'width:100%;',
+										onClick : function()
+										{
+											//Modify selected option.
+											var dialog = this.getDialog();
+												optName = dialog.getContentElement( 'info', 'txtOptName' ),
+												optValue = dialog.getContentElement( 'info', 'txtOptValue' ),
+												names = dialog.getContentElement( 'info', 'cmbName' ),
+												values = dialog.getContentElement( 'info', 'cmbValue' ),
+												iIndex = getSelectedIndex( names );
+
+											if ( iIndex >= 0 )
+											{
+												modifyOption( names, iIndex, optName.getValue(), optName.getValue() );
+												modifyOption( values, iIndex, optValue.getValue(), optValue.getValue() );
+											}
+										}
+									},
+									{
+										type : 'button',
+										style : 'width:100%;',
+										label : editor.lang.select.btnUp,
+										title : editor.lang.select.btnUp,
+										onClick : function()
+										{
+											//Move up.
+											var dialog = this.getDialog(),
+												names = dialog.getContentElement( 'info', 'cmbName' ),
+												values = dialog.getContentElement( 'info', 'cmbValue' );
+
+											changeOptionPosition( names, -1, dialog.getParentEditor().document );
+											changeOptionPosition( values, -1, dialog.getParentEditor().document );
+										}
+									},
+									{
+										type : 'button',
+										style : 'width:100%;',
+										label : editor.lang.select.btnDown,
+										title : editor.lang.select.btnDown,
+										onClick : function()
+										{
+											//Move down.
+											var dialog = this.getDialog(),
+												names = dialog.getContentElement( 'info', 'cmbName' ),
+												values = dialog.getContentElement( 'info', 'cmbValue' );
+
+											changeOptionPosition( names, 1, dialog.getParentEditor().document );
+											changeOptionPosition( values, 1, dialog.getParentEditor().document );
+										}
+									}
+								]
+							}
+						]
+					},
+					{
+						type : 'hbox',
+						widths : [ '40%', '20%', '40%' ],
+						children :
+						[
+							{
+								type : 'button',
+								label : editor.lang.select.btnSetValue,
+								title : editor.lang.select.btnSetValue,
+								onClick : function()
+								{
+									//Set as default value.
+									var dialog = this.getDialog(),
+										values = dialog.getContentElement( 'info', 'cmbValue' ),
+										txtValue = dialog.getContentElement( 'info', 'txtValue' );
+									txtValue.setValue( values.getValue() );
+								}
+							},
+							{
+								type : 'button',
+								label : editor.lang.select.btnDelete,
+								title : editor.lang.select.btnDelete,
+								onClick : function()
+								{
+									// Delete option.
+									var dialog = this.getDialog(),
+										names = dialog.getContentElement( 'info', 'cmbName' ),
+										values = dialog.getContentElement( 'info', 'cmbValue' ),
+										optName = dialog.getContentElement( 'info', 'txtOptName' ),
+										optValue = dialog.getContentElement( 'info', 'txtOptValue' );
+									
+									removeSelectedOptions( names );
+									removeSelectedOptions( values );
+
+									optName.setValue( "" );
+									optValue.setValue( "" );
+								}
+							},
+							{
+								id : 'chkMulti',
+								type : 'checkbox',
+								label : editor.lang.select.chkMulti,
+								'default' : '',
+								accessKey : 'M',
+								value : "checked",
+								setup : function( name, element )
+								{
+									if ( name == 'select' )
+										this.setValue( element.getAttribute( 'multiple' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() == true || this.isChanged() )
+										element.setAttribute( 'multiple', this.getValue() );
+								}
+							}
+						]
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/textarea.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/textarea.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/textarea.js	(revision 3114)
@@ -0,0 +1,115 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'textarea', function( editor )
+{
+	return {
+		title : editor.lang.textarea.title,
+		minWidth : 400,
+		minHeight : 230,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+			if ( element && element.getName() == "textarea" )
+			{
+				this._element = element;
+				this.setupContent( element );
+			}
+		},
+		onOk : function()
+		{
+			var editor,
+				element = this._element,
+				isInsertMode = !element;
+
+			if ( isInsertMode )
+			{
+				editor = this.getParentEditor();
+				element = editor.document.createElement( 'textarea' );
+			}
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.textarea.title,
+				title : editor.lang.textarea.title,
+				elements : [
+					{
+						id : 'txtName',
+						type : 'text',
+						label : editor.lang.common.name,
+						'default' : '',
+						accessKey : 'N',
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'name' ) );
+							this.focus();
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'name', this.getValue() );
+						}
+					},
+					{
+						id : 'txtColumns',
+						type : 'text',
+						label : editor.lang.textarea.cols,
+						'default' : '',
+						accessKey : 'C',
+						style : 'width:50px',
+						validate: function()
+						{
+							var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
+							return func.apply( this );
+						},
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'cols' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'cols', this.getValue() );
+						}
+					},
+					{
+						id : 'txtRows',
+						type : 'text',
+						label : editor.lang.textarea.rows,
+						'default' : '',
+						accessKey : 'R',
+						style : 'width:50px',
+						validate: function()
+						{
+							var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
+							return func.apply( this );
+						},
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'rows' ) );
+						},
+						commit : function( element )
+						{
+							if ( this.getValue() != '' || this.isChanged() )
+								element.setAttribute( 'rows', this.getValue() );
+						}
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/dialogs/textfield.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/dialogs/textfield.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/dialogs/textfield.js	(revision 3114)
@@ -0,0 +1,166 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add( 'textfield', function( editor )
+{
+	return {
+		title : editor.lang.textfield.title,
+		minWidth : 400,
+		minHeight : 230,
+		onShow : function()
+		{
+			// IE BUG: Selection must be in the editor for getSelectedElement()
+			// to work.
+			this.restoreSelection();
+
+			var element = this.getParentEditor().getSelection().getSelectedElement();
+			if ( element && element.getName() == "input" && ( element.getAttribute( 'type' ) == "text" && !element.getAttribute( 'type' ) ) )
+			{
+				this._element = element;
+				this.setupContent( element );
+			}
+		},
+		onOk : function()
+		{
+			var editor,
+				element = this._element,
+				isInsertMode = !element;
+
+			if ( isInsertMode )
+			{
+				editor = this.getParentEditor();
+				element = editor.document.createElement( 'input' );
+				element.setAttribute( 'type', 'text' );
+			}
+			this.commitContent( element );
+
+			if ( isInsertMode )
+			{
+				this.restoreSelection();
+				this.clearSavedSelection();
+				editor.insertElement( element );
+			}
+		},
+		contents : [
+			{
+				id : 'info',
+				label : editor.lang.textfield.title,
+				title : editor.lang.textfield.title,
+				elements : [
+					{
+						type : 'hbox',
+						widths : [ '50%', '50%' ],
+						children :
+						[
+							{
+								id : 'txtName',
+								type : 'text',
+								label : editor.lang.textfield.name,
+								'default' : '',
+								accessKey : 'N',
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'name' ) );
+									this.focus();
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'name', this.getValue() );
+								}
+							},
+							{
+								id : 'txtValue',
+								type : 'text',
+								label : editor.lang.textfield.value,
+								'default' : '',
+								accessKey : 'V',
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'value' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'value', this.getValue() );
+								}
+							}
+						]
+					},
+					{
+						type : 'hbox',
+						widths : [ '50%', '50%' ],
+						children :
+						[
+							{
+								id : 'txtTextCharWidth',
+								type : 'text',
+								label : editor.lang.textfield.charWidth,
+								'default' : '',
+								accessKey : 'C',
+								style : 'width:50px',
+								validate: function()
+								{
+									var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
+									return isValid = func.apply( this );
+								},
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'size' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'size', this.getValue() );
+								}
+							},
+							{
+								id : 'txtMaxChars',
+								type : 'text',
+								label : editor.lang.textfield.maxChars,
+								'default' : '',
+								accessKey : 'M',
+								style : 'width:50px',
+								validate: function()
+								{
+									var func = CKEDITOR.dialog.validate.integer( editor.lang.common.validateNumberFailed );
+									return isValid = func.apply( this );
+								},
+								setup : function( element )
+								{
+									this.setValue( element.getAttribute( 'maxlength' ) );
+								},
+								commit : function( element )
+								{
+									if ( this.getValue() != '' || this.isChanged() )
+										element.setAttribute( 'maxlength', this.getValue() );
+								}
+							}
+						]
+					},
+					{
+						id : 'cmbType',
+						type : 'select',
+						label : editor.lang.textfield.type,
+						'default' : 'text',
+						accessKey : 'M',
+						items :
+						[
+							[ editor.lang.textfield.typeText, 'text' ],
+							[ editor.lang.textfield.typePass, 'pass' ],
+						],
+						setup : function( element )
+						{
+							this.setValue( element.getAttribute( 'type' ) );
+						},
+						commit : function( element )
+						{
+							element.setAttribute( 'type', this.getValue() );
+						}
+					}
+				]
+			}
+		]
+	};
+});
Index: /CKEditor/trunk/_source/plugins/forms/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/forms/plugin.js	(revision 3114)
+++ /CKEditor/trunk/_source/plugins/forms/plugin.js	(revision 3114)
@@ -0,0 +1,47 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/**
+ * @file Forms Plugin
+ */
+
+CKEDITOR.plugins.add( 'forms',
+{
+	init : function( editor )
+	{
+		editor.addCss(
+			'form' +
+			'{' +
+				'border: 1px dotted #FF0000;' +
+				'padding: 2px;' +
+			'}' );
+		// All buttons use the same code to register. So, to avoid
+		// duplications, let's use this tool function.
+		var addButtonCommand = function( buttonName, commandName, dialogFile )
+		{
+			editor.addCommand( commandName, new CKEDITOR.dialogCommand( commandName ) );
+
+			editor.ui.addButton( buttonName,
+				{
+					label : editor.lang.common[ commandName ],
+					command : commandName
+				});
+			CKEDITOR.dialog.add( commandName, dialogFile );
+		};
+
+		var dialogPath = this.path + 'dialogs/';
+		addButtonCommand( 'Form',			'form',			dialogPath + 'form.js' );
+		addButtonCommand( 'Checkbox',		'checkbox',		dialogPath + 'checkbox.js' );
+		addButtonCommand( 'Radio',			'radio',		dialogPath + 'radio.js' );
+		addButtonCommand( 'TextField',		'textfield',	dialogPath + 'textfield.js' );
+		addButtonCommand( 'Textarea',		'textarea',		dialogPath + 'textarea.js' );
+		addButtonCommand( 'Select',			'select',		dialogPath + 'select.js' );
+		addButtonCommand( 'Button',			'button',		dialogPath + 'button.js' );
+		addButtonCommand( 'ImageButton',	'imagebutton',	CKEDITOR.plugins.getPath('image') + 'dialogs/image.js' );
+		addButtonCommand( 'HiddenField',	'hiddenfield',	dialogPath + 'hiddenfield.js' );
+
+	},
+	requires : [ 'image' ]
+} );
Index: /CKEditor/trunk/_source/plugins/toolbar/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/toolbar/plugin.js	(revision 3113)
+++ /CKEditor/trunk/_source/plugins/toolbar/plugin.js	(revision 3114)
@@ -212,4 +212,5 @@
 		'Undo', 'Redo', '-',
 		'Find', 'Replace', '-',
+		'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField', '-',
 		'Bold', 'Italic', 'Underline', 'Strike', '-',
 		'NumberedList', 'BulletedList', '-',
