Index: image_attach.css
===================================================================
RCS file: /cvs/drupal/contributions/modules/image/contrib/image_attach/image_attach.css,v
retrieving revision 1.1
diff -u -r1.1 image_attach.css
--- image_attach.css	7 May 2006 00:54:00 -0000	1.1
+++ image_attach.css	2 Oct 2006 16:25:00 -0000
@@ -9,6 +9,46 @@
 .image-attach-preview {
   margin-bottom: 1em;
 }
+.image-attach-preview a {
+	display: block;
+}
 .node {
   clear: both;
+}
+#attach_image-wrapper {
+	padding: 5px;
+}
+#attach_image-wrapper .image-item {
+	float: left;
+	width: 170px;
+	height: 130px;
+	padding: 5px;
+	margin: 5px;
+	border: 1px solid #ccc;
+	position: relative;
+}
+#attach_image-wrapper .image-item .picture {
+	height: 106px;
+	text-align: center;
+	vertical-align: middle;
+}
+#attach_image-wrapper .image-item .form-radio {
+	position: absolute;
+	top: 0;
+	left: 0;
+}
+#attach_image-wrapper .image-item .form-textfield {
+	position: absolute;
+	left: 5px;
+	bottom: 5px;
+	width: 165px;
+	height: 14px;
+}
+#attach_image-hide {
+	float: left;
+	width: 100%;
+}
+#attach_image-wrapper #uploadprogress {
+	float: left;
+	clear: both;
 }
\ No newline at end of file
Index: image_attach.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/image/contrib/image_attach/image_attach.install,v
retrieving revision 1.1
diff -u -r1.1 image_attach.install
--- image_attach.install	3 May 2006 20:04:25 -0000	1.1
+++ image_attach.install	26 Oct 2006 15:24:00 -0000
@@ -11,14 +11,65 @@
   switch ($GLOBALS['db_type']) {
     case 'mysqli':
     case 'mysql':
-      db_query("
-CREATE TABLE {image_attach} (
-  nid int(10) unsigned NOT NULL default '0',
-  iid int(10) unsigned NOT NULL default '0',
-  PRIMARY KEY  (nid)
-) TYPE=MyISAM
-/*!40100 DEFAULT CHARACTER SET utf8 */;");
+			// modified the original database to accommodate multiple images per node.
+			// drop the old table if it happens to be present (just incase).
+			db_query("CREATE TABLE {image_attach} (
+									nid int(10) unsigned NOT NULL default '0',
+                  vid int(10) unsigned NOT NULL default '0',
+									iid int(10) unsigned NOT NULL default '0',
+									PRIMARY KEY  (vid, iid)
+								) TYPE=MyISAM;
+			");
       break;
   }
   
+}
+
+function image_attach_update_1() {
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      // Save data in a temp table for later reconstruction, and empty the table
+      $ret[] = update_sql( "
+        CREATE TEMPORARY TABLE {tmp_image_attach} (
+          nid int(10) unsigned, 
+          iid int(10) unsigned
+        );" );
+      $ret[] = update_sql( "
+        INSERT INTO {tmp_image_attach}
+          SELECT nid, iid FROM {image_attach};
+        " );
+      $ret[] = update_sql( "
+        DELETE FROM {image_attach};
+        " );
+
+      // add `vid` column to the table, recreate primary key and add a second index
+      $ret[] = update_sql( "
+        ALTER TABLE {image_attach}
+          ADD COLUMN `vid` int(10) unsigned NOT NULL default '0' AFTER `nid`,
+          DROP PRIMARY KEY,
+          ADD PRIMARY KEY (vid, iid),
+          ADD INDEX `nid_iid` (nid, iid);
+        " );
+
+      // reconstruction of the image_attach table.
+/*
+      // OPTION 1: Attach images to the current node revision only
+      $ret[] = update_sql( "
+        INSERT INTO {image_attach} (nid, vid, iid)
+          SELECT tmp.nid, n.vid, tmp.iid
+          FROM {tmp_image_attach} tmp INNER JOIN {node} n ON n.nid = tmp.nid;
+        " );
+*/
+      // OPTION 2: Attach images to all node revisions
+      $ret[] = update_sql( "
+        INSERT INTO {image_attach} (nid, vid, iid)
+          SELECT tmp.nid, r.vid, tmp.iid
+          FROM {tmp_image_attach} tmp INNER JOIN {node_revisions} r ON r.nid = tmp.nid;
+        " );
+        
+      break;
+  }
+
+  return $ret;
 }
\ No newline at end of file
Index: image_attach.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/image/contrib/image_attach/image_attach.module,v
retrieving revision 1.7
diff -u -r1.7 image_attach.module
--- image_attach.module	20 Nov 2006 04:54:28 -0000	1.7
+++ image_attach.module	20 Nov 2006 18:28:50 -0000
@@ -1,10 +1,26 @@
 <?php
-// $Id: image_attach.module,v 1.7 2006/11/20 04:54:28 walkah Exp $
+// $Id: image_attach.module,v 1.6 2006/10/25 14:03:04 walkah Exp $
 
 /**
  * @file image_attach.module
  */
 
+/*
+** Modified by Marty Zalega (evil.marty-#AT#-gmail.com) 2006/10/03
+** 
+** I've modified the source to allow uploading of multiple images using Drupal's
+** upload mechanism. It works the same way as the file attachment module where if
+** the node is not saved then any attachments that were uploaded during that edit
+** will be deleted and no changes made.
+**
+** Still some issues with deleting images after an edit cancellation that it
+** displays a message that the node was deleted.
+**
+** Enjoy. Let me know if any issues arise =)
+**
+** TODO: Allow attaching of other images.
+*/
+
 /**
  * Implementation of hook_help().
  */
@@ -17,175 +33,373 @@
 }
 
 /**
- * Implementation of hook_menu()
+ * Implementation of hook_menu().
  */
 function image_attach_menu($may_cache) {
   $items = array();
 
   if ($may_cache) {
-      $items[] = array('path' => 'image_attach',
-                       'title' => t('Image Attachment View'),
-                       'callback' => 'image_attach_view_image',
-                       'access' => user_access('access content'),
-                       'type' => MENU_CALLBACK);
-      $items[] = array('path' => 'admin/settings/image_attach',
-                       'title' => t('Image attach'),
-                       'description' => t('Enable image attach for content'),
-                       'callback' => 'drupal_get_form',
-                       'callback arguments' => array('image_attach_admin_settings'),
-                       'access' => user_access('administer site configuration'),
-                       'type' => MENU_NORMAL_ITEM);
+    $items[] = array(
+      'path' => 'upload/image_js',
+      'callback' => 'image_attach_js',
+      'access' => user_access('create images'),
+      'type' => MENU_CALLBACK
+    );
   }
+
   return $items;
 }
 
 
-function image_attach_admin_settings() {
-  $form = array();
-  
-  $form['image_attach_existing'] = array(
-    '#type' => 'radios',
-    '#title' => t('Attach existing images'),
-    '#default_value' => variable_get('image_attach_existing', 1),
-    '#options' => array(0 => 'Disabled', 1 => 'Enabled'),
-    '#description' => t('When enabled, will allow existing image nodes to be attached instead of uploading new images.')
-  );
-  
-  return system_settings_form($form);
-}
-
 /**
  * implementation of hook_form_alter()
  */
 function image_attach_form_alter($form_id, &$form) {
-  if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
-    if(function_exists('_image_check_settings')){
-      _image_check_settings();
-      $form['workflow']['image_attach'] = array(
-        '#type' => 'radios',
-        '#title' => t('Attach Images'),
-        '#default_value' => variable_get('image_attach_'. $form['identity']['type']['default_value'], 1),
-        '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
-        '#description' => t('Should this node allows users to upload an image?'),
-        );
-      
-    }
+  if (!isset($form['type']) || $form['type'] == 'image') {
+    return;
   }
-
   // Make a copy of the type to shorten up the code
-  if (isset($form['type'])) {
-    $node = $form['#node'];
-    // if enabled adjust the form
-    if ($form_id ==  $form['type']['#value'].'_node_form' && variable_get('image_attach_'.$node->type, 0)) {
-      _image_check_settings();
-      $existing = variable_get('image_attach_existing', 1);
-      $value = ($node->new_image) ? '#value' : '#default_value';
-      $form['#attributes'] = array("enctype" => "multipart/form-data");
-      
-      $form['image_attach'] = array(
-        '#type' => 'fieldset', 
-        '#title' => t('Attached Images'), 
-        '#collapsible' => TRUE, 
-        '#collapsed' => !$node->iid
+  $type =  $form['type']['#value'];
+
+  $upload = variable_get('image_attach_'. $type .'_upload', 0);
+  $existing = variable_get('image_attach_'. $type .'_existing', 0);
+  $enabled = $existing || $upload;
+
+  switch ($form_id) {
+     
+    // checkbox in the node's content type configuration page.
+    case $type .'_node_settings':
+      if (function_exists('_image_check_settings')){
+          _image_check_settings();
+        $form['workflow']['image_attach_'. $type .'_upload'] = array(
+          '#type' => 'radios',
+          '#title' => t('Attach uploaded images'),
+          '#default_value' => $upload,
+          '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
+          '#description' => t('Should this node allows users to attach uploaded images?'),
         );
-      if ($node->iid) {
-        $image = node_load($node->iid);
-        $form['image_attach']['image_thumbnail'] = array(
-          '#type' => 'item', 
-          '#title' => t('Thumbnail'), 
-          '#value' => image_display($image, 'thumbnail')
-          );
+        $form['workflow']['image_attach_'. $type .'_existing'] = array(
+          '#type' => 'radios',
+          '#title' => t('Attach existing images'),
+          '#default_value' => $existing,
+          '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
+          '#description' => t('Should this node allows users to attach existing images?'),
+        );
+      } else {
+        drupal_set_message(t('The image module is not installed. The image_attach module will not function without it.'), 'error');
       }
-      if ($existing && user_access('access content')) {         
-        $form['image_attach']['iid'] = array(
-          '#type' => 'select', 
-          '#title' => t('Existing Image'), 
-          '#options' => _image_attach_get_image_nodes(),
-          $value => $node->iid,
-          '#description' => t('Choose an image already existing on the server if you do not upload a new one.')
-          );
-        $form['image_attach'][] = array(
-          '#type' => 'item',
-          '#value' => t('-or-'),
-          '#attributes' => array('class' => 'either-choice')
-          );
-        }
-      else {
-        $form['image_attach']['iid'] = array(
-          '#type' => 'hidden',
-          '#value' => $node->iid
-          );
+      break;
+
+    // if enabled adjust the form
+    case $type .'_node_form':
+      if ($enabled && function_exists('_image_check_settings')) {
+				_image_check_settings();
+        $node = $form['#node'];
+				
+				drupal_add_js('misc/progress.js');
+				drupal_add_js('misc/upload.js');
+	
+				// Attachments fieldset
+				$form['image_attach'] = array(
+					'#type' => 'fieldset',
+					'#title' => t('Attached Images'),
+					'#collapsible' => TRUE,
+					'#collapsed' => empty($node->images),
+					'#description' => t('Changes made to the attachments are not permanent until you save this post. The first "listed" image will be included in RSS feeds.'),
+					'#prefix' => '<div class="attachments">',
+					'#suffix' => '</div>',
+					'#weight' => 30,
+				);
+	
+				// Wrapper for fieldset contents (used by upload JS).
+				$form['image_attach']['wrapper'] = array(
+					'#prefix' => '<div id="attach_image-wrapper">',
+					'#suffix' => '</div>',
+				);
+				$form['image_attach']['wrapper'] += _image_attach_form($node, $upload, $existing);
+				$form['#attributes']['enctype'] = 'multipart/form-data';
       }
-      $form['image_attach']['image'] = array(
-        '#type' => 'file',
-        '#title' => t('Upload Image')
+      break;
+  }
+}
+
+function _image_attach_form($node, $upload, $existing) {
+  $form['#theme'] = 'image_attach_form_new';
+
+  if (count($node->images)) {
+    $form['images']['#theme'] = 'image_attach_form_current';
+    $form['images']['#tree'] = TRUE;
+    foreach ($node->images as $iid => $image) {
+      $description = file_create_url($image->images['_original']);
+      $description = "<small>". check_plain($description) ."</small>";
+      $form['images'][$iid]['title'] = array('#type' => 'textfield', '#default_value' => (strlen($image->title)) ? $image->title : $image->images['_original'], '#maxlength' => 256, '#description' => $description );
+			if ($group = image_display($image, 'thumbnail'))
+				$form['images'][$iid]['thumbnail'] = array('#type' => 'markup', '#value' => $group);
+			
+			if (file_exists($image->images['_original']))
+				$filesize = filesize($image->images['_original']);
+			else
+				$filesize = filesize(file_directory_path() . '/' . $image->images['_original']);
+			
+      $form['images'][$iid]['size'] = array('#type' => 'markup', '#value' => format_size($filesize));
+      $form['images'][$iid]['remove'] = array('#type' => 'checkbox', '#default_value' => $image->remove);
+      $form['images'][$iid]['filepath'] = array('#type' => 'value',  '#value' => $image->images['_original']);
+      $form['images'][$iid]['filesize'] = array('#type' => 'value',  '#value' => $filesize);
+      $form['images'][$iid]['nid'] = array('#type' => 'value',  '#value' => $image->nid);
+    }
+  }
+
+  $upload = user_access('create images') && $upload;
+  $existing = user_access('access content') && $existing;
+
+  
+  if ($upload || $existing) {
+    // This div is hidden when the user uploads through JS.
+    $form['new'] = array(
+      '#prefix' => '<div id="attach_image-hide">',
+      '#suffix' => '</div>',
+      );
+    $form['new']['image_attach_node_type'] = array(
+      '#type' => 'hidden', 
+      '#value' => $node->type
+      );
+
+    if ($existing) {   
+      // The existing image chooser      
+      $form['new']['iid'] = array(
+        '#type' => 'select', 
+        '#title' => t('Attach an existing Image'), 
+        '#options' => _image_attach_get_image_nodes(),
+        '#description' => t('Choose an image already existing on the server and attach it.')
         );
-      $form['image_attach']['image_title'] = array(
+    }
+  
+    if ($existing && $upload) {
+      $form['new']['or'] = array(
+        '#type' => 'item',
+        '#value' => t('-or-'),
+        '#attributes' => array('class' => 'either-choice')
+        );
+    }
+
+    if ($upload) {
+      // The upload file name field
+      $form['new']['image'] = array(
+        '#type' => 'file', 
+        '#title' => t('Upload and attach new image'), 
+        '#size' => 40,
+        '#description' => t('Upload a new image and attach it.')
+        );
+      $form['new']['image_title'] = array(
         '#type' => 'textfield', 
         '#title' => t('Image title'),
         $value => '',
         '#description' => t('The title the image will be shown with.')
         );        
     }
+
+    // The submit button
+    $form['new']['attach_image'] = array(
+      '#type' => 'button', 
+      '#value' => t('Attach'), 
+      '#name'=> 'attach_image', 
+      '#attributes' => array('id' => 'attach_image')
+      );
+    // The class triggers the js upload behaviour.
+    $form['attach_image'] = array(
+      '#type' => 'hidden', 
+      '#value' => url('upload/image_js', NULL, NULL, TRUE), 
+      '#attributes' => array('class' => 'upload')
+      );
+    // Needed for JS
+    $form['current']['vid'] = array(
+      '#type' => 'hidden', 
+      '#value' => $node->vid
+      );
   }
+  
+  return $form;
 }
 
 /**
- * Implementation of hook_nodeapi().
- */
-function image_attach_nodeapi(&$node, $op, $teaser, $page) {
-  if(variable_get('image_attach_'. $node->type, 0) == 0){
-      return;
+* Implementation of hook_nodeapi().
+*/
+function image_attach_nodeapi(&$node, $op, $teaser = FALSE, $page = FALSE) {
+  $upload = variable_get('image_attach_'. $node->type .'_upload', 0);
+  $existing = variable_get('image_attach_'. $node->type .'_existing', 0);
+
+  if ($upload == 0 && $existing == 0) {
+  	return;
   }
   switch ($op) {
+		case 'validate':
+      _image_attach_validate($node);
+      break;
     case 'prepare':
-      $image->title = $_POST['edit']['image_title'];
-      $image->uid = $node->uid;
-      $image->name = $node->name;
-      $image->created = $node->created;
-      $image->type = 'image';
-      image_prepare($image, 'image');
-      if ($image->images) {
-        node_validate($image);
-        if (!form_get_errors()) {
-          $image = node_submit($image);
-          node_save($image);
-          $node->iid = $image->nid;
-          $node->new_image = TRUE;
-        }
-      }
-      elseif (variable_get('image_attach_existing', 1) && $_POST['edit']['iid']) {
-        $node->iid = $_POST['edit']['iid'];
-      }
+			_image_attach_prepare($node, $upload, $existing);
       break;
     case 'insert':
     case 'update':
-      if ($node->iid) {
-        db_query("DELETE FROM {image_attach} WHERE nid=%d", $node->nid);
-        db_query("INSERT INTO {image_attach} (nid, iid) VALUES (%d, %d)", $node->nid, $node->iid);
-      }
+      _image_attach_save($node);
       break;
     case 'delete':
-      db_query("DELETE FROM {image_attach} WHERE nid=%d", $node->nid);
+      _image_attach_delete($node);
+      break;
+    case 'delete revision':
+      _image_attach_delete_revision($node);
       break;
     case 'load':
-      $iid = db_result(db_query("SELECT iid FROM {image_attach} WHERE nid=%d", $node->nid));
-      return array('iid' => $iid);
+      return array('images' => _image_attach_load($node));
+      break;
      
     // Pass the body and teaser objects to the theme again to add the images
     case 'view':
-      if($node->iid && function_exists('image_display')){
-        if ($teaser) {
-          $node->content['image_attach'] = array(
-            '#value' => theme('image_attach_teaser', $node)
-            );
+      if (count($node->images) && function_exists('image_display')){
+        if ($teaser){
+          $node->teaser = theme('image_attach_teaser', $node) . $node->teaser;
+        } else {
+          $node->body = theme('image_attach_body', $node) . $node->body;
+        }
+      }
+			break;
+
+  }
+  
+}
+
+function _image_attach_validate(&$node) {
+}
+
+function _image_attach_prepare(&$node, $upload, $existing) {
+  global $user;
+  
+	if(count($_POST) == 0) {
+		if (is_array($_SESSION['image_attach_uploaded']) && count($_SESSION['image_attach_uploaded'])) {
+			foreach($_SESSION['image_attach_uploaded'] as $iid => $image) {
+				node_delete($iid);
+			}
+			unset($_SESSION['image_attach_uploaded']);
+			unset($_SESSION['image_attach_existing']);
+		}
+	}
+	
+	unset($_SESSION['image_attach_current_upload']);
+	if ($upload && ($file = file_check_upload('image'))) {
+		$image->uid = $user->uid;
+		$image->name = $user->name;
+		$image->type = 'image';
+    
+    node_object_prepare($image, 'image');
+		if ($image->images) {
+			$image->title = trim($node->image_title) ? $node->image_title : $file->filename;
+			node_validate($image);
+			if (!form_get_errors()) {
+				$image = node_submit($image);
+				node_save($image);
+				//$image->new_image = TRUE;
+				$_SESSION['image_attach_uploaded'][$image->nid] = $image;
+				$_SESSION['image_attach_current_upload'] = $image->nid;
+			}
+		}
+	}
+
+  // Attach image previews to node object.
+	if (is_array($_SESSION['image_attach_uploaded']) && count($_SESSION['image_attach_uploaded'])) {
+		foreach($_SESSION['image_attach_uploaded'] as $iid => $image) {
+      $node->images[$iid] = $image;
+		}
+	}
+
+	if ($existing && ($iid = $_POST['edit']['iid'])) {
+    $image = node_load($iid);
+    
+    // Check if we really loaded an image
+    if ($image->nid && $image->type == 'image') {
+      $_SESSION['image_attach_existing'][$image->nid] = $image;
+    } else {
+      drupal_set_message(t('Attached image with node id %iid not found', array('%iid' => $iid)));
+    }
+	}
+
+  // Attach image previews to node object.
+	if (is_array($_SESSION['image_attach_existing']) && count($_SESSION['image_attach_existing'])) {
+		foreach($_SESSION['image_attach_existing'] as $iid => $image) {
+      $node->images[$iid] = $image;
+		}
+	}
+
+}
+
+function _image_attach_load($node) {
+	$images = array();
+			
+	$result = db_query("SELECT n.* FROM {image_attach} a, {node} n WHERE a.iid = n.nid AND a.vid = %d AND n.type = 'image'", $node->vid);
+	while ($row = db_fetch_object($result)) {
+		if ($image = node_load($row->nid)) {
+      $images[$row->nid] = $image;
+    }
+	}
+	
+	return $images;
+}
+
+function _image_attach_save($node) {
+  if (is_array($node->images)) {
+    foreach ($node->images as $iid => $image) {
+		  $image = (object)$image;
+					
+			if ($image->remove) {
+				db_query("DELETE FROM {image_attach} WHERE vid = %d AND iid = %d", $node->vid, $image->nid);
+        // Check if image is uses in other releases, before deleting it
+        if (!db_num_rows(db_query('SELECT * FROM {image_attach} WHERE iid = %d', $image->nid))) {
+   				node_delete($image->nid);
         }
+			}
+			else {
+				if (!db_num_rows(db_query('SELECT * FROM {image_attach} WHERE vid = %d AND iid = %d', $node->vid, $image->nid))) {
+					db_query("INSERT INTO {image_attach} (nid, vid, iid) VALUES (%d, %d, %d)", $node->nid, $node->vid, $image->nid);
+        } 
         else {
-          $node->content['image_attach'] = array(
-            '#value' => theme('image_attach_body', $node)
-            );
+          db_query("UPDATE {node} SET title = '%s' WHERE nid = %d", $image->title, $image->nid);
         }
-      }
+			}
+
+      // remove it from previews, as it is processed.
+      unset($_SESSION['image_attach_uploaded'][$image->nid]);
+      unset($_SESSION['image_attach_existing'][$image->nid]);
+		}
+  }
+}
+
+function _image_attach_delete($node) {
+  $images = array();
+  $result = db_query('SELECT DISTINCT iid FROM {image_attach} WHERE nid = %d', $node->nid);
+  while ($row = db_fetch_object($result)) {
+    $images[] = $row->iid;
+  }
+
+  foreach ($images as $iid) {
+	  db_query("DELETE FROM {image_attach} WHERE nid = %d AND iid = %d", $node->nid, $iid);
+    node_delete($iid);
+  }
+}
+
+
+function _image_attach_delete_revision($node) {
+  $images = array();
+  $result = db_query('SELECT iid FROM {image_attach} WHERE vid = %d', $node->vid);
+  while ($row = db_fetch_object($result)) {
+    $images[] = $row->iid;
+  }
+
+  foreach ($images as $iid) {
+	  db_query("DELETE FROM {image_attach} WHERE vid = %d AND iid = %d", $node->vid, $iid);
+
+    // Check if image is still uses in other releases, before deleting it
+    $result = db_query('SELECT vid FROM {image_attach} WHERE nid = %d AND iid = %d', $node->nid, $iid);
+    if (!db_num_rows($result)) {
+      node_delete($iid);
+    }
   }
 }
 
@@ -205,6 +419,7 @@
   return $rows;
 }
 
+
 /**
  * Theme the teaser.
  *
@@ -212,15 +427,16 @@
  * If you have additional image sizes you defined in image.module, you can use them by theming this function as well.
  */
 function theme_image_attach_teaser($node){
-  drupal_add_css(drupal_get_path('module', 'image_attach') .'/image_attach.css');
-
-  $image = node_load($node->iid);
+  theme_add_style(drupal_get_path('module', 'image_attach') .'/image_attach.css');
 
+  $image = array_shift($node->images);
+  
   $info = image_get_info(file_create_path($image->images['thumbnail']));
   $output = '';
   $output .= '<div style="width: '. $info['width'] .'px" class="image-attach-teaser">';
+  $output .= '<div class="image-attach-image">';
   $output .= l(image_display($image, 'thumbnail'), "node/$node->nid", array(), NULL, NULL, FALSE, TRUE);
-  $output .= '</div>'."\n";
+  $output .= '</div></div>'."\n";
   return $output;
 }
 
@@ -228,15 +444,88 @@
  * Theme the body
  */
 function theme_image_attach_body($node){
-  drupal_add_css(drupal_get_path('module', 'image_attach') .'/image_attach.css');
+  theme_add_style(drupal_get_path('module', 'image_attach') .'/image_attach.css');
+	
+	$max_width = 0;
+	$images = array();
+	foreach ($node->images as $image) {
+		$info = image_get_info(file_create_path($image->images['thumbnail']));
+		$max_width = max($max_width, $info['width']);
+		
+		$images[] = '<div class="image-attach-image">'.l(image_display($image, 'thumbnail'), "node/$image->nid", array('title' => t('Click to see larger image')), NULL, NULL, FALSE, TRUE).'</div>';
+	}
+	$output = '<div style="width: '. $max_width .'px" class="image-attach-body">' . implode("\n", $images) . "</div>\n";
+  return $output;
+}
 
-  $image = node_load($node->iid);
-  
-  $info = image_get_info(file_create_path($image->images['thumbnail']));
-  $output = '';
-  $output .= '<div style="width: '. $info['width'] .'px" class="image-attach-body">';
-  $output .= l(image_display($image, 'thumbnail'), "node/$node->nid", array(), NULL, NULL, FALSE, TRUE);
-  $output .= '</div>'."\n";
+function theme_image_attach_form_current(&$form) {
+	theme_add_style(drupal_get_path('module', 'image_attach') .'/image_attach.css');
+	$output = '';
+	foreach (element_children($form) as $key) {
+		$form[$key]['remove']['#printed'] = $form[$key]['title']['#printed'] = TRUE;
+		
+    $output .= '<div class="image-item">';
+		
+		if (strpos($form[$key]['remove']['#attributes']['class'], 'form-radio') === FALSE)
+			$form[$key]['remove']['#attributes']['class'] .= ' form-radio';
+		$output .= '<input type="checkbox" name="'. $form[$key]['remove']['#name'] .'" id="'. $form[$key]['remove']['#id'].'" value="'. $form[$key]['remove']['#return_value'] .'"'. ($form[$key]['remove']['#value'] ? ' checked="checked" ' : ' ') . drupal_attributes($form[$key]['remove']['#attributes']) .' />';
+		
+		$output .= '<div class="picture">'. form_render($form[$key]['thumbnail']) ."</div>\n";
+		
+		if (strpos($form[$key]['title']['#attributes']['class'], 'form-textfield') === FALSE)
+			$form[$key]['title']['#attributes']['class'] .= ' form-textfield';
+		$output .= '<input type="text" maxlength="'. $form[$key]['title']['#maxlength'] .'" name="'. $form[$key]['title']['#name'] .'" id="'. $form[$key]['title']['#id'] .'" value="'. check_plain($form[$key]['title']['#value']) .'"'. drupal_attributes($form[$key]['title']['#attributes']) .' />';
+		$output .= "</div>\n";
+  }
+	
   return $output;
 }
 
+function theme_image_attach_form_new($form) {
+	theme_add_style(drupal_get_path('module', 'image_attach') .'/image_attach.css');
+  $output = form_render($form);
+  return $output;
+}
+
+function image_attach_js() {
+  // We only do the upload.module part of the node validation process.
+  $node = (object)$_POST['edit'];
+  $node->type = $node->image_attach_node_type;
+
+  $upload = variable_get('image_attach_'. $node->type .'_upload', 0);
+  $existing = variable_get('image_attach_'. $node->type .'_existing', 0);
+  $enabled = $existing || $upload;
+
+  if ($enabled) {
+    // Load existing node files.
+    $node->images = _image_attach_load($node);
+
+    // Handle new uploads, and merge tmp files into node-files.
+    _image_attach_prepare($node, $upload && user_access('create images'), $existing && user_access('access content'));
+    _image_attach_validate($node);
+
+    // Preserve modifications
+    if (is_array($_POST['edit']['images'])) {
+      foreach ($_POST['edit']['images'] as $iid => $image) {
+        if (array_key_exists($iid, $node->images)) {
+          $node->images[$iid]->remove = $image['remove'];
+          $node->images[$iid]->title = $image['title'];
+        }
+      }
+    }
+
+    $form = _image_attach_form($node, $upload, $existing);
+  }
+  
+  foreach (module_implements('form_alter') as $module) {
+    $function = $module .'_form_alter';
+    $function('image_attach_js', $form);
+  }
+
+  $form = form_builder('image_attach_js', $form);
+  $output = theme('status_messages') . form_render($form);
+
+  // We send the updated file attachments form.
+  print drupal_to_js(array('status' => TRUE, 'data' => $output));
+  exit;
+}
\ No newline at end of file
Index: TODO.txt
===================================================================
RCS file: /cvs/drupal/contributions/modules/image/contrib/image_attach/TODO.txt,v
retrieving revision 1.1
diff -u -r1.1 TODO.txt
--- TODO.txt	3 May 2006 20:04:25 -0000	1.1
+++ TODO.txt	21 Nov 2006 11:34:07 -0000
@@ -1,3 +1,3 @@
-* support multiple images
+* support multiple images - done by Marty Zalega (evil.marty-#AT#-gmail.com)
 * allow selection of derivative to use (though this can be overriden by the theme)
-* allow for using already uploaded images?
+* allow for using already uploaded images - done by Danny van der Weide (dvdweide at dvdweide dot nl)
