38 ** $QT_END_LICENSE$ |
38 ** $QT_END_LICENSE$ |
39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
42 #include "qversitwriter.h" |
42 #include "qversitwriter.h" |
43 #include "qvcard21writer_p.h" |
43 #include "qversitwriter_p.h" |
44 #include "qvcard30writer_p.h" |
|
45 #include "versitutils_p.h" |
44 #include "versitutils_p.h" |
46 #include "qmobilityglobal.h" |
45 #include "qmobilityglobal.h" |
47 |
46 |
48 #include <QStringList> |
47 #include <QStringList> |
49 |
48 #include <QTextCodec> |
50 QTM_BEGIN_NAMESPACE |
49 |
|
50 QTM_USE_NAMESPACE |
51 |
51 |
52 /*! |
52 /*! |
53 \class QVersitWriter |
53 \class QVersitWriter |
54 |
54 \preliminary |
55 \brief The QVersitWriter class provides an interface |
55 \brief The QVersitWriter class writes Versit documents such as vCards to a device. |
56 for writing a versit document such as a vCard to a text stream. |
|
57 |
|
58 \ingroup versit |
56 \ingroup versit |
59 |
57 |
60 QVersitWriter converts a QVersitDocument into its textual representation. |
58 QVersitWriter converts a QVersitDocument into its textual representation. |
61 QVersitWriter supports writing to an abstract I/O device |
59 QVersitWriter supports writing to an abstract I/O device |
62 which can be for example a file or a memory buffer. |
60 which can be for example a file or a memory buffer. |
63 The writing can be done synchronously or asynchronously. |
61 The writing can be done asynchronously and the waitForFinished() |
64 |
62 function can be used to implement a blocking write. |
65 \code |
63 |
66 // An example of writing a simple vCard to a memory buffer: |
64 The serialization of the document is done in accordance with the type of the QVersitDocument |
67 QBuffer vCardBuffer; |
65 being written. The value of each QVersitProperty is encoded according to the type of object: |
68 vCardBuffer.open(QBuffer::ReadWrite); |
66 \list |
69 QVersitWriter writer; |
67 \o \l{QString}{QStrings} are serialized verbatim, unless the default codec of the writer cannot |
70 writer.setDevice(&vCardBuffer); |
68 encode the string: in this case, UTF-8 is used to encode it (and the CHARSET parameter added to |
71 QVersitDocument document; |
69 the property, as per the vCard 2.1 specification). If the document type is vCard 2.1, |
72 QVersitProperty property; |
70 quoted-printable encoding may also be performed. |
73 property.setName("N"); |
71 \o \l{QByteArray}{QByteArrays} are assumed to be binary data and are serialized as base-64 encoded |
74 property.setValue("Citizen;John;Q;;"); |
72 values. |
75 document.addProperty(property); |
73 \o \l{QVersitDocument}{QVersitDocuments} are serialized as a nested document (eg. as per the |
76 writer.setVersitDocument(document); |
74 AGENT property in vCard). |
77 if (writer.writeAll()) { |
75 \endlist |
78 // Use the vCardBuffer... |
76 |
79 } |
|
80 \endcode |
|
81 |
|
82 \sa QVersitDocument, QVersitProperty |
77 \sa QVersitDocument, QVersitProperty |
83 */ |
78 */ |
84 |
79 |
85 /*! |
80 |
86 * \fn QVersitWriter::writingDone() |
81 /*! |
87 * The signal is emitted by the writer when the asynchronous writing has been completed. |
82 * \enum QVersitWriter::Error |
|
83 * This enum specifies an error that occurred during the most recent operation: |
|
84 * \value NoError The most recent operation was successful |
|
85 * \value UnspecifiedError The most recent operation failed for an undocumented reason |
|
86 * \value IOError The most recent operation failed because of a problem with the device |
|
87 * \value OutOfMemoryError The most recent operation failed due to running out of memory |
|
88 * \value NotReadyError The most recent operation failed because there is an operation in progress |
|
89 */ |
|
90 |
|
91 /*! |
|
92 * \enum QVersitWriter::State |
|
93 * Enumerates the various states that a reader may be in at any given time |
|
94 * \value InactiveState Write operation not yet started |
|
95 * \value ActiveState Write operation started, not yet finished |
|
96 * \value CanceledState Write operation is finished due to cancelation |
|
97 * \value FinishedState Write operation successfully completed |
|
98 */ |
|
99 |
|
100 /*! |
|
101 * \fn QVersitWriter::stateChanged(QVersitWriter::State state) |
|
102 * The signal is emitted by the writer when its state has changed (eg. when it has finished |
|
103 * writing to the device). |
|
104 * \a state is the new state of the writer. |
88 */ |
105 */ |
89 |
106 |
90 /*! Constructs a new writer. */ |
107 /*! Constructs a new writer. */ |
91 QVersitWriter::QVersitWriter() : d(new QVCard21Writer) |
108 QVersitWriter::QVersitWriter() : d(new QVersitWriterPrivate) |
92 { |
109 { |
93 connect(d,SIGNAL(finished()),this,SIGNAL(writingDone()),Qt::DirectConnection); |
110 connect(d, SIGNAL(stateChanged(QVersitWriter::State)), |
|
111 this, SIGNAL(stateChanged(QVersitWriter::State)), Qt::DirectConnection); |
94 } |
112 } |
95 |
113 |
96 /*! |
114 /*! |
97 * Frees the memory used by the writer. |
115 * Frees the memory used by the writer. |
98 * Waits until a pending asynchronous writing has been completed. |
116 * Waits until a pending asynchronous writing has been completed. |
102 d->wait(); |
120 d->wait(); |
103 delete d; |
121 delete d; |
104 } |
122 } |
105 |
123 |
106 /*! |
124 /*! |
107 * Set the versit document to be written to \a versitDocument and |
|
108 * selects the actual writer implementation based on the versit document type. |
|
109 */ |
|
110 void QVersitWriter::setVersitDocument(const QVersitDocument& versitDocument) |
|
111 { |
|
112 QVersitWriterPrivate* updatedWriter = 0; |
|
113 switch (versitDocument.versitType()) { |
|
114 case QVersitDocument::VCard21: |
|
115 updatedWriter = new QVCard21Writer; |
|
116 break; |
|
117 case QVersitDocument::VCard30: |
|
118 updatedWriter = new QVCard30Writer; |
|
119 break; |
|
120 default: |
|
121 break; |
|
122 } |
|
123 if (updatedWriter) { |
|
124 updatedWriter->mIoDevice = d->mIoDevice; |
|
125 delete d; |
|
126 d = updatedWriter; |
|
127 connect(d,SIGNAL(finished()),this,SIGNAL(writingDone()),Qt::DirectConnection); |
|
128 } |
|
129 d->mVersitDocument = versitDocument; |
|
130 } |
|
131 |
|
132 /*! |
|
133 * Returns the current versit document. |
|
134 */ |
|
135 QVersitDocument QVersitWriter::versitDocument() const |
|
136 { |
|
137 return d->mVersitDocument; |
|
138 } |
|
139 |
|
140 /*! |
|
141 * Sets the device used for writing to \a device. |
125 * Sets the device used for writing to \a device. |
142 */ |
126 */ |
143 void QVersitWriter::setDevice(QIODevice* device) |
127 void QVersitWriter::setDevice(QIODevice* device) |
144 { |
128 { |
145 d->mIoDevice = device; |
129 d->mIoDevice = device; |
152 { |
136 { |
153 return d->mIoDevice; |
137 return d->mIoDevice; |
154 } |
138 } |
155 |
139 |
156 /*! |
140 /*! |
157 * Starts writing the output asynchronously. |
141 * Sets the default codec for the writer to use for writing the entire output. |
|
142 * |
|
143 * If \a codec is NULL, the writer uses the codec according to the specification prescribed default. |
|
144 * (for vCard 2.1, ASCII; for vCard 3.0, UTF-8). |
|
145 */ |
|
146 void QVersitWriter::setDefaultCodec(QTextCodec *codec) |
|
147 { |
|
148 d->mDefaultCodec = codec; |
|
149 } |
|
150 |
|
151 /*! |
|
152 * Returns the document's codec. |
|
153 */ |
|
154 QTextCodec* QVersitWriter::defaultCodec() const |
|
155 { |
|
156 return d->mDefaultCodec; |
|
157 } |
|
158 |
|
159 /*! |
|
160 * Starts writing \a input to device() asynchronously. |
158 * Returns false if the output device has not been set or opened or |
161 * Returns false if the output device has not been set or opened or |
159 * if there is another asynchronous write operation already pending. |
162 * if there is another asynchronous write operation already pending. |
160 * Signal \l writingDone() is emitted when the writing has finished. |
163 * Signal \l stateChanged() is emitted with parameter FinishedState |
161 */ |
164 * when the writing has finished. |
|
165 */ |
|
166 bool QVersitWriter::startWriting(const QList<QVersitDocument>& input) |
|
167 { |
|
168 d->mInput = input; |
|
169 if (d->state() == ActiveState || d->isRunning()) { |
|
170 d->setError(QVersitWriter::NotReadyError); |
|
171 return false; |
|
172 } else if (!d->mIoDevice || !d->mIoDevice->isWritable()) { |
|
173 d->setError(QVersitWriter::IOError); |
|
174 return false; |
|
175 } else { |
|
176 d->setState(ActiveState); |
|
177 d->setError(NoError); |
|
178 d->start(); |
|
179 return true; |
|
180 } |
|
181 } |
|
182 |
|
183 /*! |
|
184 * Attempts to asynchronously cancel the write request. |
|
185 */ |
|
186 void QVersitWriter::cancel() |
|
187 { |
|
188 d->setCanceling(true); |
|
189 } |
|
190 |
|
191 /*! |
|
192 * If the state is ActiveState, blocks until the writer has finished writing or \a msec milliseconds |
|
193 * has elapsed, returning true if it successfully finishes or is cancelled by the user. |
|
194 * If the state is FinishedState, returns true immediately. |
|
195 * Otherwise, returns false immediately. |
|
196 */ |
|
197 bool QVersitWriter::waitForFinished(int msec) |
|
198 { |
|
199 State state = d->state(); |
|
200 if (state == ActiveState) { |
|
201 return d->wait(msec); |
|
202 } else if (state == FinishedState) { |
|
203 return true; |
|
204 } else { |
|
205 return false; |
|
206 } |
|
207 } |
|
208 |
|
209 /*! |
|
210 * Returns the state of the writer. |
|
211 */ |
|
212 QVersitWriter::State QVersitWriter::state() const |
|
213 { |
|
214 return d->state(); |
|
215 } |
|
216 |
|
217 /*! |
|
218 * Returns the error encountered by the last operation. |
|
219 */ |
|
220 QVersitWriter::Error QVersitWriter::error() const |
|
221 { |
|
222 return d->error(); |
|
223 } |
|
224 |
|
225 |
|
226 /*! \internal */ |
|
227 void QVersitWriter::setVersitDocument(const QVersitDocument& versitDocument) |
|
228 { |
|
229 QList<QVersitDocument> documents; |
|
230 documents.append(versitDocument); |
|
231 d->mInput = documents; |
|
232 } |
|
233 |
|
234 /*! \internal */ |
|
235 QVersitDocument QVersitWriter::versitDocument() const |
|
236 { |
|
237 return QVersitDocument(); |
|
238 } |
|
239 |
|
240 /*! \internal */ |
162 bool QVersitWriter::startWriting() |
241 bool QVersitWriter::startWriting() |
163 { |
242 { |
164 bool started = false; |
243 return startWriting(d->mInput); |
165 if (d->isReady() && !d->isRunning()) { |
244 } |
166 d->start(); |
245 |
167 started = true; |
246 /*! \internal */ |
168 } |
|
169 |
|
170 return started; |
|
171 } |
|
172 |
|
173 /*! |
|
174 * Writes the output synchronously. |
|
175 * Returns false if the output device has not been set or opened or |
|
176 * if there is an asynchronous write operation pending. |
|
177 * Using this function may block the user thread for an undefined period. |
|
178 * In most cases asynchronous \l startWriting() should be used instead. |
|
179 */ |
|
180 bool QVersitWriter::writeAll() |
247 bool QVersitWriter::writeAll() |
181 { |
248 { |
182 bool ok = false; |
249 startWriting(d->mInput); |
183 if (!d->isRunning()) |
250 return waitForFinished(); |
184 ok = d->write(); |
|
185 return ok; |
|
186 } |
251 } |
187 |
252 |
188 #include "moc_qversitwriter.cpp" |
253 #include "moc_qversitwriter.cpp" |
189 |
|
190 QTM_END_NAMESPACE |
|