diff --git a/css/fieldable_panels_panes_ipe.css b/css/fieldable_panels_panes_ipe.css
new file mode 100644
index 0000000000000000000000000000000000000000..fd799e1f0a29f364cf47b46fe32939af55cc6833
--- /dev/null
+++ b/css/fieldable_panels_panes_ipe.css
@@ -0,0 +1,3 @@
+div.panels-ipe-handlebar-wrapper li.fieldable_panels_pane_clone a span {
+ background-image: url(../images/icon_clone.png);
+}
diff --git a/fieldable_panels_panes.module b/fieldable_panels_panes.module
index cc8c072c0b38e3b5aa72b54ad1878804d58d026f..c6612a76a6f8d67db8abf75163dfe18d19f3dadb 100644
--- a/fieldable_panels_panes.module
+++ b/fieldable_panels_panes.module
@@ -1332,6 +1332,33 @@ function fieldable_panels_panes_form_ctools_export_ui_edit_item_form_alter(&$for
}
/**
+ * Implements hook_ctools_plugin_pre_alter().
+ */
+function fieldable_panels_panes_ctools_plugin_pre_alter(&$plugin, &$info) {
+ if (isset($plugin['name']) && $plugin['name'] == 'ipe') {
+ $plugin['module'] = 'fieldable_panels_panes';
+ $plugin['renderer'] = 'fieldable_panels_renderer_ipe';
+ $plugin['path'] = drupal_get_path('module', 'fieldable_panels_panes')
+ . '/plugins/display_renderers';
+ $plugin['file'] = 'fieldable_panels_renderer_ipe.class.php';
+ }
+}
+
+/**
+ * Implements hook_panels_ipe_pane_links_alter().
+ */
+function fieldable_panels_panes_panels_ipe_pane_links_alter(&$links, $context) {
+ if ($context['pane']->type == 'fieldable_panels_pane' && count(fieldable_panles_panes_pane_shares($context['pane']->pid)) > 1) {
+ ctools_add_css('fieldable_panels_panes_ipe', 'fieldable_panels_panes');
+ $links['fieldable_panels_pane_clone'] = array(
+ 'title' => '' . t('Clone') . '',
+ 'href' => $context['renderer']->get_url('clone-pane', $context['pane']->pid),
+ 'html' => TRUE,
+ ) + $links['edit'];
+ }
+}
+
+/**
* Callback function for the FPP entity label.
*/
function fieldable_panels_panes_entity_label_callback($entity, $type) {
diff --git a/images/icon_clone.png b/images/icon_clone.png
new file mode 100644
index 0000000000000000000000000000000000000000..910932e35828b8ab052b9d7d407e2315f31c6b71
GIT binary patch
literal 942
zcmV;f15x~mP)B(P;EF
zX8wqoCzu(u)<2Gnj5IelH|3=q6^q5VlyaSj-atfi0J(45c71AU%IWv};ZTeJ1}T@z
zqe6%enRx*KNJ*M>FMd~ySuwjb-UfgWHNaR
z0M3DUm{hA(5<)BsA?^wx^q?OPY}>vuIXU^B<2cXyzJFUv`J(4}=|Z9K&EespcfpZT
zDv5|6ODO>n1H&*5EX%r<&1S#Y-`{@%0P-7z=ef{bR-hF
z8iwJtQfhH<-T{Ey0C3c3G`5zPm!DzgmzlZ5%vT1Q`#})g1%R&_jYgBI)#^j7wQZW_
zA~ORsgAgJrrF&CC;~X_jo;ZUF#ru~#=^A_6JpPmxGuGn2`Do6qM1b{q#*R#qOj
zTCMNHFnocC;!3G|sZ?qW09xzo>u$5z3@eq&L*Ms%i1-{c|E;yYnaN~6>G%8Hjg5^H
z1_0RJ-VT?Rmj3K?IzLD$wPjfwu~_WLb>05X&Q1sbu(!A8<@5OmMAXt+?1wrtg*1G4qZm(Xi2WKZ^S=MiexW&wd5Tf1d^-iby4{ccr@Y5Bo
QV*mgE07*qoM6N<$f>4&Zu>b%7
literal 0
HcmV?d00001
diff --git a/plugins/display_renderers/fieldable_panels_renderer_ipe.class.php b/plugins/display_renderers/fieldable_panels_renderer_ipe.class.php
new file mode 100644
index 0000000000000000000000000000000000000000..c2cd6da291a8c16848894e9e8051c3ae0a2fcc8b
--- /dev/null
+++ b/plugins/display_renderers/fieldable_panels_renderer_ipe.class.php
@@ -0,0 +1,113 @@
+cache->display->content[$pid];
+ $clone = $this->clonePane($pid);
+ $pane->subtype = $clone->subtype;
+ $this->ajax_edit_pane($pid, $step);
+ }
+
+ /**
+ * Fix cloned fieldable panel pane that reference to single entity
+ *
+ * @param $pid
+ *
+ * @return bool
+ *
+ * @throws \Exception
+ * @throws \InvalidMergeQueryException
+ */
+ protected function clonePane($pid) {
+ $query = db_select('panels_pane', 'pp');
+ $query->fields('pp');
+ $query->condition('pid', $pid);
+ $query->range(0, 1);
+ $result = $query->execute();
+
+ $pane = $result->fetch();
+ if (!$pane) {
+ return FALSE;
+ }
+
+ // Copy from _fieldable_panels_panes_load_entity().
+ list($type, $id) = explode(':', $pane->subtype);
+ if ($type == 'uuid' && module_exists('uuid')) {
+ $ids = entity_get_id_by_uuid('fieldable_panels_pane', array($id));
+ if ($content = entity_load('fieldable_panels_pane', $ids)) {
+ $content = reset($content);
+ }
+ }
+ elseif ($type == 'vid') {
+ $fpid = db_query('SELECT fpid FROM {fieldable_panels_panes_revision} WHERE vid = :vid', array(':vid' => $id))->fetchField();
+ $content = fieldable_panels_panes_load($fpid, $id);
+ }
+ else {
+ $content = fieldable_panels_panes_load($id);
+ }
+
+ if (!$content) {
+ return FALSE;
+ }
+ // Copy of entity_ui_clone_entity() from entity module.
+
+ // Clone the entity and make sure it will get saved as a new entity.
+ $new_entity = clone $content;
+
+ $entity_info = entity_get_info('fieldable_panels_pane');
+ $new_entity->{$entity_info['entity keys']['id']} = FALSE;
+ if (!empty($entity_info['entity keys']['name'])) {
+ $new_entity->{$entity_info['entity keys']['name']} = FALSE;
+ }
+ $new_entity->is_new = TRUE;
+ $new_entity->title = '(Clone)' . $new_entity->title;
+
+ // Make sure the status of a cloned exportable is custom.
+ if (!empty($entity_info['exportable'])) {
+ $status_key = isset($entity_info['entity keys']['status']) ? $entity_info['entity keys']['status'] : 'status';
+ $new_entity->$status_key = ENTITY_CUSTOM;
+ }
+
+ if ($type == 'uuid' && module_exists('uuid')) {
+ $new_entity->vuuid = NULL;
+ $new_entity->uuid = NULL;
+ }
+ if (!empty($new_entity->vid)) {
+ $new_entity->vid = NULL;
+ }
+
+ $new_entity = fieldable_panels_panes_save($new_entity);
+ if (!$new_entity) {
+ return FALSE;
+ }
+
+ if (module_exists('uuid') && isset($new_entity->uuid)) {
+ $new_pane_subtype = 'uuid:' . $new_entity->uuid;
+ }
+ else {
+ $new_pane_subtype = 'fpid:' . $new_entity->fpid;
+ }
+ $new_entity->subtype = $new_pane_subtype;
+
+ db_merge('panels_pane')
+ ->key(array('pid' => $pid))
+ ->fields(array(
+ 'subtype' => $new_pane_subtype,
+ ))
+ ->execute();
+
+ return $new_entity;
+ }
+}
+