### Eclipse Workspace Patch 1.0
#P relativity
Index: relativity.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/relativity/relativity.module,v
retrieving revision 1.49
diff -u -r1.49 relativity.module
--- relativity.module	12 Jan 2008 02:27:19 -0000	1.49
+++ relativity.module	29 Jun 2008 14:49:12 -0000
@@ -47,11 +47,16 @@
  *   with various filters for restricting what is seen.  Someday, maybe :)
  *   javanaut
  */
-function relativity_list_possible_children($type='', $parent_nid='') {
+function relativity_list_possible_children($type='', $parent_nid='', $is_autocomplete=false, $part) {
   if (!$type && !$parent_nid) {
     $type = arg(2);
     $parent_nid = is_numeric(arg(4)) ? arg(4) : $_GET['parent_node'] + 0;
   }
+  if($is_autocomplete == true){
+    $part = "%%$part%%";
+  } else {
+    $is_autocomplete = false;
+  }
   
   $links = array();
   $parent = node_load($parent_nid);
@@ -85,11 +90,19 @@
     }
     
     $use_taxonomy = variable_get('relativity_use_taxonomy', 0);
+    $sql = '';
     if ($use_taxonomy) {
-      $result = db_query('SELECT DISTINCT n.nid, t.tid, v.vid FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid INNER JOIN {term_data} v ON t.tid = v.tid WHERE n.type = \'%s\' AND n.status = 1 ORDER BY v.vid, t.tid', $type);
+      $sql = 'SELECT DISTINCT n.nid, t.tid, v.vid FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid INNER JOIN {term_data} v ON t.tid = v.tid WHERE n.type = \'%s\' AND n.status = 1 '. ($is_autocomplete?' AND n.title LIKE \'%s\' ':'').'ORDER BY v.vid, t.tid';
     } else {
-      $result = db_query('SELECT n.nid FROM {node} n WHERE n.type = \'%s\' AND n.status = 1 ORDER BY n.title', $type);
+      $sql = 'SELECT n.nid FROM {node} n WHERE n.type = \'%s\' AND n.status = 1 '. ($is_autocomplete?' AND n.title LIKE \'%s\' ':'').'ORDER BY n.title';
     }
+    
+    if ($is_autocomplete) {
+      $result = db_query($sql, $type, $part);
+    } else {
+      $result = db_query($sql, $type);
+    }
+    
   }
   
   while($child = db_fetch_object($result)) {
@@ -107,13 +120,26 @@
               $key .= $parent_tree[$i]->tid.';';
             }
           }
-          $links[$key][] = array('title' => $child_node->title, 'child_node' => $child_node->nid, 'parent_node' => $parent_nid);
+          if ($is_autocomplete === false) {
+            $links[$key][] = array('title' => $child_node->title, 'child_node' => $child_node->nid, 'parent_node' => $parent_nid);
+          } else {
+            $links[$child_node->title.' [nid:' . $child_node->nid . ']'] = check_plain($child_node->title);
+          }
         } else {
-          $links[] = theme('relativity_link', $child_node->title, "addparent/$child_node->nid/parent/$parent_nid", $parent_nid);
+          if ($is_autocomplete === false) {
+            $links[] = theme('relativity_link', $child_node->title, "addparent/$child_node->nid/parent/$parent_nid", $parent_nid);
+          } else {
+            $links[$child_node->title.' [nid:' . $child_node->nid . ']'] = check_plain($child_node->title);
+          }
         }
       }
   } 
   
+  if($is_autocomplete !== false){
+    print drupal_to_js($links);
+    exit();
+  }
+  
   if (count($links)) {
     if ($use_taxonomy) {
       print(theme('page', drupal_get_form('relativity_taxonomy_form', $links) ));
@@ -299,6 +325,7 @@
 
       $items[] = array('path' => 'relativity/listnodes/'. arg(2).'/parent/'.arg(4), 'title' => t('list of !type nodes to attach', array('!type'=>node_get_types('name',arg(2)))),
         'callback' => 'relativity_list_possible_children',
+        'callback arguments' => array('','',arg(5),arg(6)),
         'access' => node_access('update', node_load(arg(4))) && user_access("access content"),
         'type' => MENU_CALLBACK
         );
@@ -482,11 +509,6 @@
     '#description' => t('If checked, nodes cannot be created without a parent if they require a parent to exist.'),
   );
 
-  // Node Sorting Options
-  $group['sorting_options'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Node Sorting Options'),
-  );
 
   $group['global_options']['relativity_use_taxonomy'] = array(
     '#type' => 'checkbox',
@@ -495,6 +517,23 @@
     '#default_value' => variable_get('relativity_use_taxonomy', 0),
     '#description' => t('If checked, nodes cannot be attached if they don\'t belong to a taxonomy term. When listing nodes to attach, possible children will be displayed in a taxonomy	tree.'),
   );
+  
+  $group['global_options']['relativity_select_method'] = array(
+    '#type' => 'radios',
+    '#title' => t('How should nodes be selected?'),
+    '#return_value' => 1,
+    '#default_value' => variable_get('relativity_select_method', t('Both')),
+  	'#options' => array(t('List') => t('List'), t('Autocomplete') => t('Autocomplete'), t('Both') => t('Both')),
+    '#description' => '<ul><li>'. t('List') . t(' : A link to a paged list of nodes') .'</li>'
+                      .'<li>'. t('Autocomplete') . t(' : A autocomplete form') .'</li>'
+                      .'<li>'. t('Both') . t(' : The two options together') .'</li>',
+  );
+  
+  // Node Sorting Options
+  $group['sorting_options'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Node Sorting Options'),
+  );
 
   // let admins specify sort order for node types
   $ntypes = count($allow_types);	
@@ -1569,11 +1608,26 @@
 
       // only show link to attach existing node when the potential child doesn't require a parent.
       if ((!relativity_requires_parent($type) || relativity_multi_parent($type)) && node_access('update', $parent)) {
-        if ($may_create) {      // If 'create' link is present ...
-          $output .= ' | ';      // insert a pipe separator between links
+        // If 'create' link is present ... insert a pipe separator between links
+        $list = ($may_create?' | ':'').l(t('Attach existing !type (from a list)', array('!type'=>$type_name)), "relativity/listnodes/$type/parent/$parent_nid", array('class' => 'relativity_attach_' . $type));
+        
+        switch (variable_get('relativity_select_method', t('Both'))) {
+        	case t('List'):
+        	  $output .= $list;
+        	break;
+        	
+        	case t('Autocomplete'):
+        	  $output .= drupal_get_form('relativity_autocomplete_child', array('type_name'=>$type_name, 'type'=>$type, 'parent_nid'=>$parent_nid));
+        	break;
+        	
+        	default:
+        	  $output .= $list;
+        	  $output .= '<br />';
+        	  $output .= drupal_get_form('relativity_autocomplete_child', array('type_name'=>$type_name, 'type'=>$type, 'parent_nid'=>$parent_nid));
+        	break; 
         }
-        $output .= l(t('Attach existing !type', array('!type'=>$type_name)), "relativity/listnodes/$type/parent/$parent_nid", array('class' => 'relativity_attach_' . $type));
-	$output .= "<br />\n";
+        
+	    $output .= "<br />\n";
       }
     }
   }
@@ -1615,6 +1669,75 @@
   return $output;
 }
 
+/**
+ * Defines a form for autocomplete_child.
+ *
+ */
+function relativity_autocomplete_child($details) {
+  $form['relativity_child_name'] = array(
+    '#title' => t('Attach existing !type (auto-complete)', array('!type'=>$details['type_name'])),
+    '#type' => 'textfield',
+    '#autocomplete_path' => 'relativity/listnodes/'.$details['type'].'/parent/'.$details['parent_nid'].'/true',
+    '#description' => t('Type the title of the !type', array('!type'=>$details['type_name']))
+  );
+  $form['relativity_child_type'] = array(
+    '#type' => 'hidden',
+    '#value'=> $details['child_type'],
+  );
+    $form['relativity_child_parent_nid'] = array(
+    '#type' => 'hidden',
+    '#value'=> $details['parent_nid'],
+  );
+  $form['relativity_submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit')
+  );
+  
+  return $form;
+}
+
+/**
+* Handle autocomplete_child form submission.
+*/
+function relativity_autocomplete_child_submit($form_id, $form_values) {
+  //extract nid if it exsists
+  preg_match('/\[nid:(\d*)]/', $form_values['relativity_child_name'], $matches);
+  if ( count($matches) > 1 ) {
+    $nid = $matches[1]; 
+  }
+  else { //no NID set, so try to grab it
+    $node_title = $form_values['relativity_child_name'];
+    $result = db_query("SELECT nid FROM {node} WHERE LOWER(title) LIKE LOWER('%s%%')", $node_title, 0, 10);
+    
+    if (db_num_rows($result) == 1) {
+      $nid = db_result($result);
+    } 
+    else if (db_num_rows($result) > 1) { //too many results
+      $error = t('More than one %type has the title "%title", please select the required node from !link', 
+        array( 
+        	'%type' => $form_values['relativity_child_type_name'],
+        	'%title' => $node_title, 
+        	'!link' => l('this list','relativity/listnodes/'. $form_values['relativity_child_type'] .'/parent/'. $form_values['relativity_child_parent_nid']))
+        );
+    }
+  }
+  
+  if (!$nid){
+    $error = t('No %type found with the title "%title"', 
+      array(
+      	'%type' => $form_values['relativity_child_type_name'],
+      	'%title' => $node_title 
+      )
+    );
+  }
+  
+  if ($error){
+    drupal_set_message($error, 'error');
+  } else {
+    drupal_goto('relativity/addparent/'.$nid.'/parent/'.$form_values['relativity_child_parent_nid']); 
+  }
+}
+
 
 /************************ Block themes ***********************/
 
