// clipboard.cpp// // Copyright (c) 2010 Accenture. All rights reserved.// This component and the accompanying materials are made available// under the terms of the "Eclipse Public License v1.0"// which accompanies this distribution, and is available// at the URL "http://www.eclipse.org/legal/epl-v10.html".// // Initial Contributors:// Accenture - Initial contribution//#include <fshell/ltkutils.h>#include <baclipb.h>#include <S32MEM.H>#include <S32UCMP.H>const TUid KClipboardUidTypePlainText = {268450333}; // from TXTETEXT.h// This could probably be optimised away, but I don't feel that confidentNONSHARABLE_CLASS(TFieldMapExternalizer) : public MExternalizer<TStreamRef> {public: TFieldMapExternalizer(const CStoreMap& aMap); void ExternalizeL(const TStreamRef& anObject,RWriteStream& aStream) const;private: const CStoreMap* iMap; };RFs OpenFsIfNeededLC(RFs* aFsPtr) { if (!aFsPtr) { RFs stackFs; CleanupClosePushL(stackFs); User::LeaveIfError(stackFs.Connect()); return stackFs; } else { CleanupStack::PushL((CBase*)NULL); // Just so the cleanup stack is the same depth in both cases - this is ok to destroy return *aFsPtr; } }EXPORT_C void LtkUtils::CopyToClipboardL(const TDesC& aText, RFs* aFs) { /* The simple way of implementing this is as follows. However this gives you a dependancy on etext.dll so is not desirable CClipboard* cb = CClipboard::NewForWritingLC(FsL()); CPlainText* text = CPlainText::NewL(); CleanupStack::PushL(text); text->InsertL(0, aText); text->CopyToStoreL(cb->Store(), cb->StreamDictionary(), 0, text->DocumentLength()); cb->CommitL(); CleanupStack::PopAndDestroy(2, cb); // text, cb */ RFs fs = OpenFsIfNeededLC(aFs); CClipboard* cb = CClipboard::NewForWritingLC(fs); CStreamStore& store = cb->Store(); CStreamDictionary& dictionary = cb->StreamDictionary(); // Following adapted from CPlainText::DoCopyToStoreL if (aText.Length()) { CStoreMap* map=CStoreMap::NewLC(store); //CopyComponentsL(aStore,*map,aPos,aLength); // create custom externalizer over the map TFieldMapExternalizer fMap(*map); RStoreWriteStream stream(fMap); TStreamId id=stream.CreateLC(store); //CopyToStreamL(stream,aPos,aLength); stream.WriteInt32L(aText.Length()); CBufFlat* textBuf = CBufFlat::NewL(256); CleanupStack::PushL(textBuf); textBuf->InsertL(0, TPtrC8((const TText8*)aText.Ptr(), aText.Size())); RBufReadStream input_stream(*textBuf, 0); TMemoryStreamUnicodeSource source(input_stream); TUnicodeCompressor c; c.CompressL(stream,source,KMaxTInt,aText.Length()); input_stream.Close(); stream.WriteUint8L(EFalse); // Indicating !fieldSetPresent CleanupStack::PopAndDestroy(textBuf); stream.CommitL(); dictionary.AssignL(KClipboardUidTypePlainText,id); map->Reset(); CleanupStack::PopAndDestroy(2); } cb->CommitL(); CleanupStack::PopAndDestroy(cb); CleanupStack::PopAndDestroy(); // stackfs }EXPORT_C HBufC* LtkUtils::GetFromClipboardL(RFs* aFs) { /* The simple way of implementing this is as follows. However this gives you a dependancy on etext.dll so is not desirable CClipboard* cb = CClipboard::NewForReadingLC(FsL()); CPlainText* text = CPlainText::NewL(); CleanupStack::PushL(text); text->PasteFromStoreL(cb->Store(), cb->StreamDictionary(), 0); HBufC* res = HBufC::NewL(text->DocumentLength()); TPtr ptr(res->Des()); text->Extract(ptr, 0); CleanupStack::PopAndDestroy(2, cb); // text, cb return res; */ RFs fs = OpenFsIfNeededLC(aFs); HBufC* result = NULL; CClipboard* cb = CClipboard::NewForReadingLC(fs); CStreamStore& store = cb->Store(); CStreamDictionary& dictionary = cb->StreamDictionary(); // Adapted from CPlainText::PasteFromStoreL, TStreamId id=dictionary.At(KClipboardUidTypePlainText); if (id != KNullStreamId) { RStoreReadStream stream; stream.OpenLC(store, id); CBufSeg* buffer = CBufSeg::NewL(512); CleanupStack::PushL(buffer); TInt length = stream.ReadInt32L(); RBufWriteStream output_stream(*buffer); TMemoryStreamUnicodeSink sink(output_stream); TUnicodeExpander e; e.ExpandL(sink,stream,length); output_stream.CommitL(); output_stream.Close(); result = HBufC::NewMaxL(buffer->Size()/sizeof(TText)); TPtr8 ptr = TPtr8((TText8*)result->Ptr(), 0, buffer->Size()); buffer->Read(0, ptr); CleanupStack::PopAndDestroy(2, &stream); // buffer, stream } CleanupStack::PopAndDestroy(cb); CleanupStack::PopAndDestroy(); // OpenFsIfNeededLC if (!result) result = KNullDesC().AllocL(); return result; }TFieldMapExternalizer::TFieldMapExternalizer(const CStoreMap& aMap) : iMap(&aMap) {}void TFieldMapExternalizer::ExternalizeL(const TStreamRef& aRef,RWriteStream& aStream) const// Write the stream id bound to aRef to aStream. If not bound, write KNullStreamId// { TSwizzleC<TAny> swizzle=aRef; aStream<<iMap->At(swizzle); }