1# Using the Delayed Copy and Paste Function of the Pasteboard 2<!--Kit: Basic Services Kit--> 3<!--Subsystem: MiscServices--> 4<!--Owner: @yangxiaodong41--> 5<!--Designer: @guo867--> 6<!--Tester: @maxiaorong2--> 7<!--Adviser: @HelloCrease--> 8 9## When to Use 10 11The [pasteboard service](../../reference/apis-basic-services-kit/js-apis-pasteboard.md) provides the capability of managing the pasteboard of the system to support the copy and paste functions of the system. 12 13When copy is performed repeatedly, redundant data is stored in the pasteboard cache, which increases the memory usage. To optimize the memory and support the paste of specified data types, the pasteboard provides the delayed copy and paste function. 14 15When a user copies data in an application that uses the delayed copy and paste function, the real data is not immediately written into the cache of the pasteboard service, but is obtained from the application when the data needs to be pasted. 16 17## Constraints 18 19- The pasteboard content, including system service metadata and application settings, has a maximum size of 128 MB by default. For PCs/2-in-1 devices, the maximum size can be changed through system settings, with a valid range from 128 MB to 2 GB. 20 21- NDK APIs support only record-level delayed copy and paste. 22 23- ArkTS APIs support only PasteData-level delayed copy and paste. 24 25## Using Record-Level Delayed Copy and Paste (Recommended) 26 27This solution allows you to query the data type before pasting. Applications can determine whether to request data from the pasteboard based on the query result. 28 29### Available APIs 30 31For details about the APIs, see [Pasteboard](../../reference/apis-basic-services-kit/capi-pasteboard.md) and [UDMF](../../reference/apis-arkdata/capi-udmf.md). 32 33| Name| Description | 34| -------- |----------------------------------------------------------------------| 35| OH_UdmfRecordProvider* OH_UdmfRecordProvider_Create() | Creates a pointer to the unified data provider instance. | 36| int OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider* provider, void* context, const OH_UdmfRecordProvider_GetData callback, const UdmfData_Finalize finalize) | Sets a callback for the unified data provider. | 37| int OH_UdmfRecord_SetProvider(OH_UdmfRecord* pThis, const char* const* types, unsigned int count, OH_UdmfRecordProvider* provider) | Sets the unified data provider in an **OH_UdmfRecord** instance. | 38| int OH_Pasteboard_SetData(OH_Pasteboard* pasteboard, OH_UdmfData* data) | Writes data to the pasteboard. | 39| OH_UdmfData * OH_Pasteboard_GetData(OH_Pasteboard* pasteboard, int* status) | Obtains data from the pasteboard.| 40| OH_UdmfRecord** OH_UdmfData_GetRecords(OH_UdmfData* pThis, unsigned int* count) | Obtains all data records from an **OH_UdmfData** instance. | 41 42### How to Develop 43 44The following uses plain text and HTML data as an example to describe how to set delayed data copy to the pasteboard service. 45 46For better code readability, the operation result verification of each step is omitted in the following code. In actual development, you need to check whether each call is successful. 47 481. Include header files. 49 50 ```c 51 #include <database/pasteboard/oh_pasteboard.h> 52 #include <database/udmf/udmf.h> 53 #include <database/udmf/udmf_meta.h> 54 #include <database/udmf/uds.h> 55 ``` 56 572. Define a data providing function for **OH_UdmfRecordProvider** and a callback function for destroying this instance. 58 59 ```c 60 // 1. Define a callback to be invoked to return the pasteboard data obtained. 61 void* GetDataCallback(void* context, const char* type) { 62 // Text 63 if (strcmp(type, UDMF_META_PLAIN_TEXT) == 0) { 64 // Create a Uds object of the plain text type. 65 OH_UdsPlainText* udsText = OH_UdsPlainText_Create(); 66 // Set the plain text content. 67 OH_UdsPlainText_SetContent(udsText, "hello world"); 68 return udsText; 69 } 70 // HTML 71 else if (strcmp(type, UDMF_META_HTML) == 0) { 72 // Create a Uds object of the HTML type. 73 OH_UdsHtml* udsHtml = OH_UdsHtml_Create(); 74 // Set the HTML content. 75 OH_UdsHtml_SetContent(udsHtml, "<div>hello world</div>"); 76 return udsHtml; 77 } 78 return nullptr; 79 } 80 // 2. Define a callback to be invoked when OH_UdmfRecordProvider is destroyed. 81 void ProviderFinalizeCallback(void* context) { 82 printf("OH_UdmfRecordProvider finalize."); 83 } 84 ``` 85 863. Prepare the data for delayed copy in the pasteboard. Note that the plain text and HTML data is not written to the pasteboard until the **GetDataCallback** function is triggered when the data user obtains **OH_UdsPlainText** or **OH_UdsHtml** from **OH_UdmfRecord**. 87 88 ```c 89 // 3. Create an OH_UdmfRecord object. 90 OH_UdmfRecord* record = OH_UdmfRecord_Create(); 91 92 // 4. Create an OH_UdmfRecordProvider object and set two callback functions used to provide and destruct data. 93 OH_UdmfRecordProvider* provider = OH_UdmfRecordProvider_Create(); 94 OH_UdmfRecordProvider_SetData(provider, (void*)record, GetDataCallback, ProviderFinalizeCallback); 95 96 // 5. Bind the provider to the record and set the supported data type. 97 const char* types[2] = { UDMF_META_PLAIN_TEXT, UDMF_META_HTML }; 98 OH_UdmfRecord_SetProvider(record, types, 2, provider); 99 100 // 6. Create an OH_UdmfData object and add OH_UdmfRecord to it. 101 OH_UdmfData* setData = OH_UdmfData_Create(); 102 OH_UdmfData_AddRecord(setData, record); 103 104 // 7. Create an OH_Pasteboard object and write data to the pasteboard. 105 OH_Pasteboard* pasteboard = OH_Pasteboard_Create(); 106 OH_Pasteboard_SetData(pasteboard, setData); 107 ``` 108 1094. Obtain the data for delayed copy from the pasteboard. 110 111 ```c 112 // 8. Obtain OH_UdmfData from the pasteboard. 113 int status = -1; 114 OH_UdmfData* getData = OH_Pasteboard_GetData(pasteboard, &status); 115 116 // 9. Obtain all OH_UdmfRecord records from OH_UdmfData. 117 unsigned int recordCount = 0; 118 OH_UdmfRecord** getRecords = OH_UdmfData_GetRecords(getData, &recordCount); 119 120 // 10. Traverse OH_UdmfRecord records. 121 for (unsigned int recordIndex = 0; recordIndex < recordCount; ++recordIndex) { 122 OH_UdmfRecord* record = getRecords[recordIndex]; 123 124 //11. Query the data types in OH_UdmfRecord. 125 unsigned typeCount = 0; 126 char** recordTypes = OH_UdmfRecord_GetTypes(record, &typeCount); 127 128 //12. Traverse data types. 129 for (unsigned int typeIndex = 0; typeIndex < typeCount; ++typeIndex) { 130 char* recordType = recordTypes[typeIndex]; 131 132 // Text 133 if (strcmp(recordType, UDMF_META_PLAIN_TEXT) == 0) { 134 // Create a Uds object of the plain text type. 135 OH_UdsPlainText* udsText = OH_UdsPlainText_Create(); 136 // Obtain the Uds object of the plain text type from record. 137 OH_UdmfRecord_GetPlainText(record, udsText); 138 // Obtain the content from the Uds object. 139 const char* content = OH_UdsPlainText_GetContent(udsText); 140 } 141 // HTML 142 else if (strcmp(recordType, UDMF_META_HTML) == 0) { 143 // Create a Uds object of the HTML type. 144 OH_UdsHtml* udsHtml = OH_UdsHtml_Create(); 145 // Obtain the Uds object of the HTML type from record. 146 OH_UdmfRecord_GetHtml(record, udsHtml); 147 // Obtain the content from the Uds object. 148 const char* content = OH_UdsHtml_GetContent(udsHtml); 149 } 150 } 151 } 152 ``` 153 1545. Release the memory after the objects are used. 155 156 ```c 157 OH_UdsPlainText_Destroy(udsText); 158 OH_UdsHtml_Destroy(udsHtml); 159 OH_UdmfRecordProvider_Destroy(provider); 160 OH_UdmfRecord_Destroy(record); 161 OH_UdmfData_Destroy(setData); 162 OH_UdmfData_Destroy(getData); 163 OH_Pasteboard_Destroy(pasteboard); 164 ``` 165 166 167## Using PasteData-Level Delayed Copy and Paste 168 169You are not allowed to query data type before pasting. 170 171### Available APIs 172 173| Name| Description | 174| -------- |----------------------------------------------------------------------| 175| setUnifiedData(data: unifiedDataChannel.UnifiedData): Promise\<void> | Writes data of the unified data type to the system pasteboard. This API cannot be called in the same thread as **getUnifiedDataSync** when the delayed copy and paste function is used.| 176| setUnifiedDataSync(data: unifiedDataChannel.UnifiedData): void | Writes data of the unified data type to the system pasteboard. This API returns the result synchronously and cannot be called in the same thread as **getUnifiedDataSync** when the delayed copy and paste function is used.| 177| getUnifiedData(): Promise\<unifiedDataChannel.UnifiedData> | Reads data of the unified data type from the system pasteboard.| 178| getUnifiedDataSync(): unifiedDataChannel.UnifiedData | Reads data of the unified data type from the pasteboard. This API returns the result synchronously and cannot be called in the same thread as **setUnifiedData** and **setUnifiedDataSync** when the delayed copy and paste function is used.| 179| setAppShareOptions(shareOptions: ShareOption): void | Sets pasteable range of pasteboard data for an application.| 180| removeAppShareOptions(): void | Removes the pasteable range configuration set by the application.| 181 182### How to Develop 183 1841. Import the **pasteboard**, **unifiedDataChannel**, and **uniformTypeDescriptor** modules. 185 186 ```ts\ 187 import {unifiedDataChannel, uniformTypeDescriptor} from '@kit.ArkData'; 188 import {BusinessError, pasteboard} from '@kit.BasicServicesKit' 189 ``` 190 1912. Construct a piece of PlainText data and write the function for obtaining the delay data. 192 193 ```ts 194 let plainTextData = new unifiedDataChannel.UnifiedData(); 195 let GetDelayPlainText = ((dataType:string) => { 196 let plainText = new unifiedDataChannel.PlainText(); 197 plainText.details = { 198 Key: 'delayPlaintext', 199 Value: 'delayPlaintext', 200 }; 201 plainText.textContent = 'delayTextContent'; 202 plainText.abstract = 'delayTextContent'; 203 plainTextData.addRecord(plainText); 204 return plainTextData; 205 }); 206 ``` 207 2083. Save a piece of PlainText data to the system pasteboard. 209 210 ```ts 211 let SetDelayPlainText = (() => { 212 plainTextData.properties.shareOptions = unifiedDataChannel.ShareOptions.CROSS_APP; 213 // For cross-application use, set this parameter to CROSS_APP. For intra-application use, set this parameter to IN_APP. 214 plainTextData.properties.getDelayData = GetDelayPlainText; 215 pasteboard.getSystemPasteboard().setUnifiedData(plainTextData).then(()=>{ 216 // The data is successfully saved, which is a normal case. 217 }).catch((error: BusinessError) => { 218 // Error case 219 }); 220 }) 221 ``` 222 2234. Read the text data from the system pasteboard. 224 225 ```ts 226 let GetPlainTextUnifiedData = (() => { 227 pasteboard.getSystemPasteboard().getUnifiedData().then((data) => { 228 let outputData = data; 229 let records = outputData.getRecords(); 230 if (records[0].getType() == uniformTypeDescriptor.UniformDataType.PLAIN_TEXT) { 231 let record = records[0] as unifiedDataChannel.PlainText; 232 console.info('GetPlainText success, type:' + records[0].getType() + ', details:' + 233 JSON.stringify(record.details) + ', textContent:' + record.textContent + ', abstract:' + record.abstract); 234 } else { 235 console.info('Get Plain Text Data No Success, Type is: ' + records[0].getType()); 236 } 237 }).catch((error: BusinessError) => { 238 // Error case 239 }) 240 }) 241 ``` 242 2435. Set pasteable range of pasteboard data for an application. 244 245 ```ts 246 let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); 247 try { 248 systemPasteboard.setAppShareOptions(pasteboard.ShareOption.INAPP); 249 console.info('Set app share options success.'); 250 } catch (err) { 251 let error: BusinessError = err as BusinessError; 252 // Error case 253 } 254 ``` 255 2566. Remove the pasteable range configuration set by the application. 257 258 ```ts 259 let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard(); 260 try { 261 systemPasteboard.removeAppShareOptions(); 262 console.info('Remove app share options success.'); 263 } catch (err) { 264 let error: BusinessError = err as BusinessError; 265 // Error case 266 } 267 ``` 268