# HG changeset patch
# User Abdallah-Elshamy <abdallah.k.elshamy@gmail.com>
# Date 1587947112 -7200
#      Mon Apr 27 02:25:12 2020 +0200
# Node ID 73502a13b6367431b9bd163ce3b43d23b68a3199
# Parent  46a23dc62056d43f0e468956cc5f2ddb4ba81500
Add new function clipboard (bug #57699).

* scripts/io: Add clipboard.m.
* scripts/io/module.mk: Add a reference to the new file.
* doc/interpreter/io.txi: Add a docstring to manual.
* NEWS: Add to list of new functions.
* scripts/help/__unimplemented__.m: Remove the function.

diff -r 46a23dc62056 -r 73502a13b636 NEWS
--- a/NEWS	Sun Apr 26 10:48:20 2020 -0700
+++ b/NEWS	Mon Apr 27 02:25:12 2020 +0200
@@ -58,6 +58,7 @@ vectors with rows corresponding to the i
 
 ### Alphabetical list of new functions added in Octave 7
 
+* `clipboard`
 * `endsWith`
 * `rng`
 * `startsWith`
diff -r 46a23dc62056 -r 73502a13b636 doc/interpreter/io.txi
--- a/doc/interpreter/io.txi	Sun Apr 26 10:48:20 2020 -0700
+++ b/doc/interpreter/io.txi	Mon Apr 27 02:25:12 2020 +0200
@@ -218,6 +218,8 @@ separated lists.
 
 @DOCSTRING(dlmread)
 
+@DOCSTRING(clipboard)
+
 @DOCSTRING(csvwrite)
 
 @DOCSTRING(csvread)
diff -r 46a23dc62056 -r 73502a13b636 scripts/help/__unimplemented__.m
--- a/scripts/help/__unimplemented__.m	Sun Apr 26 10:48:20 2020 -0700
+++ b/scripts/help/__unimplemented__.m	Mon Apr 27 02:25:12 2020 +0200
@@ -653,7 +653,6 @@ function rlist = missing_functions ()
   "clearAllMemoizedCaches",
   "clearCache",
   "clearpoints",
-  "clipboard",
   "clone",
   "cmopts",
   "collapse",
diff -r 46a23dc62056 -r 73502a13b636 scripts/io/clipboard.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/io/clipboard.m	Mon Apr 27 02:25:12 2020 +0200
@@ -0,0 +1,110 @@
+########################################################################
+##
+## Copyright (C) 2020 The Octave Project Developers
+##
+## See the file COPYRIGHT.md in the top-level directory of this
+## distribution or <https://octave.org/copyright/>.
+##
+## This file is part of Octave.
+##
+## Octave is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <https://www.gnu.org/licenses/>.
+##
+########################################################################
+
+## -*- texinfo -*-
+## @deftypefn  {} {@var{retval} =} clipboard ("copy", @var{data})
+## @deftypefn  {} {@var{retval} =} clipboard ("paste")
+## copy/paste text from/to system using system clipboard
+##
+## @code{clipboard ("copy", @var{data})} copies @var{data} to the system clipboard.
+## It uses mat2str to convert @var{data} to character array if it isn't. 
+##
+## @code{clipboard ("paste")} returns a character vector of the clipboard contents if it 
+## can convert them. If it can't, It returns an empty character vector ('').
+##
+## @seealso{mat2str}
+## @end deftypefn
+
+function retval = clipboard (command, data)
+  if (! (nargin == 1 || nargin == 2))
+    print_usage ();
+  endif
+
+  ## Check if Java is installed
+  if (! usejava ("awt"))
+    error ("clipboard: Java software is not installed");
+  endif
+
+  cb = javaObject ("java.awt.datatransfer.Clipboard", "OctaveBoard");
+  cb = java_get (java_get ("java.awt.Toolkit", "getDefaultToolkit"),
+                 "getSystemClipboard");
+
+  ## Paste command
+  if (nargin == 1)
+    ## Check first argument
+    if (strncmpi (command, "pastespecial", 12))
+      ## TODO handle this when uiimport is supported
+      error ("clipboard: 'pastespecial' is not supported");
+    elseif (! strncmpi (command, "paste", 5))
+      print_usage ();
+    else
+      t = cb.getContents (null (0));
+      stringFlavor = java_get ("java.awt.datatransfer.DataFlavor", "stringFlavor");
+      if (t.isDataFlavorSupported (stringFlavor))
+        retval = t.getTransferData (stringFlavor);
+      else
+        retval = ''; 
+      endif
+    endif
+  ## Copy command
+  else
+    ## Check first argument
+    if (! strncmpi (command, "copy", 4))
+      print_usage ();
+    else
+      if (! (ischar (data) || isnumeric (data)))
+        error ("clipboard: second input must be a character vector or numeric array");
+      endif
+      if (isnumeric (data))
+        data = mat2str (data);
+      endif
+      contents = javaObject ("java.awt.datatransfer.StringSelection", data);
+      cb.setContents (contents, contents);
+    endif
+  endif
+endfunction
+
+
+## Test copying and pasting a character vector 
+%!test
+%!  str = 'hello there';
+%!  clipboard("copy", str);
+%!  assert (clipboard ("paste"), str)
+
+## Test copying and pasting a numeric array 
+%!test
+%!  str = [1 2 3 4;5 6 7 8];
+%!  clipboard("copy", str);
+%!  assert (clipboard ("paste"), "[1 2 3 4;5 6 7 8]")
+
+## Test copying and pasting a numeric vector 
+%!test
+%!  clipboard("copy", pi);
+%!  assert (clipboard ("paste"), "3.14159265358979")
+
+## Test error detection
+%!error <'pastespecial' is not supported> clipboard ("pastespecial")
+
+%!error <second input must be a character vector or numeric array> clipboard ("copy",{})
diff -r 46a23dc62056 -r 73502a13b636 scripts/io/module.mk
--- a/scripts/io/module.mk	Sun Apr 26 10:48:20 2020 -0700
+++ b/scripts/io/module.mk	Mon Apr 27 02:25:12 2020 +0200
@@ -2,6 +2,7 @@ FCN_FILE_DIRS += %reldir%
 
 %canon_reldir%_FCN_FILES = \
   %reldir%/beep.m \
+  %reldir%/clipboard.m \
   %reldir%/csvread.m \
   %reldir%/csvwrite.m \
   %reldir%/dlmwrite.m \
