Index: modules/field/modules/number/number.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/number/number.module,v
retrieving revision 1.11
diff -u -r1.11 number.module
--- modules/field/modules/number/number.module	1 Aug 2009 06:03:12 -0000	1.11
+++ modules/field/modules/number/number.module	16 Aug 2009 00:27:36 -0000
@@ -88,6 +88,81 @@
 }
 
 /**
+ * Implement hook_field_settings_form().
+ */
+function number_field_settings_form($field, $instance) {
+  $settings = $field['settings'];
+  $form = array();
+
+  if ($field['type'] == 'number_decimal') {
+    $form['precision'] = array(
+      '#type' => 'select',
+      '#title' => t('Precision'),
+      '#options' => drupal_map_assoc(range(10, 32)),
+      '#default_value' => $settings['precision'],
+      '#description' => t('The total number of digits to store in the database, including those to the right of the decimal.'),
+    );
+    $form['scale'] = array(
+      '#type' => 'select',
+      '#title' => t('Scale'),
+      '#options' => drupal_map_assoc(range(0, 10)),
+      '#default_value' => $settings['scale'],
+      '#description' => t('The number of digits to the right of the decimal.'),
+    );
+    $form['decimal'] = array(
+      '#type' => 'select',
+      '#title' => t('Decimal marker'),
+      '#options' => array(
+        '.' => 'decimal point',
+        ',' => 'comma',
+        ' ' => 'space',
+      ),
+      '#default_value' => $settings['decimal'],
+      '#description' => t('The character users will input to mark the decimal point in forms.'),
+    );
+  }
+
+  return $form;
+}
+
+/**
+ * Implement hook_field_instance_settings_form().
+ */
+function number_field_instance_settings_form($field, $instance) {
+  $settings = $instance['settings'];
+
+  $form['min'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Minimum'),
+    '#default_value' => $settings['min'],
+    '#description' => t('The minimum value that should be allowed in this field. Leave blank for no minimum.'),
+    '#element_validate' => array('_element_validate_number'),
+  );
+  $form['max'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum'),
+    '#default_value' => $settings['max'],
+    '#description' => t('The maximum value that should be allowed in this field. Leave blank for no maximum.'),
+    '#element_validate' => array('_element_validate_number'),
+  );
+  $form['prefix'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Prefix'),
+    '#default_value' => $settings['prefix'],
+    '#size' => 60,
+    '#description' => t("Define a string that should be prefixed to the value, like '$ ' or '&euro; '. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
+  );
+  $form['suffix'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Suffix'),
+    '#default_value' => $settings['suffix'],
+    '#size' => 60,
+    '#description' => t("Define a string that should suffixed to the value, like ' m', ' kb/s'. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
+  );
+  return $form;
+}
+
+/**
  * Implement hook_field_validate().
  *
  * Possible error codes:
Index: modules/field/field.attach.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.attach.inc,v
retrieving revision 1.36
diff -u -r1.36 field.attach.inc
--- modules/field/field.attach.inc	13 Aug 2009 00:17:47 -0000	1.36
+++ modules/field/field.attach.inc	16 Aug 2009 00:27:36 -0000
@@ -457,6 +457,11 @@
 function field_attach_form($obj_type, $object, &$form, &$form_state) {
   $form += (array) _field_invoke_default('form', $obj_type, $object, $form, $form_state);
 
+  // Add custom weight handling.
+  list($id, $vid, $bundle) = field_attach_extract_ids($obj_type, $object);
+  $form['#pre_render'][] = '_field_extra_weights_pre_render';
+  $form['#extra_fields'] = field_extra_fields($bundle);
+
   // Let other modules make changes to the form.
   foreach (module_implements('field_attach_form') as $module) {
     $function = $module . '_field_attach_form';
@@ -1043,6 +1048,11 @@
 
   $output = _field_invoke_default('view', $obj_type, $object, $build_mode);
 
+  // Add custom weight handling.
+  list($id, $vid, $bundle) = field_attach_extract_ids($obj_type, $object);
+  $output['#pre_render'][] = '_field_extra_weights_pre_render';
+  $output['#extra_fields'] = field_extra_fields($bundle);
+
   // Let other modules make changes after rendering the view.
   drupal_alter('field_attach_view', $output, $obj_type, $object, $build_mode);
 
@@ -1051,6 +1061,24 @@
 }
 
 /**
+ * Retrieve the user-defined weight for pseudo-field components.
+ *
+ * @param $bundle
+ *   The bundle name.
+ * @param $pseudo_field
+ *   The name of the 'field'.
+ * @return
+ *   The weight for the 'field', respecting the user settings stored
+ *   by field.module.
+ */
+function field_attach_extra_weight($bundle, $pseudo_field) {
+  $extra = field_extra_fields($bundle);
+  if (isset($extra[$pseudo_field])) {
+    return $extra[$pseudo_field]['weight'];
+  }
+}
+
+/**
  * Implement hook_node_prepare_translation.
  *
  * TODO D7: We do not yet know if this really belongs in Field API.
Index: modules/field/modules/text/text.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v
retrieving revision 1.17
diff -u -r1.17 text.module
--- modules/field/modules/text/text.module	4 Aug 2009 06:38:56 -0000	1.17
+++ modules/field/modules/text/text.module	16 Aug 2009 00:27:37 -0000
@@ -129,6 +129,50 @@
 }
 
 /**
+ * Implement hook_field_settings_form().
+ */
+function text_field_settings_form($field, $instance) {
+  $settings = $field['settings'];
+  $form['max_length'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Maximum length'),
+    '#default_value' => $settings['max_length'],
+    '#required' => FALSE,
+    '#description' => t('The maximum length of the field in characters. Leave blank for an unlimited size.'),
+    '#element_validate' => array('_element_validate_integer_positive'),
+  );
+  return $form;
+}
+
+/**
+ * Implement hook_field_instance_settings_form().
+ */
+function text_field_instance_settings_form($field, $instance) {
+  $settings = $instance['settings'];
+  $form = array();
+
+  $form['text_processing'] = array(
+    '#type' => 'radios',
+    '#title' => t('Text processing'),
+    '#default_value' => $settings['text_processing'],
+    '#options' => array(
+      t('Plain text'),
+      t('Filtered text (user selects input format)'),
+    ),
+  );
+  if ($field['type'] == 'text_with_summary') {
+    $form['display_summary'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Summary input'),
+      '#default_value' => $settings['display_summary'],
+      '#description' => t('This allows authors to input an explicit summary, to be displayed instead of the automatically trimmed text when using the "Summary or trimmed" display format.'),
+    );
+  }
+
+  return $form;
+}
+
+/**
  * Implement hook_field_validate().
  *
  * Possible error codes:
@@ -467,6 +511,33 @@
 }
 
 /**
+ * Implement hook_field_widget_settings_form().
+ */
+function text_field_widget_settings_form($field, $instance) {
+  $widget = $instance['widget'];
+  $settings = $widget['settings'];
+  if ($widget['type'] == 'text_textfield') {
+    $form['size'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Size of textfield'),
+      '#default_value' => $settings['size'],
+      '#required' => TRUE,
+      '#element_validate' => array('_element_validate_integer_positive'),
+    );
+  }
+  else {
+    $form['rows'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Rows'),
+      '#default_value' => $settings['rows'],
+      '#required' => TRUE,
+      '#element_validate' => array('_element_validate_integer_positive'),
+    );
+  }
+  return $form;
+}
+
+/**
  * Implement FAPI hook_elements().
  *
  * Any FAPI callbacks needed for individual widgets can be declared here,
Index: modules/field/modules/list/list.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/list/list.module,v
retrieving revision 1.7
diff -u -r1.7 list.module
--- modules/field/modules/list/list.module	1 Aug 2009 06:03:12 -0000	1.7
+++ modules/field/modules/list/list.module	16 Aug 2009 00:27:36 -0000
@@ -28,28 +28,28 @@
     'list' => array(
       'label' => t('List'),
       'description' => t('This field stores numeric keys from key/value lists of allowed values where the key is a simple alias for the position of the value, i.e. 0|First option, 1|Second option, 2|Third option.'),
-      'settings' => array('allowed_values_function' => ''),
+      'settings' => array('allowed_values' => '', 'allowed_values_function' => ''),
       'default_widget' => 'options_select',
       'default_formatter' => 'list_default',
     ),
     'list_boolean' => array(
       'label' => t('Boolean'),
       'description' => t('This field stores simple on/off or yes/no options.'),
-      'settings' => array('allowed_values_function' => ''),
+      'settings' => array('allowed_values' => '', 'allowed_values_function' => ''),
       'default_widget' => 'options_select',
       'default_formatter' => 'list_default',
     ),
     'list_number' => array(
       'label' => t('List (numeric)'),
       'description' => t('This field stores keys from key/value lists of allowed numbers where the stored numeric key has significance and must be preserved, i.e. \'Lifetime in days\': 1|1 day, 7|1 week, 31|1 month.'),
-      'settings' => array('allowed_values_function' => ''),
+      'settings' => array('allowed_values' => '', 'allowed_values_function' => ''),
       'default_widget' => 'options_select',
       'default_formatter' => 'list_default',
     ),
     'list_text' => array(
       'label' => t('List (text)'),
       'description' => t('This field stores keys from key/value lists of allowed values where the stored key has significance and must be a varchar, i.e. \'US States\': IL|Illinois, IA|Iowa, IN|Indiana'),
-      'settings' => array('allowed_values_function' => ''),
+      'settings' => array('allowed_values' => '', 'allowed_values_function' => ''),
       'default_widget' => 'options_select',
       'default_formatter' => 'list_default',
     ),
@@ -98,6 +98,132 @@
 }
 
 /**
+ * Implement hook_field_settings_form().
+ */
+function list_field_settings_form($field, $instance) {
+  $settings = $field['settings'];
+  $form = array();
+
+  $form['allowed_values'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Allowed values list'),
+    '#default_value' => $settings['allowed_values'],
+    '#required' => FALSE,
+    '#rows' => 10,
+    '#description' => '<p>' . t('The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database, and must be a %type value. The label is optional, and the key will be used as the label if no label is specified.', array('%type' => $field['type'] == 'list_text' ? t('text') : t('numeric'))) . '</p>',
+    '#element_validate' => array('list_allowed_values_validate'),
+    '#list_field_type' => $field['type'],
+    '#access' => empty($settings['allowed_values_function']),
+  );
+
+  // Alter the description for allowed values depending on the widget type.
+  if ($instance['widget']['type'] == 'options_onoff') {
+    $form['allowed_values']['#description'] .= '<p>' . t("For a 'single on/off checkbox' widget, define the 'off' value first, then the 'on' value in the <strong>Allowed values</strong> section. Note that the checkbox will be labeled with the label of the 'on' value.") . '</p>';
+  }
+  elseif ($instance['widget']['type'] == 'options_buttons') {
+    $form['allowed_values']['#description'] .= '<p>' . t("The 'checkboxes/radio buttons' widget will display checkboxes if the <em>Number of values</em> option is greater than 1 for this field, otherwise radios will be displayed.") . '</p>';
+  }
+  $form['allowed_values']['#description'] .= t('Allowed HTML tags in labels: @tags', array('@tags' => _field_filter_xss_display_allowed_tags()));
+
+  $form['allowed_values_function'] = array(
+    '#type' => 'value',
+    '#value' => $settings['allowed_values_function'],
+  );
+  $form['allowed_values_function_display'] = array(
+    '#type' => 'item',
+    '#title' => t('Allowed values list'),
+    '#markup' => t('The value of this field is being determined by the %function function and may not be changed.', array('%function' => $settings['allowed_values_function'])),
+    '#access' => !empty($settings['allowed_values_function']),
+  );
+
+  return $form;
+}
+
+/**
+ * Create an array of the allowed values for this field.
+ */
+function list_allowed_values($field) {
+  $allowed_values = drupal_static(__FUNCTION__, array());
+
+  if (isset($allowed_values[$field['field_name']])) {
+    return $allowed_values[$field['field_name']];
+  }
+
+  $allowed_values[$field['field_name']] = array();
+
+  $function = $field['settings']['allowed_values_function'];
+  if (!empty($function) && drupal_function_exists($function)) {
+    $allowed_values[$field['field_name']] = $function($field);
+  }
+  elseif (!empty($field['settings']['allowed_values'])) {
+    $allowed_values[$field['field_name']] = list_allowed_values_list($field['settings']['allowed_values'], $field['type'] == 'list');
+  }
+
+  return $allowed_values[$field['field_name']];
+}
+
+/**
+ * Create an array of the allowed values for this field.
+ *
+ * Explode a string with keys and labels separated with '|' and with each new
+ * value on its own line.
+ *
+ * @param $string_values
+ *   The list of choices as a string.
+ * @param $position_keys
+ *   Boolean value indicating whether to generate keys based on the position of
+ *   the value if a key is not manually specified, effectively generating
+ *   integer-based keys. This should only be TRUE for fields that have a type of
+ *   "list". Otherwise the value will be used as the key if not specified.
+ */
+function list_allowed_values_list($string_values, $position_keys = FALSE) {
+  $allowed_values = array();
+
+  $list = explode("\n", $string_values);
+  $list = array_map('trim', $list);
+  $list = array_filter($list, 'strlen');
+  foreach ($list as $key => $value) {
+    // Sanitize the user input with a permissive filter.
+    $value = field_filter_xss($value);
+
+    // Check for a manually specified key.
+    if (strpos($value, '|') !== FALSE) {
+      list($key, $value) = explode('|', $value);
+    }
+    // Otherwise see if we need to use the value as the key. The "list" type
+    // automatically will convert non-keyed lines to integers.
+    elseif (!$position_keys) {
+      $key = $value;
+    }
+    $allowed_values[$key] = (isset($value) && $value !== '') ? $value : $key;
+  }
+
+  return $allowed_values;
+}
+
+/**
+ * Element validate callback; check that the entered values are valid.
+ */
+function list_allowed_values_validate($element, &$form_state) {
+  $values = list_allowed_values_list($element['#value'], $element['#list_field_type'] == 'list');
+  $field_type = $element['#list_field_type'];
+  foreach ($values as $key => $value) {
+    if ($field_type == 'list_number' && !is_numeric($key)) {
+      form_error($element, t('The entered available values are not valid. Each key must be a valid integer or decimal.'));
+      break;
+    }
+    elseif ($field_type == 'list_text' && strlen($key) > 255) {
+      form_error($element, t('The entered available values are not valid. Each key must be a string less than 255 characters.'));
+      break;
+    }
+    elseif ($field_type == 'list' && (!preg_match('/^-?\d+$/', $key))) {
+      form_error($element, t('The entered available values are not valid. All specified keys must be integers.'));
+      break;
+    }
+  }
+}
+
+/**
  * Implement hook_field_validate().
  *
  * Possible error codes:
@@ -161,29 +287,3 @@
 function theme_field_formatter_list_key($element) {
   return $element['#item']['safe'];
 }
-
-/**
- *  Create an array of the allowed values for this field.
- *
- *  Call the allowed_values_function to retrieve the allowed
- *  values array.
- *
- *  TODO Rework this to create a method of selecting plugable allowed values lists.
- */
-function list_allowed_values($field) {
-  static $allowed_values;
-
-  if (isset($allowed_values[$field['field_name']])) {
-    return $allowed_values[$field['field_name']];
-  }
-
-  $allowed_values[$field['field_name']] = array();
-
-  if (isset($field['settings']['allowed_values_function'])) {
-    $function = $field['settings']['allowed_values_function'];
-    if (drupal_function_exists($function)) {
-      $allowed_values[$field['field_name']] = $function($field);
-    }
-  }
-  return $allowed_values[$field['field_name']];
-}
