|
1 // clipboard.cpp |
|
2 // |
|
3 // Copyright (c) 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "Eclipse Public License v1.0" |
|
6 // which accompanies this distribution, and is available |
|
7 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 // |
|
9 // Initial Contributors: |
|
10 // Accenture - Initial contribution |
|
11 // |
|
12 #include <fshell/ltkutils.h> |
|
13 #include <baclipb.h> |
|
14 #include <S32MEM.H> |
|
15 #include <S32UCMP.H> |
|
16 const TUid KClipboardUidTypePlainText = {268450333}; // from TXTETEXT.h |
|
17 |
|
18 // This could probably be optimised away, but I don't feel that confident |
|
19 NONSHARABLE_CLASS(TFieldMapExternalizer) : public MExternalizer<TStreamRef> |
|
20 { |
|
21 public: |
|
22 TFieldMapExternalizer(const CStoreMap& aMap); |
|
23 void ExternalizeL(const TStreamRef& anObject,RWriteStream& aStream) const; |
|
24 private: |
|
25 const CStoreMap* iMap; |
|
26 }; |
|
27 |
|
28 RFs OpenFsIfNeededLC(RFs* aFsPtr) |
|
29 { |
|
30 if (!aFsPtr) |
|
31 { |
|
32 RFs stackFs; |
|
33 CleanupClosePushL(stackFs); |
|
34 User::LeaveIfError(stackFs.Connect()); |
|
35 return stackFs; |
|
36 } |
|
37 else |
|
38 { |
|
39 CleanupStack::PushL((CBase*)NULL); // Just so the cleanup stack is the same depth in both cases - this is ok to destroy |
|
40 return *aFsPtr; |
|
41 } |
|
42 } |
|
43 |
|
44 |
|
45 EXPORT_C void LtkUtils::CopyToClipboardL(const TDesC& aText, RFs* aFs) |
|
46 { |
|
47 /* |
|
48 The simple way of implementing this is as follows. However this gives you a dependancy on etext.dll so is not desirable |
|
49 |
|
50 CClipboard* cb = CClipboard::NewForWritingLC(FsL()); |
|
51 CPlainText* text = CPlainText::NewL(); |
|
52 CleanupStack::PushL(text); |
|
53 text->InsertL(0, aText); |
|
54 text->CopyToStoreL(cb->Store(), cb->StreamDictionary(), 0, text->DocumentLength()); |
|
55 cb->CommitL(); |
|
56 CleanupStack::PopAndDestroy(2, cb); // text, cb |
|
57 */ |
|
58 |
|
59 RFs fs = OpenFsIfNeededLC(aFs); |
|
60 CClipboard* cb = CClipboard::NewForWritingLC(fs); |
|
61 CStreamStore& store = cb->Store(); |
|
62 CStreamDictionary& dictionary = cb->StreamDictionary(); |
|
63 // Following adapted from CPlainText::DoCopyToStoreL |
|
64 if (aText.Length()) |
|
65 { |
|
66 CStoreMap* map=CStoreMap::NewLC(store); |
|
67 //CopyComponentsL(aStore,*map,aPos,aLength); |
|
68 |
|
69 // create custom externalizer over the map |
|
70 TFieldMapExternalizer fMap(*map); |
|
71 RStoreWriteStream stream(fMap); |
|
72 TStreamId id=stream.CreateLC(store); |
|
73 //CopyToStreamL(stream,aPos,aLength); |
|
74 stream.WriteInt32L(aText.Length()); |
|
75 CBufFlat* textBuf = CBufFlat::NewL(256); |
|
76 CleanupStack::PushL(textBuf); |
|
77 textBuf->InsertL(0, TPtrC8((const TText8*)aText.Ptr(), aText.Size())); |
|
78 RBufReadStream input_stream(*textBuf, 0); |
|
79 TMemoryStreamUnicodeSource source(input_stream); |
|
80 TUnicodeCompressor c; |
|
81 c.CompressL(stream,source,KMaxTInt,aText.Length()); |
|
82 input_stream.Close(); |
|
83 stream.WriteUint8L(EFalse); // Indicating !fieldSetPresent |
|
84 CleanupStack::PopAndDestroy(textBuf); |
|
85 stream.CommitL(); |
|
86 |
|
87 dictionary.AssignL(KClipboardUidTypePlainText,id); |
|
88 map->Reset(); |
|
89 CleanupStack::PopAndDestroy(2); |
|
90 } |
|
91 cb->CommitL(); |
|
92 CleanupStack::PopAndDestroy(cb); |
|
93 CleanupStack::PopAndDestroy(); // stackfs |
|
94 } |
|
95 |
|
96 EXPORT_C HBufC* LtkUtils::GetFromClipboardL(RFs* aFs) |
|
97 { |
|
98 /* |
|
99 The simple way of implementing this is as follows. However this gives you a dependancy on etext.dll so is not desirable |
|
100 |
|
101 CClipboard* cb = CClipboard::NewForReadingLC(FsL()); |
|
102 CPlainText* text = CPlainText::NewL(); |
|
103 CleanupStack::PushL(text); |
|
104 text->PasteFromStoreL(cb->Store(), cb->StreamDictionary(), 0); |
|
105 HBufC* res = HBufC::NewL(text->DocumentLength()); |
|
106 TPtr ptr(res->Des()); |
|
107 text->Extract(ptr, 0); |
|
108 CleanupStack::PopAndDestroy(2, cb); // text, cb |
|
109 return res; |
|
110 */ |
|
111 |
|
112 RFs fs = OpenFsIfNeededLC(aFs); |
|
113 HBufC* result = NULL; |
|
114 CClipboard* cb = CClipboard::NewForReadingLC(fs); |
|
115 CStreamStore& store = cb->Store(); |
|
116 CStreamDictionary& dictionary = cb->StreamDictionary(); |
|
117 |
|
118 // Adapted from CPlainText::PasteFromStoreL, |
|
119 TStreamId id=dictionary.At(KClipboardUidTypePlainText); |
|
120 if (id != KNullStreamId) |
|
121 { |
|
122 RStoreReadStream stream; |
|
123 stream.OpenLC(store, id); |
|
124 CBufSeg* buffer = CBufSeg::NewL(512); |
|
125 CleanupStack::PushL(buffer); |
|
126 TInt length = stream.ReadInt32L(); |
|
127 RBufWriteStream output_stream(*buffer); |
|
128 TMemoryStreamUnicodeSink sink(output_stream); |
|
129 TUnicodeExpander e; |
|
130 e.ExpandL(sink,stream,length); |
|
131 output_stream.CommitL(); |
|
132 output_stream.Close(); |
|
133 |
|
134 result = HBufC::NewMaxL(buffer->Size()/sizeof(TText)); |
|
135 TPtr8 ptr = TPtr8((TText8*)result->Ptr(), 0, buffer->Size()); |
|
136 buffer->Read(0, ptr); |
|
137 |
|
138 CleanupStack::PopAndDestroy(2, &stream); // buffer, stream |
|
139 } |
|
140 |
|
141 CleanupStack::PopAndDestroy(cb); |
|
142 CleanupStack::PopAndDestroy(); // OpenFsIfNeededLC |
|
143 if (!result) result = KNullDesC().AllocL(); |
|
144 return result; |
|
145 } |
|
146 |
|
147 |
|
148 TFieldMapExternalizer::TFieldMapExternalizer(const CStoreMap& aMap) |
|
149 : iMap(&aMap) |
|
150 {} |
|
151 |
|
152 void TFieldMapExternalizer::ExternalizeL(const TStreamRef& aRef,RWriteStream& aStream) const |
|
153 // Write the stream id bound to aRef to aStream. If not bound, write KNullStreamId |
|
154 // |
|
155 { |
|
156 TSwizzleC<TAny> swizzle=aRef; |
|
157 aStream<<iMap->At(swizzle); |
|
158 } |