ClipboardField: add copy button
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout-module.js b/org.eclipse.scout.rt.ui.html/src/main/js/scout-module.js
index 8f6d5ef..1d9b90e 100644
--- a/org.eclipse.scout.rt.ui.html/src/main/js/scout-module.js
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout-module.js
@@ -384,7 +384,9 @@
   __include("scout/form/fields/checkbox/CheckBoxField.js");
   __include("scout/form/fields/checkbox/CheckBoxFieldAdapter.js");
   __include("scout/form/fields/checkbox/CheckBoxToggleKeyStroke.js");
+  __include("scout/form/fields/clipboardfield/CopyButton.js");
   __include("scout/form/fields/clipboardfield/ClipboardField.js");
+  __include("scout/form/fields/clipboardfield/ClipboardFieldLayout.js");
   __include("scout/form/fields/clipboardfield/ClipboardFieldAdapter.js");
   __include("scout/form/fields/colorfield/ColorField.js");
   __include("scout/form/fields/colorfield/ColorFieldAdapter.js");
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.js b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.js
index 17e629a..bb6ad27 100644
--- a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.js
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.js
@@ -67,12 +67,21 @@
   // not work in IE9.
   this.addContainer(this.$parent, 'clipboard-field');
   this.addLabel();
-  this.addField(this.$parent.makeElement('<div>').addClass('input-field'));
+  this.addFieldContainer(this.$parent.makeDiv());
+  this.htmlField = scout.HtmlComponent.install(this.$fieldContainer, this.session);
+  this.htmlField.setLayout(new scout.ClipboardFieldLayout(this));
+  this.addField(this.$fieldContainer.appendDiv().addClass('input-field'));
+  this.copyButton = scout.create('CopyButton', {
+    parent: this,
+    processButton: false,
+    $input: this.$field
+  });
+  this.copyButton.render(this.$fieldContainer);
   this.addStatus();
 
   this.$field
     .disableSpellcheck()
-    .attr('contenteditable', true)
+    .attr('contenteditable', this._shouldBeContentEditable())
     .attr('tabindex', '0')
     .on('keydown', this._onKeyDown.bind(this))
     .on('input', this._onInput.bind(this))
@@ -81,15 +90,38 @@
     .on('cut', this._onCopy.bind(this));
 
   this.$parent.on('click', function(event) {
-    this.focus();
+//    this.focus(); // FIXME CGU what is this for
   }.bind(this));
 };
 
+scout.ClipboardField.prototype._remove = function() {
+  scout.ClipboardField.parent.prototype._remove.call(this);
+  this.copyButton.destroy();
+};
+
 scout.ClipboardField.prototype._renderProperties = function() {
   scout.ClipboardField.parent.prototype._renderProperties.call(this);
   this._renderDropType();
 };
 
+/**
+ * @override
+ */
+scout.ClipboardField.prototype.focus = function() {
+  if (!this.rendered) {
+    return;
+  }
+  // The copy button should be focused by default
+  this.copyButton.focus();
+};
+
+scout.ClipboardField.prototype._shouldBeContentEditable = function() {
+  // On iOS the on screen keyboard pops up which is very annoying.
+  // Drawback is that 'Select all' button disappears and text selection is not limited to the field anymore.
+  // But since the user can use the copy button this should not be a real problem.
+  return !scout.device.isIos();
+};
+
 scout.ClipboardField.prototype._createDragAndDropHandler = function() {
   return scout.dragAndDrop.handler(this, {
     supportedScoutTypes: scout.dragAndDrop.SCOUT_TYPES.FILE_TRANSFER,
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.less b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.less
index b2d38d2..f1585df 100644
--- a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.less
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardField.less
@@ -10,12 +10,22 @@
  ******************************************************************************/
 .clipboard-field > .field {
   margin-left: @mandatory-indicator-width;
-  background-color: @item-selection-background-color;
-  padding: @text-field-padding-y @text-field-padding-x;
-  #scout.user-select(text);
-  white-space: pre-wrap;
 
-  & > img {
-    display: none;
+  & .input-field {
+    background-color: @item-selection-background-color;
+    padding: @text-field-padding-y @text-field-padding-x;
+    #scout.user-select(text);
+    white-space: pre-wrap;
+    height: 100%;
+
+    & > img {
+      display: none;
+    }
+  }
+
+  & > .copy-button {
+    position: absolute;
+    top: 0;
+    right: 0;
   }
 }
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardFieldLayout.js b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardFieldLayout.js
new file mode 100644
index 0000000..a99dd18
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/ClipboardFieldLayout.js
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2014-2017 BSI Business Systems Integration AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     BSI Business Systems Integration AG - initial API and implementation
+ ******************************************************************************/
+scout.ClipboardFieldLayout = function(field) {
+  this.clipboardField = field;
+};
+scout.inherits(scout.ClipboardFieldLayout, scout.AbstractLayout);
+
+scout.ClipboardFieldLayout.prototype.layout = function($container) {
+  var htmlContainer = this.clipboardField.htmlField;
+  var containerSize = htmlContainer.availableSize().subtract(htmlContainer.insets());
+  var copyButton = this.clipboardField.copyButton;
+  var buttonPrefSize = copyButton.htmlComp.prefSize(true);
+  var inputWidth = containerSize.width - buttonPrefSize.width;
+
+  this.clipboardField.$field.cssWidth(inputWidth);
+  copyButton.htmlComp.setSize(buttonPrefSize);
+};
diff --git a/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/CopyButton.js b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/CopyButton.js
new file mode 100644
index 0000000..9ca3857
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.html/src/main/js/scout/form/fields/clipboardfield/CopyButton.js
@@ -0,0 +1,52 @@
+scout.CopyButton = function() {
+  scout.CopyButton.parent.call(this);
+  this.$input = null;
+  this.label = 'copy';
+  this.cssClass = 'copy-button';
+};
+scout.inherits(scout.CopyButton, scout.Button);
+
+scout.CopyButton.prototype._doAction = function() {
+  scout.CopyButton.parent.prototype._doAction.call(this);
+  this.copyToClipboard();
+};
+
+scout.CopyButton.prototype.copyToClipboard = function() {
+  if (!this.$input) {
+    return;
+  }
+  this.$input.selectAllText();
+
+  try {
+    var successful = document.execCommand('copy');
+    if (successful) {
+      this._showSuccessMessage();
+    } else {
+      this._showFailedMessage();
+    }
+  } catch (error) {
+    this._showFailedMessage(error);
+  }
+};
+
+scout.CopyButton.prototype._showSuccessMessage = function() {
+  var tooltip = this._createTooltip({
+    parent: this,
+    autoRemove: true,
+    $anchor: this.$field,
+    text: 'Copied successfully'
+  });
+  tooltip.render();
+};
+
+scout.CopyButton.prototype._showFailedMessage = function(error) {
+  var tooltip = this._createTooltip({
+    parent: this,
+    autoRemove: true,
+    $anchor: this.$field,
+    text: 'Sorry, copying has failed',
+    severity: scout.Status.Severity.ERROR
+  });
+  tooltip.render();
+  $.log.warn('Copying has failed', error);
+};