1 // Written by Christopher E. Miller
2 // See the included license.txt for copyright and license details.
3 
4 /// Interfacing with the system clipboard for copy and paste operations.
5 module dfl.clipboard;
6 
7 import core.sys.windows.windows;
8 import core.sys.windows.objidl;
9 
10 import dfl.exception;
11 import dfl.base;
12 import dfl.data;
13 import dfl.internal.dlib;
14 
15 class Clipboard {
16    private this() {
17    }
18 
19 static:
20 
21    IDataObjectD getDataObject() {
22       IDataObject comdobj;
23       if (S_OK != OleGetClipboard(&comdobj)) {
24          throw new DflException("Unable to obtain clipboard data object");
25       }
26       if (comdobj is comd) {
27          return dd;
28       }
29       //delete dd;
30       comd = comdobj;
31       return dd = new ComToDdataObject(comdobj);
32    }
33 
34    void setDataObject(Data obj, bool persist = false) {
35       comd = null;
36       /+
37       Object ddd;
38       ddd = cast(Object)dd;
39       delete ddd;
40       +/
41       dd = null;
42       objref = null;
43 
44       if (obj.info) {
45          if (cast(TypeInfo_Class) obj.info) {
46             Object foo;
47             foo = obj.getObject();
48 
49             /+
50             if(cast(Bitmap)foo) {
51                // ...
52             } else +/
53             if (cast(IDataObjectD) foo) {
54                dd = cast(IDataObjectD) foo;
55                objref = foo;
56             } else {
57                // Can't set any old class object.
58                throw new DflException("Unknown data object");
59             }
60          } else if (obj.info == typeid(IDataObjectD)) {
61             dd = obj.getValue!(IDataObjectD)();
62             objref = cast(Object) dd;
63          } else if (cast(TypeInfo_Interface) obj.info) {
64             // Can't set any old interface.
65             throw new DflException("Unknown data object");
66          } else {
67             DataObject foo = new DataObject;
68             dd = foo;
69             objref = foo;
70             dd.setData(obj);
71          }
72 
73          assert(!(dd is null));
74          comd = new DtoComDataObject(dd);
75          if (S_OK != OleSetClipboard(comd)) {
76             comd = null;
77             //delete dd;
78             dd = null;
79             goto err_set;
80          }
81 
82          if (persist) {
83             OleFlushClipboard();
84          }
85       } else {
86          dd = null;
87          if (S_OK != OleSetClipboard(null)) {
88             goto err_set;
89          }
90       }
91 
92       return;
93    err_set:
94       throw new DflException("Unable to set clipboard data");
95    }
96 
97    void setDataObject(IDataObjectD obj, bool persist = false) {
98       setDataObject(Data(obj), persist);
99    }
100 
101    void setString(Dstring str, bool persist = false) {
102       setDataObject(Data(str), persist);
103    }
104 
105    Dstring getString() {
106       IDataObjectD ido;
107       ido = getDataObject();
108       if (ido.getDataPresent(DataFormats.utf8)) {
109          return ido.getData(DataFormats.utf8).getString();
110       }
111       return null; // ?
112    }
113 
114    // ANSI text.
115    void setText(ubyte[] ansiText, bool persist = false) {
116       setDataObject(Data(ansiText), persist);
117    }
118 
119    ubyte[] getText() {
120       IDataObjectD ido;
121       ido = getDataObject();
122       if (ido.getDataPresent(DataFormats.text)) {
123          return ido.getData(DataFormats.text).getText();
124       }
125       return null; // ?
126    }
127 
128 private:
129    IDataObject comd;
130    IDataObjectD dd;
131    Object objref; // Prevent dd from being garbage collected!
132 
133    /+
134    static ~this() {
135       Object ddd;
136       ddd = cast(Object)dd;
137       delete ddd;
138    }
139    +/
140 }