Index: /CKEditor/branches/prototype/_source/plugins/image/dialogs/image.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/image/dialogs/image.js	(revision 2799)
+++ /CKEditor/branches/prototype/_source/plugins/image/dialogs/image.js	(revision 2800)
@@ -22,5 +22,5 @@
 imageDialog = function( editor, dialogType )
 {
-	var regexSize = /^\s*(\d+)px\s*$/i ;
+	var regexSize = /^\s*(\d+)(px)?\s*$/i;
 	var uploadAction = 'nowhere.php';
 	var imageDialog = ( dialogType == 'image' );
@@ -36,4 +36,136 @@
 		return false;
 	};
+
+	var onUrlChange = function( input )
+	{
+		var dialog = input.getDialog();
+		var editor = dialog.getParentEditor();
+
+		//Don't load before onShow.
+		if ( !dialog.allowOnChange )
+			return 0;
+
+		updateOriginal( dialog, true );
+		updatePreview( dialog );
+	}
+
+	var onSizeChange = function( input )
+	{
+		var dialog = input.getDialog();
+		var editor = dialog.getParentEditor();
+
+		//Don't load before onShow.
+		if ( !dialog.allowOnChange )
+			return 0;
+
+		// Only if ratio locked
+		if ( dialog.imageLockRatio )
+		{
+			var oImageOriginal = dialog.editObj[ 'imageOriginal' ];
+			if ( oImageOriginal && oImageOriginal.getCustomData( 'isReady' ) == 'true' )
+			{
+				var value = input.getValue();
+				if ( input.id == 'txtHeight' ){
+					dialog.allowOnChange = false;
+					if ( value != '' && value != 0 )
+						value = Math.round( oImageOriginal.$.height * ( value  / oImageOriginal.$.width ) );
+					// Image loaded but with unknow size.
+					if ( !isNaN( value ) )
+						dialog.setValueOf( 'info', 'txtWidth', value );
+					dialog.allowOnChange = true;
+				}
+				else		//input.id = txtWidth.
+				{
+					dialog.allowOnChange = false;
+					if ( value != '' && value != 0 )
+						value = Math.round( oImageOriginal.$.height * ( value  / oImageOriginal.$.width ) );
+					if ( !isNaN( value ) )
+						dialog.setValueOf( 'info', 'txtHeight', value );
+					dialog.allowOnChange = true;
+				}
+			}
+		}
+		updatePreview( dialog );
+	}
+
+	var updatePreview = function( dialog )
+	{
+		return 0;
+	}
+
+	var updateOriginal = function( dialog, forceResetSize )
+	{
+		var editor = dialog.getParentEditor();
+		var url = dialog.getContentElement( 'info', 'txtUrl' ).getValue()
+
+		dialog.editObj[ 'imageOriginal' ].setCustomData( 'isReady', 'false' );
+		if ( dialog.editObj && url.length>0 )
+		{
+			dialog.editObj[ 'imageOriginal' ].on( 'load', function()
+				{
+					//Image is ready.
+					this.editObj[ 'imageOriginal' ].setCustomData( 'isReady', 'true' );
+					this.editObj[ 'imageOriginal' ].removeListener( 'load' );
+					if ( forceResetSize ){
+						resetSize( this );
+					}
+				}, dialog );
+			dialog.editObj[ 'imageOriginal' ].setAttribute( 'src', url );
+		}
+	}
+
+	var switchLockRatio = function( dialog )
+	{
+		dialog.imageLockRatio = !dialog.imageLockRatio;
+		return 0;
+	}
+
+	var resetSize = function( dialog )
+	{
+		var oImageOriginal = dialog.editObj[ 'imageOriginal' ];
+		if ( oImageOriginal && oImageOriginal.getCustomData( 'isReady' ) == 'true' )
+		{
+			dialog.allowOnChange = false;
+			dialog.setValueOf( 'info', 'txtWidth', oImageOriginal.$.width );
+			dialog.setValueOf( 'info', 'txtHeight', oImageOriginal.$.height );
+			dialog.allowOnChange = true;
+		}
+		updatePreview( dialog );
+	}
+	var readSize = function( dialog )
+	{
+		var heightText = '';
+		var widthText = '';
+
+		// Read height.
+		if ( dialog.editObj[ 'image' ].getAttribute( 'height' ) )
+		{
+			var aMatchH  =  dialog.editObj[ 'image' ].getAttribute( 'height' ).match( regexSize );
+			if ( aMatchH )
+			{
+				dialog.imageDimenstions[ 'height' ] = aMatchH[1];
+				heightText = aMatchH[1];
+			}
+		}
+
+		// Read width.
+		if ( dialog.editObj[ 'image' ].getAttribute( 'width' ) )
+		{
+			var aMatchW  =  dialog.editObj[ 'image' ].getAttribute( 'width' ).match( regexSize );
+			if ( aMatchW )
+			{
+				dialog.imageDimenstions[ 'width' ] = aMatchW[1];
+				widthText = aMatchW[1];
+			}
+		}
+
+		//TODO: read styles
+		
+		var allow = dialog.allowOnChange;
+		dialog.allowOnChange = false;
+		dialog.setValueOf( 'info', 'txtHeight', heightText );
+		dialog.setValueOf( 'info', 'txtWidth', widthText );
+		dialog.allowOnChange = allow;
+	}
 
 	// Function called in onShow to load selected element.
@@ -43,5 +175,4 @@
 		this.editMode[ 'image' ] = false;		// Default:  Create a new Image
 		this.saveSelection();
-		//a=element;for(i in a){alert(i+'--'+a[i])}
 
 		this.setValueOf( "Link", "txtUrl", "" );
@@ -80,22 +211,25 @@
 				this.editObj[ 'image' ] = element;
 
+			updateOriginal( this, true );
+			readSize( this );
+
+			var imgObject = this.editObj[ 'image' ];
+			
 			// Fill out all fields.
-			if ( !readAttribute.apply( this, [ 'info', '_cke_saved_url', 'txtUrl' ] ) )
-				readAttribute.apply( this, [ 'info', 'src', 'txtUrl' ] )
-
-			readAttribute.apply( this, [ 'info', 'alt', 'txtAlt' ] );
-			readAttribute.apply( this, [ 'info', 'width', 'txtWidth' ] );
-			readAttribute.apply( this, [ 'info', 'height', 'txtHeight' ] );
-			readAttribute.apply( this, [ 'info', 'border', 'txtBorder' ] );
-			readAttribute.apply( this, [ 'info', 'hspace', 'txtHSpace' ] );
-			readAttribute.apply( this, [ 'info', 'vspace', 'txtVSpace' ] );
-			readAttribute.apply( this, [ 'info', 'align', 'cmbAlign' ] );
-			readAttribute.apply( this, [ 'advanced', 'id', 'linkId' ] );
-			readAttribute.apply( this, [ 'advanced', 'dir', 'cmbLangDir' ] );
-			readAttribute.apply( this, [ 'advanced', 'lang', 'txtLangCode' ] );
-			readAttribute.apply( this, [ 'advanced', 'longdesc', 'txtGenLongDescr' ] );
-			readAttribute.apply( this, [ 'advanced', 'class', 'txtGenClass' ] );
-			readAttribute.apply( this, [ 'advanced', 'style', 'txtdlgGenStyle' ] );	
-			readAttribute.apply( this, [ 'advanced', 'title', 'txtGenTitle' ] );
+			if ( !readAttribute.apply( this, [ 'info', '_cke_saved_url', 'txtUrl', imgObject ] ) )
+				readAttribute.apply( this, [ 'info', 'src', 'txtUrl', imgObject ] )
+	
+			readAttribute.apply( this, [ 'info', 'alt', 'txtAlt', imgObject ] );
+			readAttribute.apply( this, [ 'info', 'border', 'txtBorder', imgObject  ] );
+			readAttribute.apply( this, [ 'info', 'hspace', 'txtHSpace', imgObject ] );
+			readAttribute.apply( this, [ 'info', 'vspace', 'txtVSpace', imgObject ] );
+			readAttribute.apply( this, [ 'info', 'align', 'cmbAlign', imgObject ] );
+			readAttribute.apply( this, [ 'advanced', 'id', 'linkId', imgObject ] );
+			readAttribute.apply( this, [ 'advanced', 'dir', 'cmbLangDir', imgObject ] );
+			readAttribute.apply( this, [ 'advanced', 'lang', 'txtLangCode', imgObject ] );
+			readAttribute.apply( this, [ 'advanced', 'longdesc', 'txtGenLongDescr', imgObject ] );
+			readAttribute.apply( this, [ 'advanced', 'class', 'txtGenClass', imgObject ] );
+			readAttribute.apply( this, [ 'advanced', 'style', 'txtdlgGenStyle', imgObject ] );	
+			readAttribute.apply( this, [ 'advanced', 'title', 'txtGenTitle', imgObject ] );
 		}
 
@@ -105,7 +239,4 @@
 	var readAttribute = function( page, attribute, input, object )
 	{
-		if( !object )
-			object = this.editObj[ 'image' ];
-
 		var attributeValue = object.getAttribute( attribute );
 		if ( attributeValue == null )
@@ -121,6 +252,8 @@
 		minWidth : 450,
 		minHeight : 400,
-		onOk : function( data )
-		{
+		onOk : function()
+		{
+			this.allowOnChange = true;
+			
 			var useLink = false;
 			var removeObj = false;
@@ -211,20 +344,33 @@
 					this.editObj[ 'link' ].remove( true );
 			}
-	
+
+			this.allowOnChange = false;		// Don't load onChange before onShow.
+
 			return true;
 		},
 		onShow : function()
 		{
+			//Don't call onShow before onShow.
+			this.allowOnChange = false;
+
+			this.editObj = new Array();
+			this.editObj[ 'image' ] = false;
+			this.editObj[ 'link' ] = false;
+			this.editObj[ 'imageOriginal' ] = false;		//TODO: move it to preview area
+			
 			// Default: create a new element.
-			this.editObj = new Array();
-			
 			this.editMode = new Array();
 			this.editMode[ 'link' ] = false;
 			this.editMode[ 'image' ] = false;
-			
+
 			this.changedAttibutes = new Array();			
 			this.changedAttibutes[ 'link' ] = new Array();
 			this.changedAttibutes[ 'image' ] = new Array();
-			
+
+			this.imageDimenstions  = new Array ();
+			this.imageDimenstions['width'] = 0;
+			this.imageDimenstions['height'] = 0;
+			this.imageLockRatio = true;
+
 			// IE BUG: Selection must be in the editor for getSelection() to work.
 			this.restoreSelection();
@@ -234,4 +380,9 @@
 				ranges = selection.getRanges();
 
+			// Copy of the image
+			this.editObj[ 'imageOriginal' ] = editor.document.createElement( 'img' );
+			this.editObj[ 'imageOriginal' ].setCustomData( 'isReady', 'false' );
+			
+			
 			// Check selection. Fill in all the relevant fields if there's already one link selected.
 			if ( ranges.length == 1 )
@@ -263,4 +414,8 @@
 				}
 			}
+			updateOriginal( this, false );
+			updatePreview( this );
+
+			this.allowOnChange = true;
 
 			this.getContentElement( 'info', 'txtUrl' ).focus();
@@ -274,4 +429,12 @@
 				this.hidePage( 'Upload' );		//Hide Upload tab.
 		},	
+		onHide : function()
+		{
+			// Don't call onChange before onShow.
+			this.allowOnChange = false;
+
+			// Pop the default values from default value set that are pushed in onShow().
+			this.popDefault();
+		},
 		contents : [
 			{
@@ -305,4 +468,7 @@
 											addChange( '_cke_saved_url', this, 'image' );
 											return true;
+										},
+										onChange : function(){
+											onUrlChange( this );
 										}
 									},
@@ -315,5 +481,4 @@
 										{
 											this.getDialog().setValueOf( "info", "txtUrl", "http://www.fckeditor.net/images/demo_screenshot.gif" );
-											
 										}
 									}
@@ -358,4 +523,8 @@
 														labelLayout : 'horizontal',
 														label : editor.lang.dlgImgWidth,
+														onChange : function()
+														{
+															onSizeChange( this );
+														},
 														validate: function()
 														{
@@ -372,4 +541,8 @@
 														labelLayout : 'horizontal',
 														label : editor.lang.dlgImgHeight,
+														onChange : function()
+														{
+															onSizeChange( this );
+														},
 														validate: function()
 														{
