Index: wysiwyg.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg.admin.inc,v
retrieving revision 1.15.2.9
diff -u -p -r1.15.2.9 wysiwyg.admin.inc
--- wysiwyg.admin.inc	13 Feb 2010 23:58:41 -0000	1.15.2.9
+++ wysiwyg.admin.inc	21 Apr 2010 23:44:16 -0000
@@ -316,7 +316,16 @@ function wysiwyg_profile_form_submit($fo
   unset($values['submit'], $values['form_id'], $values['op'], $values['form_token'], $values['form_build_id']);
 
   // Insert new profile data.
-  db_query("UPDATE {wysiwyg} SET settings = '%s' WHERE format = %d", serialize($values), $format);
+  if (!db_result(db_query("SELECT 1 FROM {wysiwyg} WHERE format = %d", $format))) {
+    $wysiwyg = new stdClass();
+    $wysiwyg->format = $format;
+    $wysiwyg->editor = $editor;
+    $wysiwyg->settings = serialize($values);
+    drupal_write_record('wysiwyg', $wysiwyg);
+  }
+  else {
+    db_query("UPDATE {wysiwyg} SET settings = '%s' WHERE format = %d", serialize($values), $format);
+  }
 
   drupal_set_message(t('Wysiwyg profile for %format has been saved.', array('%format' => $input_format)));
 
@@ -443,8 +452,18 @@ function wysiwyg_profile_overview() {
       $enable_save = TRUE;
     }
     if (isset($profiles[$id]) && !empty($profiles[$id]->editor)) {
-      $form['formats'][$id]['edit'] = array(
-        '#value' => l(t('Edit'), "admin/settings/wysiwyg/profile/$id/edit"),
+      if (isset($profiles[$id]->default)) {
+        $form['formats'][$id]['edit'] = array(
+          '#value' => l(t('Override'), "admin/settings/wysiwyg/profile/$id/edit"),
+        );
+      }
+      else {
+        $form['formats'][$id]['edit'] = array(
+          '#value' => l(t('Edit'), "admin/settings/wysiwyg/profile/$id/edit"),
+        );
+      }
+      $form['formats'][$id]['export'] = array(
+        '#value' => l(t('Export'), "admin/settings/wysiwyg/profile/$id/export"),
       );
       $form['formats'][$id]['delete'] = array(
         '#value' => l(t('Delete'), "admin/settings/wysiwyg/profile/$id/delete"),
@@ -475,6 +494,7 @@ function theme_wysiwyg_profile_overview(
       drupal_render($format['name']),
       drupal_render($format['editor']),
       isset($format['edit']) ? drupal_render($format['edit']) : '',
+      isset($format['export']) ? drupal_render($format['export']) : '',
       isset($format['delete']) ? drupal_render($format['delete']) : '',
     );
   }
@@ -529,3 +549,96 @@ function wysiwyg_profile_delete($format)
   db_query("DELETE FROM {wysiwyg} WHERE format = %d", $format);
 }
 
+/**
+* Import a format setting.
+*/
+function wysiwyg_import_format(&$form_state) {
+  $format_objs = filter_formats();
+  $formats[0] = t('As defined in the import'); 
+  foreach ($format_objs as $obj) {
+    $formats[$obj->format] = $obj->name;
+  }
+  
+  $form['wysiwyg'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Paste wysiwyg settings code here:'),
+    '#required' => TRUE,
+  );
+  
+  $form['target_format'] = array(
+    '#type' => 'select', 
+    '#title' => t('Target format'), 
+    '#options' => $formats,
+    '#description' => t('Input format for the wysiwyg settings'),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Import'),
+    '#submit' => array('wysiwyg_import_submit'),
+    '#validate' => array('wysiwyg_import_validate'),
+  );
+
+  return $form;
+}
+
+/**
+ * Validate that the pasted in code works.
+ */
+function wysiwyg_import_validate($form, &$form_state) {
+  $wysiwyg = '';
+  // Put any necessary includes here
+  ob_start();
+  eval($form_state['values']['wysiwyg']);
+  ob_end_clean();
+
+  if (!is_object($wysiwyg)) {
+    return form_error($form['wysiwyg'], t('Unable to interpret view code.'));
+  }
+  if (empty($wysiwyg->api_version) || $wysiwyg->api_version < 2) {
+    form_error($form['wysiwyg'], t('That wysiwyg format setting is not compatible with this version of the wysiwyg module.'));
+  }
+  
+  if ($form_state['values']['target_format']) {
+    $wysiwyg->format = $form_state['values']['target_format'];
+  }
+
+  // Refuse any settings that already exist for that format type
+  $settings_count = db_result(db_query("SELECT count(*) FROM {wysiwyg} WHERE format = %d", $wysiwyg->format));
+  if ($settings_count >= 1) {
+    form_error($form['wysiwyg'], t('Wysiwyg settings already exist for that input format type. Please delete the existing settings and attempt the import again if you wish to replace the existing settings.'));
+  }
+
+}
+
+/**
+ * Submit handler for wysiwyg settings import
+ */
+function wysiwyg_import_submit($form, &$form_state) {
+  // Check to see if the setting exits (should have been caught by validation hook above); if so give an error;
+  // else write the format settings to the database and then redirect the user to the edit page
+  $wysiwyg = '';
+  eval($form_state['values']['wysiwyg']);
+  
+  if ($form_state['values']['target_format']) {
+    $wysiwyg->format = $form_state['values']['target_format'];
+  }
+
+  $settings_count = db_result(db_query("SELECT count(*) FROM {wysiwyg} WHERE format = %d", $wysiwyg->format));
+  if ($settings_count >= 1) {
+    drupal_set_message(t("Settings for that format input type already existed; your import was not used and nothing was done.  Please delete the existing wysiwyg format settings for that input type and import again."), "error");
+    return;
+  }
+
+  // Write the settings to the database
+  $wysiwyg->settings = serialize($wysiwyg->settings);
+  $dwr_ret = drupal_write_record("wysiwyg", $wysiwyg);
+
+  if ($dwr_ret == FALSE) {
+    drupal_set_message(t("An error occurred when writing the settings to the database.") , "error");
+    return ;
+  }
+
+  $form_state['redirect'] = 'admin/settings/wysiwyg/profile/'. $wysiwyg->format .'/edit';
+
+}
Index: wysiwyg.features.inc
===================================================================
RCS file: wysiwyg.features.inc
diff -N wysiwyg.features.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ wysiwyg.features.inc	21 Apr 2010 23:44:16 -0000
@@ -0,0 +1,11 @@
+<?php
+
+// $Id$
+
+/**
+ * This file is only neccesary to inform to features modules that
+ * Wysiwyg can export their settings.
+ *
+ * However all the export/import proccess is managed by ctools.
+ */
+
Index: wysiwyg.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg.install,v
retrieving revision 1.4.2.2
diff -u -p -r1.4.2.2 wysiwyg.install
--- wysiwyg.install	13 Feb 2010 23:58:41 -0000	1.4.2.2
+++ wysiwyg.install	21 Apr 2010 23:44:16 -0000
@@ -7,6 +7,18 @@
 function wysiwyg_schema() {
   $schema['wysiwyg'] = array(
     'description' => t('Stores Wysiwyg profiles.'),
+    'export' =>  array(
+      'key' => 'format',
+      'identifier' => 'wysiwyg',
+      'default hook' => 'wysiwyg_default_format',  // Function hook name.
+      'export callback' => 'wysiwyg_format_export',
+      'api' => array(
+        'owner' => 'wysiwyg',
+        'api' => 'wysiwyg_default_format', // Base name for api include files.
+        'minimum_version' => 2,
+        'current_version' => 2,
+      ),
+    ),
     'fields' => array(
       'format' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
       'editor' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
Index: wysiwyg.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/wysiwyg/wysiwyg.module,v
retrieving revision 1.33.2.11
diff -u -p -r1.33.2.11 wysiwyg.module
--- wysiwyg.module	14 Feb 2010 01:59:47 -0000	1.33.2.11
+++ wysiwyg.module	21 Apr 2010 23:44:17 -0000
@@ -50,6 +50,22 @@ function wysiwyg_menu() {
     'type' => MENU_CALLBACK,
     'file' => 'wysiwyg.dialog.inc',
   );
+  $items['admin/settings/wysiwyg/profile/%/export'] = array(
+    'title' => 'Export',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('wysiwyg_export_format', 4),
+    'access arguments' => array('administer filters'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/settings/wysiwyg/import'] = array(
+    'title' => 'Import',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('wysiwyg_import_format', 3),
+    'access arguments' => array('administer filters'),
+    'file' => 'wysiwyg.admin.inc',
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 10
+  );
   return $items;
 }
 
@@ -591,6 +607,16 @@ function wysiwyg_profile_load($format) {
       $profile->settings = unserialize($profile->settings);
       $profiles[$profile->format] = $profile;
     }
+    // For features integration: call each module's hook_wysiwyg_defaults if they have it,
+    // and if the settings for that format type don't already exist from being read from
+    // the database above, put them in the array.
+    $default_profiles = module_invoke_all('wysiwyg_default_format');
+    foreach ($default_profiles as $def_prof) {
+      if (!isset($profiles) || !array_key_exists( $def_prof->format, $profiles)) {
+        $def_prof->default = TRUE;
+        $profiles[$def_prof->format] = $def_prof;
+      }
+    }
   }
 
   return (isset($profiles[$format]) ? $profiles[$format] : FALSE);
@@ -609,6 +635,16 @@ function wysiwyg_profile_load_all() {
       $profile->settings = unserialize($profile->settings);
       $profiles[$profile->format] = $profile;
     }
+    // For features integration: call each module's hook_wysiwyg_defaults if they have it,
+    // and if the settings for that format type don't already exist from being read from
+    // the database above, put them in the array.
+    $default_profiles = module_invoke_all('wysiwyg_default_format');
+    foreach ($default_profiles as $def_prof) {
+      if (!array_key_exists($def_prof->format, $profiles)) {
+        $def_prof->default = TRUE;
+        $profiles[$def_prof->format] = $def_prof;
+      }
+    }
   }
 
   return $profiles;
@@ -968,6 +1004,70 @@ function _wysiwyg_process_include($modul
 }
 
 /**
+ * Export a format setting and display it in a form.
+ */
+function wysiwyg_export_format(&$form_state, $format) {
+  $obj = wysiwyg_format_load($format);
+
+  $formats = filter_formats();
+  $format_name = $formats[$format]->name;
+
+  drupal_set_title(t('Export @wysiwyg settings for: @format input format', array('@wysiwyg'=> $obj->editor, '@format' => $format_name)));
+  $code = wysiwyg_format_export($obj);
+  $lines = substr_count($code, "\n");
+
+  $form['export'] = array(
+    '#title' => t('Export data'),
+    '#type' => 'textarea',
+    '#value' => $code,
+    '#rows' => $lines,
+    '#description' => t('Copy the export text and paste it into another wysiwyg format using the import function.'),
+  );
+  return $form;
+}
+
+/**
+ * Load a single format setting.
+ */
+function wysiwyg_format_load($format) {
+  ctools_include('export');
+  $result = ctools_export_load_object('wysiwyg', 'names', array($format));
+
+  if (isset($result[$format])) {
+    return $result[$format];
+  }
+}
+
+/**
+ * Export wysiwyg settings.
+ */
+function wysiwyg_format_export($obj, $indent = '') {
+  ctools_include('export');
+  if (is_string($obj->settings)) {
+    $obj->settings = unserialize($obj->settings);
+  }
+  else {
+    $obj->settings = $obj->settings;
+  }
+  $output = ctools_export_object('wysiwyg', $obj, $indent);
+  return $output;
+}
+
+/**
+ * Implementation of hook_features_api().
+ */
+function wysiwyg_features_api() {
+  return array(
+    'wysiwyg' => array(
+      'default_hook' => 'wysiwyg_default_format',
+      'default_file' => FEATURES_DEFAULTS_INCLUDED,
+      'features_source' => TRUE,
+      'file' => drupal_get_path('module', 'wysiwyg') .'/wysiwyg.features.inc',
+    ),
+  );
+}
+
+/**
  * @} End of "defgroup wysiwyg_api".
  */
 
