|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-E180D222-CC4F-5007-93FC-C339BBE708BC" xml:lang="en"><title>Client |
|
13 MTM</title><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>Client MTMs provide a client-side API to functionality provided by the |
|
15 Server MTM, mainly for message manipulation and transport. It acts as the |
|
16 interface between the internal representation of a message’s data and the |
|
17 User Interface (UI) MTM. This architecture provides certain advantages; for |
|
18 example, a UI MTM can offer a user interface to enter message addresses without |
|
19 knowing the address storage format. Message client applications that do not |
|
20 require a user interface can use these client-side functions directly for |
|
21 automated message handling. </p> |
|
22 <p>The Message Server entry with which Client MTMs currently work is referred |
|
23 to as the context. UI MTMs always operate on the contexts set through Client |
|
24 MTMs. </p> |
|
25 <p>Client MTMs offer some or all of the following capabilities: </p> |
|
26 <ul> |
|
27 <li id="GUID-4327B533-04C0-5110-B8AD-90EC90C73D32"><p>Address list manipulation </p> </li> |
|
28 <li id="GUID-FC4908FC-5958-5815-90EB-D601B4710247"><p>Creation of forward |
|
29 and response messages </p> </li> |
|
30 <li id="GUID-CF8196EB-1C40-50D0-86AA-0F2C954CBC5D"><p>Message subject access </p> </li> |
|
31 <li id="GUID-51B25D57-A577-5375-9DD6-D398C8B860A8"><p>Message validation </p> </li> |
|
32 <li id="GUID-4345AB18-2096-5312-955D-EACE72DCA52F"><p>Internalising and externalising |
|
33 MTM-specific data to the Message Store </p> </li> |
|
34 </ul> |
|
35 <section id="GUID-BCFBE2C5-2C90-5E43-9B21-0D80A469CEAB"><title>Client MTM |
|
36 base class</title> <p>The base class for Client MTMs is <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita"><apiname>CBaseMtm</apiname></xref> which |
|
37 provides a high-level interface for accessing and manipulating a Message Server |
|
38 entry </p> <p>The following are some significant functions in <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita"><apiname>CBaseMtm</apiname></xref>. |
|
39 Some functions are implemented by the base class, and others must be implemented |
|
40 in a derived class: </p> <ul> |
|
41 <li id="GUID-8E6AB26D-BDD2-5D5E-BEDD-5371EE86834D"><p> <b>Context functions</b> </p> <p>The <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-00C140DE-012F-3785-A628-E8D1330438B8"><apiname>CBaseMtm::SetCurrentEntryL</apiname></xref> <codeph>(CMsvEntry *)</codeph> and <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-016A5DFD-5C88-3531-A5F3-456884CAC041"><apiname>CBaseMtm::SwitchCurrentEntryL</apiname></xref> <codeph>(TMsvId)</codeph> functions |
|
42 change the Message Server entry (the context) on which later actions are performed. |
|
43 After creating a new Client MTM object, a message client application must |
|
44 set an initial context before using other functions. </p> </li> |
|
45 <li id="GUID-1E3E98F7-FBBF-5594-A7EF-93D7106FD3D3"><p> <b>Store and restore |
|
46 entry data functions</b> </p> <p>The changes that a message client application |
|
47 makes to a message context through Client MTM functions, such as altering |
|
48 the body text obtained through <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-072E627F-8AB4-3C90-AD48-A5AF6A39581B"><apiname>CBaseMtm::Body()</apiname></xref>, are, for |
|
49 efficiency, cached in memory by a Client MTM. The message store (<xref href="GUID-A0F2B215-C453-3CB8-A659-29CB0B4CF0A7.dita"><apiname>SaveMessageL()</apiname></xref>)and |
|
50 restore (<xref href="GUID-DF6E56F8-3B05-3D34-8500-BDA77BABD05D.dita"><apiname>LoadMessageL()</apiname></xref>), functions are concerned with |
|
51 transferring data between that cache and committed storage. </p> <p> <b>Note:</b> Unlike |
|
52 message contexts, message client applications are not expected to manipulate |
|
53 directly contexts for message services. Instead, the corresponding <xref href="GUID-C197C9A7-EA05-3F24-9854-542E984C612D.dita"><apiname>User</apiname></xref> Interface |
|
54 MTM provides a dialog to allow the user to alter service settings, and calls |
|
55 Client MTM functions to handle their retrieval and storage. </p> </li> |
|
56 <li id="GUID-A0FDCB02-3C4E-5CB0-A374-61C89889621B"><p> <b>Store and restore |
|
57 body text functions</b> </p> <p>The base class maintains a private <xref href="GUID-39945DA4-B362-3DF6-BF9E-DD079EEA7934.dita"><apiname>CRichText</apiname></xref> object |
|
58 cache to store the body text for the current context. This can be accessed |
|
59 for reading and writing by message client applications through <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-072E627F-8AB4-3C90-AD48-A5AF6A39581B"><apiname>CBaseMtm::Body()</apiname></xref>. |
|
60 The <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-A036C34A-EFB9-3E98-983B-0DFF1EE8CD85"><apiname>CBaseMtm::StoreBodyL()</apiname></xref> <codeph>(CMsvStore &)</codeph> and <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-43AF1C02-C435-3450-A549-8AECE9F6CAB0"><apiname>CBaseMtm::RestoreBodyL()</apiname></xref> <codeph>(CMsvStore |
|
61 &)</codeph> functions encapsulate the retrieval and storage of this <xref href="GUID-39945DA4-B362-3DF6-BF9E-DD079EEA7934.dita"><apiname>CRichText</apiname></xref> object |
|
62 to a <xref href="GUID-8CB90FA2-A6CF-3FA2-81FF-7D22EFD9C2CE.dita"><apiname>CMsvStore</apiname></xref>. </p> </li> |
|
63 <li id="GUID-B44CFD8D-DB97-5A4D-B876-EA04D464A5B1"><p> <b>Address list functions</b> </p> <p>The |
|
64 format and storage of message addresses is MTM-specific. The <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-51A8768D-684A-3668-98BF-AB88D676DEB5"><apiname>CBaseMtm::AddresseeList()</apiname></xref> <codeph>const</codeph>, <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-D3DFE444-DB84-331C-BC3F-AB12E148CD00"><apiname>CBaseMtm::AddAddresseeL</apiname></xref> <codeph>(const TDesC &)</codeph>, and <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-770E749C-BA7F-3F31-B7B8-F2C21F4F06A1"><apiname>CBaseMtm::RemoveAddressee</apiname></xref> <codeph>(TInt)</codeph> allow |
|
65 clients to access address information in a generic way without having MTM-specific |
|
66 knowledge. </p> </li> |
|
67 <li id="GUID-F1E2AAD3-41E0-522A-B7AC-7090EE823807"><p> <b>MTM-specific client |
|
68 functions</b> </p> <p>MTM components can offer protocol-specific functionality |
|
69 not provided by base class interface functions. MTM components define IDs |
|
70 that correspond to each protocol-specific operation offered, and implement |
|
71 the <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-A5B6CDAC-7C02-35F4-840E-35932B438FD8"><apiname>CBaseMtm::InvokeSyncFunctionL()</apiname></xref> and <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita#GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D/GUID-05327221-98A9-35FA-BD28-D6323BE449D1"><apiname>CBaseMtm::InvokeAsyncFunctionL()</apiname></xref> functions |
|
72 to allow clients to access these operations by passing in the appropriate |
|
73 ID. These functions are provided to allow the MTM component to offer both |
|
74 synchronous and asynchronous functionality. Message client applications can |
|
75 dynamically add user-interface features for these operations using <xref href="GUID-899C6D87-5712-34A7-902C-EA452894700C.dita#GUID-899C6D87-5712-34A7-902C-EA452894700C/GUID-75DE35D7-4738-38C0-9BFA-A066F67B114B"><apiname>CBaseMtmUiData::MtmSpecificFunctions()</apiname></xref>. </p> </li> |
|
76 <li id="GUID-A4A3ED85-EAC5-58BC-BB40-E40949A84B66"><p> <b>Query function</b> </p> <p>The |
|
77 Client MTM <xref href="GUID-E32E2F1C-62C5-3635-BA60-3E547C32DB9C.dita"><apiname>QueryCapability()</apiname></xref> function is used to inquire |
|
78 whether an MTM supports a given feature. The first argument is a UID defined |
|
79 to correspond to a particular capability. The function returns a system error |
|
80 code and the response (whether the MTM supports the queried capability) is |
|
81 passed back through the second (by-reference)<codeph>aResponse</codeph> parameter. |
|
82 This value can be an integer or a bit set, depending on the capability. </p> <p>The |
|
83 UIDs for the different types of query are as follows: </p> <table id="GUID-6ADE624E-8B18-58F9-9386-79A75E72E0C7"> |
|
84 <tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/> |
|
85 <thead> |
|
86 <row> |
|
87 <entry>UID</entry> |
|
88 <entry>Capability</entry> |
|
89 </row> |
|
90 </thead> |
|
91 <tbody> |
|
92 <row> |
|
93 <entry><p> <codeph>KUidMsvMtmQueryMaxBodySize</codeph> </p> </entry> |
|
94 <entry><p>Maximum message body size </p> </entry> |
|
95 </row> |
|
96 <row> |
|
97 <entry><p> <codeph>KUidMtmQueryMaxTotalMsgSize</codeph> </p> </entry> |
|
98 <entry><p>Maximum total size of message. </p> </entry> |
|
99 </row> |
|
100 <row> |
|
101 <entry><p> <codeph> KUidMtmQuerySupportedBody</codeph> </p> </entry> |
|
102 <entry><p>Character widths supported by message type. The returned value is |
|
103 the sum of the appropriate values. The return type is either of KMtm7BitBody, |
|
104 KMtm8BitBody, KMtm16BitBody, and KMtmBinaryBody) </p> </entry> |
|
105 </row> |
|
106 <row> |
|
107 <entry><p> <codeph> KUidMtmQuerySupportAttachments</codeph> </p> </entry> |
|
108 <entry><p>To check if the attachments are supported </p> </entry> |
|
109 </row> |
|
110 <row> |
|
111 <entry><p> <codeph>KUidMtmQuerySupportSubject</codeph> </p> </entry> |
|
112 <entry><p>Does the MTM message type have a subject field </p> </entry> |
|
113 </row> |
|
114 <row> |
|
115 <entry><p> <codeph> KUidMtmQuerySupportsFolder</codeph> </p> </entry> |
|
116 <entry><p>Does the MTM support folders </p> </entry> |
|
117 </row> |
|
118 <row> |
|
119 <entry><p> <codeph> KUidMtmQueryOffLineAllowed</codeph> </p> </entry> |
|
120 <entry><p>Off-line operation allowed </p> </entry> |
|
121 </row> |
|
122 <row> |
|
123 <entry><p> <codeph>KUidMtmQueryCanSendMsg</codeph> </p> </entry> |
|
124 <entry><p>Can send the message </p> </entry> |
|
125 </row> |
|
126 <row> |
|
127 <entry><p> <codeph>KUidMtmQueryCanReceiveMsg</codeph> </p> </entry> |
|
128 <entry><p>Can receive the message </p> </entry> |
|
129 </row> |
|
130 <row> |
|
131 <entry><p> <codeph>KUidMtmQueryMaxRecipientCount</codeph> </p> </entry> |
|
132 <entry><p>Maximum number of recipients (-1 indicates unlimited numbers). </p> </entry> |
|
133 </row> |
|
134 <row> |
|
135 <entry><p> <codeph>KUidMtmQuerySendAsRequiresRenderedImage</codeph> </p> </entry> |
|
136 <entry><p>When using the MTM in Send As, does a rendered image have to be |
|
137 prepared. </p> </entry> |
|
138 </row> |
|
139 <row> |
|
140 <entry><p> <codeph> KUidMtmQuerySendAsRenderingUid</codeph> </p> </entry> |
|
141 <entry><p>Printer driver UID for rendering the fax image. </p> </entry> |
|
142 </row> |
|
143 <row> |
|
144 <entry><p> <codeph>KUidMsvMtmQueryEditorUid</codeph> </p> </entry> |
|
145 <entry><p>UID of default message editor. </p> </entry> |
|
146 </row> |
|
147 <row> |
|
148 <entry><p> <codeph>KUidMsvQuerySupportsBioMsg</codeph> </p> </entry> |
|
149 <entry><p>Does the MTM support BIO messages </p> </entry> |
|
150 </row> |
|
151 <row> |
|
152 <entry><p> <codeph> KUidMsvQuerySupportsScheduling</codeph> </p> </entry> |
|
153 <entry><p>Does the MTM support scheduled sending. </p> </entry> |
|
154 </row> |
|
155 <row> |
|
156 <entry><p> <codeph>KUidMtmQuerySupportsRecipientType</codeph> </p> </entry> |
|
157 <entry><p>Does the MTM support the use of recipient type. </p> </entry> |
|
158 </row> |
|
159 <row> |
|
160 <entry><p> <codeph>KUidMtmQuerySendAsMessageSendSupport</codeph> </p> </entry> |
|
161 <entry><p>Support for Sending messages using SendAs. </p> <p>If this is supported, |
|
162 then the MTM supports sending messages created through the SendAs API. </p> </entry> |
|
163 </row> |
|
164 </tbody> |
|
165 </tgroup> |
|
166 </table> <p>The following example is a snapshot of the Text MTM example. For |
|
167 more implementation details, see <xref href="GUID-5B9F2EEE-A5F6-5833-BFC4-3B063EA7EDF2.dita">Messaging |
|
168 Text MTM example code</xref>. </p> <codeblock id="GUID-375C5493-8DAA-5B2D-B371-B7FD7DC2CCD1" xml:space="preserve">TInt CTextMtmClient::QueryCapability(TUid aCapability, TInt& aResponse) |
|
169 { |
|
170 TInt error = KErrNone; |
|
171 switch (aCapability.iUid) |
|
172 { |
|
173 case KUidMtmQueryMaxBodySizeValue: |
|
174 case KUidMtmQueryMaxTotalMsgSizeValue: |
|
175 aResponse = KMaxTextMessageSize; |
|
176 break; |
|
177 case KUidMtmQuerySupportedBodyValue: |
|
178 aResponse = KMtm8BitBody + KMtm7BitBody; |
|
179 break; |
|
180 case KUidMtmQueryOffLineAllowedValue: |
|
181 case KUidMtmQueryCanReceiveMsgValue: |
|
182 aResponse = ETrue; |
|
183 break; |
|
184 case KUidMtmQuerySupportAttachmentsValue: |
|
185 default: |
|
186 return KErrNotSupported; |
|
187 } |
|
188 return error; |
|
189 } |
|
190 </codeblock> </li> |
|
191 </ul> <p>The <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita"><apiname>CBaseMtm</apiname></xref> class provides the virtual functions |
|
192 for overriding in derived classes. </p> </section> |
|
193 <section id="GUID-6DD0912E-1E82-5BAD-889C-5FA79E5E800C"><title>Client-side |
|
194 operations</title> <p>Many Messaging tasks can take a long time to complete. |
|
195 For example, sending all items from the Outbox or downloading a large number |
|
196 of items from a POP3 server. In these situations, the use of active objects |
|
197 to wait for the completion of the task is inadequate, since applications also |
|
198 require to obtain progress information while the task is running (for example, |
|
199 to update a progress dialog). To solve this problem, most asynchronous functions |
|
200 in Messaging create a <xref href="GUID-AF724192-6580-3DE3-9287-3A005C0AA932.dita"><apiname>CMsvOperation</apiname></xref> object and return a |
|
201 pointer to it, as well as taking a <codeph>TRequestStatus&</codeph> parameter. |
|
202 The <xref href="GUID-AF724192-6580-3DE3-9287-3A005C0AA932.dita"><apiname>CMsvOperation</apiname></xref> class is derived from <xref href="GUID-067293BF-B28C-3CEC-92F4-1351A795EA7F.dita"><apiname>CActive</apiname></xref> and |
|
203 is used to obtain progress information about a long-running task. </p> <p>The |
|
204 base class for all client-side Messaging operations is <xref href="GUID-AF724192-6580-3DE3-9287-3A005C0AA932.dita"><apiname>CMsvOperation</apiname></xref>. |
|
205 The asynchronous methods in the <xref href="GUID-177AF50B-14EF-3C45-AE22-1FEE5678261D.dita"><apiname>CBaseMtm </apiname></xref> interface all |
|
206 return a pointer to a <xref href="GUID-AF724192-6580-3DE3-9287-3A005C0AA932.dita"><apiname>CMsvOperation</apiname></xref> object. When you implement |
|
207 an MTM, you will have to provide your own custom operations, derived from <xref href="GUID-AF724192-6580-3DE3-9287-3A005C0AA932.dita"><apiname>CMsvOperation</apiname></xref>, |
|
208 and return those polymorphically from your implementations of the asynchronous |
|
209 APIs. </p> <p><b>Example</b> </p> <p>The forward operation of the Text MTM |
|
210 is explained in the following example. </p> <p>The forward operation is an |
|
211 active object state machine that runs a series of asynchronous tasks one after |
|
212 another and waits for each to complete before moving on to the next. After |
|
213 the operation has been completed, an active object is notified through its <codeph>TRequestStatus</codeph> passed |
|
214 into the operation at construction. </p> <p>The forward operation is constructed |
|
215 using standard two-phase construction. The <xref href="GUID-93132FF9-512F-30EC-8AB0-BD3E98F668E6.dita"><apiname>NewL()</apiname></xref> function |
|
216 takes two arguments of a <xref href="GUID-A4B1F874-27C0-3BB6-9D29-C35C75A5DB98.dita"><apiname>TMsvId</apiname></xref> (source message and destination |
|
217 folder) type, a <xref href="GUID-2DA04D96-F0AD-3FDC-9E36-1C27D889AF4B.dita"><apiname>CMsvSession</apiname></xref> reference, and the observer’s <codeph>TRequestStatus</codeph>, |
|
218 which is notified on completion. The active object is constructed and added |
|
219 to the scheduler, and then <xref href="GUID-C8E0575D-5A7F-3D00-9BE5-AD8D6DBCF2F7.dita"><apiname>ConstructL()</apiname></xref> is called: </p> <codeblock id="GUID-C046D5BB-A157-5F5D-9702-C9ED271B89E8" xml:space="preserve">void CTxtMtmForwardOperation::ConstructL() |
|
220 { |
|
221 iObserverRequestStatus = KRequestPending; |
|
222 SetActive(); |
|
223 TRequestStatus* stat = &iStatus; |
|
224 User::RequestComplete(stat, KErrNone); |
|
225 } |
|
226 </codeblock> <p>This has the effect of marking this stage of the operation |
|
227 as complete and means that <xref href="GUID-12C281FF-546C-318D-8783-F26B0F619E11.dita"><apiname>RunL()</apiname></xref> is called at the next |
|
228 opportunity. This simplifies the state machine because it means that all states |
|
229 and tasks are started in <xref href="GUID-12C281FF-546C-318D-8783-F26B0F619E11.dita"><apiname>RunL()</apiname></xref> and not in <xref href="GUID-C8E0575D-5A7F-3D00-9BE5-AD8D6DBCF2F7.dita"><apiname>ConstructL()</apiname></xref>. </p> <p>The <xref href="GUID-12C281FF-546C-318D-8783-F26B0F619E11.dita"><apiname>RunL()</apiname></xref> function |
|
230 starts each task and receives a notification when it completes. The current |
|
231 task being executed is stored in <xref href="GUID-51087246-DDFF-384B-9DB6-2525F8C73CA5.dita"><apiname>iProgress</apiname></xref> and <xref href="GUID-A36DDD59-6236-3549-9DEB-8BE1F402CB16.dita"><apiname>iState</apiname></xref>, |
|
232 as are the errors and the ID of the new forwarded message, once complete. |
|
233 The default state for <xref href="GUID-A36DDD59-6236-3549-9DEB-8BE1F402CB16.dita"><apiname>iState</apiname></xref> on construction is <codeph>EInit</codeph>. </p> <codeblock id="GUID-B223CED8-8391-5825-BAC7-E81ED08C7E7E" xml:space="preserve">void CTxtMtmForwardOperation::RunL() |
|
234 { |
|
235 User::LeaveIfError(iStatus.Int()); |
|
236 switch(iProgress.iState) |
|
237 { |
|
238 case TTxtMtmForwardOpProgress::EInit: |
|
239 iProgress.iState = |
|
240 TTxtMtmForwardOpProgress::ECreateMessage; |
|
241 CreateMessageL(); |
|
242 break; |
|
243 |
|
244 case TTxtMtmForwardOpProgress::ECreateMessage: |
|
245 iProgress.iState = |
|
246 TTxtMtmForwardOpProgress::EFormatBodyText; |
|
247 FormatBodyTextL(); |
|
248 break; |
|
249 |
|
250 case TTxtMtmForwardOpProgress::EFormatBodyText: |
|
251 iProgress.iState = |
|
252 TTxtMtmForwardOpProgress::EFinished; |
|
253 |
|
254 default: |
|
255 break; |
|
256 } |
|
257 if(!IsActive()) |
|
258 { |
|
259 TRequestStatus* stat = &iObserverRequestStatus; |
|
260 User::RequestComplete(stat, KErrNone); |
|
261 } |
|
262 } |
|
263 </codeblock> <p>If the state is <codeph>EInit</codeph>, the <xref href="GUID-12C281FF-546C-318D-8783-F26B0F619E11.dita"><apiname>RunL()</apiname></xref> changes |
|
264 state to <codeph>ECreateMessage</codeph> and then calls <xref href="GUID-E1D580C2-8B05-3A9E-8157-A3F849811AAB.dita"><apiname>CreateMessageL()</apiname></xref> to |
|
265 start the process of creating a message asynchronously. </p> <codeblock id="GUID-69C1C1DB-8813-56DC-8BDF-BF8B13D43583" xml:space="preserve">void CTxtMtmForwardOperation::CreateMessageL() |
|
266 { |
|
267 </codeblock> <p>The function constructs a <xref href="GUID-85BBE389-81F7-3E2F-A789-446D9BE2CC49.dita"><apiname>CMsvEntry</apiname></xref> for |
|
268 the source entry and then retrieves its index entry. </p> <codeblock id="GUID-5E1A2C12-832E-54BF-91A4-9755348FD298" xml:space="preserve">delete iMsvEntry; |
|
269 iMsvEntry = NULL; |
|
270 iMsvEntry = iMsvSession.GetEntryL(iSourceMessage); |
|
271 |
|
272 // Get the entry to be forwarded |
|
273 TMsvEntry forwardEntry = iMsvEntry->Entry(); |
|
274 </codeblock> <p>The context of <xref href="GUID-55F14844-0FCB-380C-B797-956CA2B2CFE2.dita"><apiname>iMsvEntry</apiname></xref> is changed to |
|
275 the destination folder and an entry is created. </p> <codeblock id="GUID-ECBE0131-DCC1-5182-B8D9-DBA35F4FD42A" xml:space="preserve">// Set the context to the destination folder |
|
276 iMsvEntry->SetEntryL(iDestinationFolder); |
|
277 </codeblock> <p>The index entry’s date is updated to reflect the current date. </p> <codeblock id="GUID-B7156135-805B-509E-8778-EA17E5B69AE6" xml:space="preserve">// Create the forwarded index entry |
|
278 forwardEntry.iDate.HomeTime(); |
|
279 iMsvEntry->CreateL(forwardEntry); |
|
280 </codeblock> <p>The <xref href="GUID-CAE27183-B48C-3B02-A88D-98CC51475DC0.dita"><apiname>iFinalMsgId</apiname></xref> member of the progress |
|
281 is updated to reflect the newly created entry. </p> <codeblock id="GUID-2C15F0E2-64C9-507B-8997-D257DACE0EEB" xml:space="preserve">iProgress.iFinalMsgId = forwardEntry.Id(); |
|
282 |
|
283 // schedules the active object to complete so that this |
|
284 // class's RunL method |
|
285 // will be called by the active scheduler |
|
286 SetActive(); |
|
287 </codeblock> <p>The operation’s <codeph>TRequestStatus</codeph> is then flagged |
|
288 to cause <xref href="GUID-12C281FF-546C-318D-8783-F26B0F619E11.dita"><apiname>RunL()</apiname></xref>. </p> <codeblock id="GUID-971DFF4A-E78F-5EBD-8DFB-616DA421E521" xml:space="preserve">TRequestStatus* stat = &iStatus; |
|
289 User::RequestComplete(stat, KErrNone); |
|
290 } |
|
291 </codeblock> <p>When this happens,<codeph> iProgress.iState</codeph> is set |
|
292 to <codeph>ECreateMessage</codeph>, so the following code is executed: </p> <codeblock id="GUID-1AA9893A-2CAA-5E64-A09A-E20689B38BAF" xml:space="preserve">case TTxtMtmForwardOpProgress::ECreateMessage: |
|
293 iProgress.iState = TTxtMtmForwardOpProgress::EFormatBodyText; |
|
294 FormatBodyTextL(); |
|
295 break;</codeblock> <p>The state is set to <codeph>EFormatBodyText</codeph> and |
|
296 the <xref href="GUID-FC4144F7-9D46-3D30-8316-ED22170E37B0.dita"><apiname>FormatBodyTextL()</apiname></xref> function is called. </p> <codeblock id="GUID-51C72DF8-9F39-51EA-BFFC-E4793A7B6621" xml:space="preserve"> |
|
297 void CTxtMtmForwardOperation::FormatBodyTextL() |
|
298 { |
|
299 </codeblock> <p>The function constructs a <xref href="GUID-C5A6B3D4-1BDE-35B4-AC6B-DF517A4D4147.dita"><apiname>CParaFormatLayer</apiname></xref>, |
|
300 a <xref href="GUID-7BEFAAD5-15C3-35A0-BDEF-BC56380D6CE5.dita"><apiname>CCharFormatLayer</apiname></xref>, and a <xref href="GUID-39945DA4-B362-3DF6-BF9E-DD079EEA7934.dita"><apiname>CRichText</apiname></xref> object. |
|
301 These objects are required to store the body text of the forwarded message. </p> <codeblock id="GUID-D02202DB-9E19-5873-86D6-6B0DCF035B74" xml:space="preserve">CParaFormatLayer* paraLayer = CParaFormatLayer::NewL(); |
|
302 CleanupStack::PushL(paraLayer); |
|
303 CCharFormatLayer* charLayer = CCharFormatLayer::NewL(); |
|
304 CleanupStack::PushL(charLayer); |
|
305 CRichText* body = CRichText::NewL(paraLayer, charLayer); |
|
306 CleanupStack::PushL(body); |
|
307 </codeblock> <p>Then the context of <codeph>iMsvEntry</codeph> is changed |
|
308 to point at the source message and a read-only <xref href="GUID-8CB90FA2-A6CF-3FA2-81FF-7D22EFD9C2CE.dita"><apiname>CMsvStore</apiname></xref> is |
|
309 opened for that entry. </p> <codeblock id="GUID-F3B582CD-867C-54FD-ACAB-0F50319601BC" xml:space="preserve">// Get the message store from the source entry |
|
310 iMsvEntry->SetEntryL(iSourceMessage); |
|
311 CMsvStore* readStore = iMsvEntry->ReadStoreL(); |
|
312 CleanupStack::PushL(readStore);</codeblock> <p>The context of the <xref href="GUID-55F14844-0FCB-380C-B797-956CA2B2CFE2.dita"><apiname>iMsvEntry</apiname></xref> object |
|
313 is changed to point at the newly created entry and a <xref href="GUID-8CB90FA2-A6CF-3FA2-81FF-7D22EFD9C2CE.dita"><apiname>CMsvStore</apiname></xref> is |
|
314 opened for that entry. </p> <codeblock id="GUID-097EC5DB-9FCB-5D45-8B94-8E7DB5256005" xml:space="preserve">// Get the message store from the newly created destination |
|
315 // entry |
|
316 iMsvEntry->SetEntryL(iProgress.iFinalMsgId); |
|
317 CMsvStore* writeStore = iMsvEntry->EditStoreL(); |
|
318 CleanupStack::PushL(writeStore); |
|
319 |
|
320 // Get the body text from the source entry and write it |
|
321 // to the destination entry, prepending the forward |
|
322 // prefix |
|
323 readStore->RestoreBodyTextL(*body); |
|
324 body->InsertL(0, KTxtMtmFwdPrefix); |
|
325 |
|
326 // this method performs a commit for us |
|
327 writeStore->StoreBodyTextL(*body); |
|
328 |
|
329 CleanupStack::PopAndDestroy(5, paraLayer); |
|
330 |
|
331 // schedules the active object to complete so that this |
|
332 // class's RunL method |
|
333 // will be called by the active scheduler |
|
334 SetActive(); |
|
335 TRequestStatus* stat = &iStatus; |
|
336 User::RequestComplete(stat, KErrNone); |
|
337 } |
|
338 </codeblock> <p>The <codeph>iProgress.iState</codeph> is set to <codeph>EFinished</codeph>, |
|
339 and because the object has not been activated the following conditional statement |
|
340 evaluates true: </p> <codeblock id="GUID-9CC7BAD3-B185-59F4-8CED-7BE23886661A" xml:space="preserve">if(!IsActive()) |
|
341 { |
|
342 TRequestStatus* stat = &iObserverRequestStatus; |
|
343 User::RequestComplete(stat, KErrNone); |
|
344 } |
|
345 </codeblock> <p>The observer active object’s <codeph>TRequestStatus</codeph> is |
|
346 flagged to let it know that the operation is complete. </p> <p>To return progress |
|
347 from the operation, implement the <xref href="GUID-E13013FF-09B9-3A9A-B471-0A9AE90E49EC.dita"><apiname>ProgressL()</apiname></xref> and <xref href="GUID-890A4968-EAD6-30F5-97D8-E6C07BA28B37.dita"><apiname>FinalProgress()</apiname></xref> functions. <xref href="GUID-E13013FF-09B9-3A9A-B471-0A9AE90E49EC.dita"><apiname>ProgressL()</apiname></xref> must |
|
348 be used to return progress information on the operation during processing, |
|
349 and <xref href="GUID-890A4968-EAD6-30F5-97D8-E6C07BA28B37.dita"><apiname>FinalProgress()</apiname></xref> is guaranteed to return the status |
|
350 of a completed operation. <xref href="GUID-E13013FF-09B9-3A9A-B471-0A9AE90E49EC.dita"><apiname>ProgressL()</apiname></xref> must be implemented |
|
351 to leave with <codeph>KErrNotReady</codeph> if the operation is not in progress, |
|
352 and <xref href="GUID-890A4968-EAD6-30F5-97D8-E6C07BA28B37.dita"><apiname>FinalProgress()</apiname></xref> must panic if the operation is not |
|
353 complete. </p> <codeblock id="GUID-4EAE052A-F445-589E-8B6A-983A579FBAE6" xml:space="preserve">const TDesC8& CTxtMtmForwardOperation::ProgressL() |
|
354 { |
|
355 if (!IsActive()) |
|
356 { |
|
357 User::Leave(KErrNotReady); |
|
358 } |
|
359 iProgressBuf() = iProgress; |
|
360 return iProgressBuf; |
|
361 } |
|
362 |
|
363 const TDesC8& CTxtMtmForwardOperation::FinalProgress() |
|
364 { |
|
365 __ASSERT_ALWAYS(!IsActive(), User::Panic(KTxtCPanic, |
|
366 ETxtcOperationIsActive)); |
|
367 iProgressBuf() = iProgress; |
|
368 return iProgressBuf; |
|
369 }</codeblock> <p>The <xref href="GUID-189483E6-31EA-32DF-8CD5-ECE58592DB3E.dita"><apiname>RunError()</apiname></xref> function must also be |
|
370 implemented to get any leaves in <xref href="GUID-12C281FF-546C-318D-8783-F26B0F619E11.dita"><apiname>RunL()</apiname></xref>. </p> <codeblock id="GUID-D41E3F81-83E2-5F9C-BDB0-A97A4D9920A6" xml:space="preserve">TInt CTxtMtmForwardOperation::RunError(TInt aError) |
|
371 { |
|
372 iProgress.iError = aError; |
|
373 TRequestStatus* stat = &iObserverRequestStatus; |
|
374 User::RequestComplete(stat, aError); |
|
375 return KErrNone; |
|
376 }</codeblock> </section> |
|
377 </conbody><related-links> |
|
378 <link href="GUID-59217FA7-3078-53CA-88B3-78D6FB788271.dita"><linktext>MTM overview</linktext> |
|
379 </link> |
|
380 <link href="GUID-BAD138D5-2914-5C6E-9FA4-F7A3CCB85E6D.dita"><linktext>MTM Capabilities</linktext> |
|
381 </link> |
|
382 <link href="GUID-1E2DB50A-D8D7-595D-8448-77F057655E82.dita"><linktext>Writing a |
|
383 Client MTM</linktext></link> |
|
384 </related-links></concept> |