Index: modules_contrib/panels/panels_ipe/panels_ipe.module
===================================================================
--- modules_contrib/panels/panels_ipe/panels_ipe.module	(revision 4f375e3c16522ed686093be9fd8d4fd3a3e601a3)
+++ modules_contrib/panels/panels_ipe/panels_ipe.module	(revision 4f375e3c16522ed686093be9fd8d4fd3a3e601a3)
@@ -0,0 +1,147 @@
+<?php
+
+/**
+ * Implementation of hook_ctools_plugin_directory().
+ */
+function panels_ipe_ctools_plugin_directory($module, $plugin) {
+  if ($module == 'panels' && $plugin == 'display_renderers') {
+    return 'plugins/' . $plugin;
+  }
+}
+
+/**
+ * Implementation of hook_ctools_plugin_api().
+ *
+ * Inform CTools about version information for various plugins implemented by
+ * Panels.
+ *
+ * @param string $owner
+ *   The system name of the module owning the API about which information is
+ *   being requested.
+ * @param string $api
+ *   The name of the API about which information is being requested.
+ */
+function panels_ipe_ctools_plugin_api($owner, $api) {
+  if ($owner == 'panels' && $api == 'pipelines') {
+    return array(
+      'version' => 1,
+      'path' => drupal_get_path('module', 'panels_ipe') . '/includes',
+    );
+  }
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function panels_ipe_theme() {
+  return array(
+    'panels_ipe_pane_wrapper' => array(
+      'arguments' => array('output' => NULL, 'pane' => NULL, 'display' => NULL),
+    ),
+    'panels_ipe_region_wrapper' => array(
+      'arguments' => array('output' => NULL, 'region_id' => NULL, 'display' => NULL, 'renderer' => NULL),
+    ),
+    'panels_ipe_add_pane_button' => array(
+      'arguments' => array('region_id' => NULL, 'display' => NULL, 'renderer' => NULL),
+    ),
+    'panels_ipe_placeholder_pane' => array(
+      'arguments' => array('region_id' => NULL, 'region_title' => NULL),
+    ),
+    'panels_ipe_dnd_form_container' => array(
+      'arguments' => array('link' => NULL, 'cache_key' => NULL, 'display' => NULL),
+    ),
+  );
+}
+
+/**
+ * Theme the 'placeholder' pane, which is shown on an active IPE when no panes
+ * live in that region.
+ *
+ * @param string $region_id
+ * @param string $region_title
+ */
+function theme_panels_ipe_placeholder_pane($region_id, $region_title) {
+  $output = '<div class="panels-ipe-placeholder-content">';
+  $output .= "<h3>$region_title</h3>";
+  $output .= '</div>';
+  return $output;
+}
+
+function theme_panels_ipe_pane_wrapper($output, $pane, $display, $renderer) {
+  $content_type = ctools_get_content_type($pane->type);
+  $subtype = ctools_content_get_subtype($content_type, $pane->subtype);
+  $links = array();
+
+  if (ctools_content_editable($content_type, $subtype, $pane->configuration)) {
+    $links['edit'] = array(
+      'title' => isset($content_type['edit text']) ? $content_type['edit text'] : t('Settings'),
+      'href' => $renderer->get_url('edit-pane', $pane->pid),
+      'attributes' => array(
+        'class' => 'ctools-use-modal',
+        // 'id' => "pane-edit-panel-pane-$pane->pid",
+      ),
+    );
+  }
+
+  // Deleting is managed entirely in the js; this is just an attachment point
+  // for it
+  $links['delete'] = array(
+    'title' => t('Delete'),
+    'href' => '#',
+    'attributes' => array(
+      'class' => 'pane-delete',
+      'id' => "pane-delete-panel-pane-$pane->pid",
+    ),
+  );
+
+  $attr = array(
+    'class' => 'panels-ipe-linkbar',
+  );
+
+  $links = theme('links', $links, $attr);
+  $links .= '<div class="panels-ipe-draghandle">&nbsp;</div>';
+  $handlebar = '<div class="panels-ipe-handlebar-wrapper panels-ipe-on clear-block">' . $links . '</div>';
+  return $handlebar . $output;
+}
+
+function theme_panels_ipe_region_wrapper($output, $region_id, $display) {
+  return $output;
+}
+
+function theme_panels_ipe_add_pane_button($region_id, $display, $renderer) {
+  $attr = array('class' => 'ctools-use-modal');
+  $link = l(t('Add new pane'), $renderer->get_url('select-content', $region_id), array('attributes' => $attr));
+  return '<div class="panels-ipe-newblock panels-ipe-on panels-ipe-portlet-static">' . $link . '</div>';
+}
+
+function panels_ipe_get_cache_key($key = NULL) {
+  static $cache;
+  if (isset($key)) {
+    $cache = $key;
+  }
+  return $cache;
+}
+
+/**
+ * Implementation of hook_footer()
+ *
+ * Adds the IPE control container.
+ *
+ * @param unknown_type $main
+ */
+function panels_ipe_footer($main = 0) {
+  $key = panels_ipe_get_cache_key();
+  if (!isset($key)) {
+    return;
+  }
+
+  // TODO should be moved into the IPE plugin - WAAAY too hardcoded right now
+  $output = "<div id='panels-ipe-control-container' class='clear-block'>";
+  $output .= "<div id='panels-ipe-control-$key' class='panels-ipe-control'>";
+  $output .= "<div class='panels-ipe-startedit panels-ipe-pseudobutton panels-ipe-off'>";
+  $output .= "<span>" . t('Customize this page') . "</span>";
+  $output .= "</div>";
+  $output .= "<div class='panels-ipe-form-container panels-ipe-on clear-block'></div>";
+  $output .= "</div></div>";
+  return $output;
+}
