1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <com/sun/star/datatransfer/XTransferable.hpp>
#include <unx/gtk/gtkinst.hxx>
#include "transferableprovider.hxx"
#define TRANSFERABLE_CONTENT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), transerable_content_get_type(), TransferableContent))
struct _TransferableContent
{
GdkContentProvider parent;
VclToGtkHelper* m_pConversionHelper;
css::datatransfer::XTransferable* m_pContents;
Link<void*, void> m_aDetachClipboardLink;
};
namespace
{
struct _TransferableContentClass : public GdkContentProviderClass
{
};
}
G_DEFINE_TYPE(TransferableContent, transerable_content, GDK_TYPE_CONTENT_PROVIDER)
static void transerable_content_write_mime_type_async(GdkContentProvider* provider,
const char* mime_type, GOutputStream* stream,
int io_priority, GCancellable* cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
TransferableContent* self = TRANSFERABLE_CONTENT(provider);
if (!self->m_pContents)
return;
// tdf#129809 take a reference in case m_aContents is replaced during this
// call
css::uno::Reference<css::datatransfer::XTransferable> xCurrentContents(self->m_pContents);
self->m_pConversionHelper->setSelectionData(xCurrentContents, provider, mime_type, stream,
io_priority, cancellable, callback, user_data);
}
static gboolean transerable_content_write_mime_type_finish(GdkContentProvider*,
GAsyncResult* result, GError** error)
{
return g_task_propagate_boolean(G_TASK(result), error);
}
static GdkContentFormats* transerable_content_ref_formats(GdkContentProvider* provider)
{
TransferableContent* self = TRANSFERABLE_CONTENT(provider);
css::uno::Reference<css::datatransfer::XTransferable> xCurrentContents(self->m_pContents);
if (!xCurrentContents)
return nullptr;
auto aFormats = xCurrentContents->getTransferDataFlavors();
std::vector<OString> aGtkTargets(self->m_pConversionHelper->FormatsToGtk(aFormats));
GdkContentFormatsBuilder* pBuilder = gdk_content_formats_builder_new();
for (const auto& rFormat : aGtkTargets)
gdk_content_formats_builder_add_mime_type(pBuilder, rFormat.getStr());
return gdk_content_formats_builder_free_to_formats(pBuilder);
}
static void transerable_content_detach_clipboard(GdkContentProvider* provider, GdkClipboard*)
{
TransferableContent* self = TRANSFERABLE_CONTENT(provider);
self->m_aDetachClipboardLink.Call(nullptr);
}
static void transerable_content_class_init(TransferableContentClass* klass)
{
GdkContentProviderClass* provider_class = GDK_CONTENT_PROVIDER_CLASS(klass);
provider_class->ref_formats = transerable_content_ref_formats;
provider_class->detach_clipboard = transerable_content_detach_clipboard;
provider_class->write_mime_type_async = transerable_content_write_mime_type_async;
provider_class->write_mime_type_finish = transerable_content_write_mime_type_finish;
}
static void transerable_content_init(TransferableContent* self)
{
self->m_pConversionHelper = nullptr;
self->m_pContents = nullptr;
// prevent loplugin:unreffun firing on macro generated function
(void)transerable_content_get_instance_private(self);
}
void transerable_content_set_transferable(TransferableContent* pContent,
css::datatransfer::XTransferable* pTransferable)
{
pContent->m_pContents = pTransferable;
}
void transerable_content_set_detach_clipboard_link(TransferableContent* pContent,
const Link<void*, void>& rDetachClipboardLink)
{
pContent->m_aDetachClipboardLink = rDetachClipboardLink;
}
GdkContentProvider* transerable_content_new(VclToGtkHelper* pConversionHelper,
css::datatransfer::XTransferable* pTransferable)
{
TransferableContent* content
= TRANSFERABLE_CONTENT(g_object_new(transerable_content_get_type(), nullptr));
content->m_pConversionHelper = pConversionHelper;
content->m_pContents = pTransferable;
return GDK_CONTENT_PROVIDER(content);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|