Get started with patching up the Qt GUI docs
[profile/ivi/qtbase.git] / src / gui / text / qtextdocumentwriter.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include "qtextdocumentwriter.h"
42
43 #include <QtCore/qfile.h>
44 #include <QtCore/qbytearray.h>
45 #include <QtCore/qfileinfo.h>
46 #include <QtCore/qtextcodec.h>
47 #include <QtCore/qtextstream.h>
48 #include <QtCore/qdebug.h>
49 #include "qtextdocument.h"
50 #include "qtextdocumentfragment.h"
51
52 #include "qtextdocumentfragment_p.h"
53 #include "qtextodfwriter_p.h"
54
55 QT_BEGIN_NAMESPACE
56
57 class QTextDocumentWriterPrivate
58 {
59 public:
60     QTextDocumentWriterPrivate(QTextDocumentWriter* qq);
61
62     // device
63     QByteArray format;
64     QIODevice *device;
65     bool deleteDevice;
66 #ifndef QT_NO_TEXTCODEC
67     QTextCodec *codec;
68 #endif
69
70     QTextDocumentWriter *q;
71 };
72
73 /*!
74     \since 4.5
75     \class QTextDocumentWriter
76
77     \brief The QTextDocumentWriter class provides a format-independent interface for writing a QTextDocument to files or other devices.
78     \inmodule QtGui
79
80     \ingroup richtext-processing
81     \ingroup io
82
83     To write a document, construct a QTextDocumentWriter object with either a
84     file name or a device object, and specify the document format to be
85     written. You can construct a writer and set the format using setFormat()
86     later.
87
88     Call write() to write the document to the device. If the document is
89     successfully written, this function returns true. However, if an error
90     occurs when writing the document, it will return false.
91
92     Call supportedDocumentFormats() for a list of formats that
93     QTextDocumentWriter can write.
94
95     Since the capabilities of the supported output formats vary considerably,
96     the writer simply outputs the appropriate subset of objects for each format.
97     This typically includes the formatted text and images contained in a
98     document.
99 */
100
101 /*!
102     \internal
103 */
104 QTextDocumentWriterPrivate::QTextDocumentWriterPrivate(QTextDocumentWriter *qq)
105     : device(0),
106     deleteDevice(false),
107 #ifndef QT_NO_TEXTCODEC
108     codec(QTextCodec::codecForName("utf-8")),
109 #endif
110     q(qq)
111 {
112 }
113
114 /*!
115     Constructs an empty QTextDocumentWriter object. Before writing, you must
116     call setFormat() to set a document format, then setDevice() or
117     setFileName().
118 */
119 QTextDocumentWriter::QTextDocumentWriter()
120     : d(new QTextDocumentWriterPrivate(this))
121 {
122 }
123
124 /*!
125     Constructs a QTextDocumentWriter object to write to the given \a device
126     in the document format specified by \a format.
127 */
128 QTextDocumentWriter::QTextDocumentWriter(QIODevice *device, const QByteArray &format)
129     : d(new QTextDocumentWriterPrivate(this))
130 {
131     d->device = device;
132     d->format = format;
133 }
134
135 /*!
136     Constructs an QTextDocumentWriter object that will write to a file with
137     the name \a fileName, using the document format specified by \a format.
138     If \a format is not provided, QTextDocumentWriter will detect the document
139     format by inspecting the extension of \a fileName.
140 */
141 QTextDocumentWriter::QTextDocumentWriter(const QString &fileName, const QByteArray &format)
142     : d(new QTextDocumentWriterPrivate(this))
143 {
144     QFile *file = new QFile(fileName);
145     d->device = file;
146     d->deleteDevice = true;
147     d->format = format;
148 }
149
150 /*!
151     Destroys the QTextDocumentWriter object.
152 */
153 QTextDocumentWriter::~QTextDocumentWriter()
154 {
155     if (d->deleteDevice)
156         delete d->device;
157     delete d;
158 }
159
160 /*!
161     Sets the format used to write documents to the \a format specified.
162     \a format is a case insensitive text string. For example:
163
164     \snippet code/src_gui_text_qtextdocumentwriter.cpp 0
165
166     You can call supportedDocumentFormats() for the full list of formats
167     QTextDocumentWriter supports.
168
169     \sa format()
170 */
171 void QTextDocumentWriter::setFormat (const QByteArray &format)
172 {
173     d->format = format;
174 }
175
176 /*!
177     Returns the format used for writing documents.
178
179     \sa setFormat()
180 */
181 QByteArray QTextDocumentWriter::format () const
182 {
183     return d->format;
184 }
185
186 /*!
187     Sets the writer's device to the \a device specified. If a device has
188     already been set, the old device is removed but otherwise left
189     unchanged.
190
191     If the device is not already open, QTextDocumentWriter will attempt to
192     open the device in \l QIODevice::WriteOnly mode by calling open().
193
194     \note This will not work for certain devices, such as QProcess,
195     QTcpSocket and QUdpSocket, where some configuration is required before
196     the device can be opened.
197
198     \sa device(), setFileName()
199 */
200 void QTextDocumentWriter::setDevice (QIODevice *device)
201 {
202     if (d->device && d->deleteDevice)
203         delete d->device;
204
205     d->device = device;
206     d->deleteDevice = false;
207 }
208
209 /*!
210     Returns the device currently assigned, or 0 if no device has been
211     assigned.
212 */
213 QIODevice *QTextDocumentWriter::device () const
214 {
215     return d->device;
216 }
217
218 /*!
219     Sets the name of the file to be written to \a fileName. Internally,
220     QTextDocumentWriter will create a QFile and open it in \l
221     QIODevice::WriteOnly mode, and use this file when writing the document.
222
223     \sa fileName(), setDevice()
224 */
225 void QTextDocumentWriter::setFileName (const QString &fileName)
226 {
227     setDevice(new QFile(fileName));
228     d->deleteDevice = true;
229 }
230
231 /*!
232     If the currently assigned device is a QFile, or if setFileName()
233     has been called, this function returns the name of the file
234     to be written to. In all other cases, it returns an empty string.
235
236     \sa setFileName(), setDevice()
237 */
238 QString QTextDocumentWriter::fileName () const
239 {
240     QFile *file = qobject_cast<QFile *>(d->device);
241     return file ? file->fileName() : QString();
242 }
243
244 /*!
245     Writes the given \a document to the assigned device or file and
246     returns true if successful; otherwise returns false.
247 */
248 bool QTextDocumentWriter::write(const QTextDocument *document)
249 {
250     QByteArray suffix;
251
252     if (d->device && d->format.isEmpty()) {
253         // if there's no format, see if device is a file, and if so, find
254         // the file suffix
255         if (QFile *file = qobject_cast<QFile *>(d->device))
256             suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1();
257     }
258
259     QByteArray format = !d->format.isEmpty() ? d->format.toLower() : suffix;
260
261 #ifndef QT_NO_TEXTODFWRITER
262     if (format == "odf" || format == "opendocumentformat" || format == "odt") {
263         QTextOdfWriter writer(*document, d->device);
264 #ifndef QT_NO_TEXTCODEC
265         writer.setCodec(d->codec);
266 #endif
267         return writer.writeAll();
268     }
269 #endif // QT_NO_TEXTODFWRITER
270
271 #ifndef QT_NO_TEXTHTMLPARSER
272     if (format == "html" || format == "htm") {
273         if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
274             qWarning() << "QTextDocumentWriter::write: the device can not be opened for writing";
275             return false;
276         }
277         QTextStream ts(d->device);
278 #ifndef QT_NO_TEXTCODEC
279         ts.setCodec(d->codec);
280         ts << document->toHtml(d->codec->name());
281 #endif
282         d->device->close();
283         return true;
284     }
285 #endif
286     if (format == "txt" || format == "plaintext") {
287         if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
288             qWarning() << "QTextDocumentWriter::write: the device can not be opened for writing";
289             return false;
290         }
291         QTextStream ts(d->device);
292 #ifndef QT_NO_TEXTCODEC
293         ts.setCodec(d->codec);
294 #endif
295         ts << document->toPlainText();
296         d->device->close();
297         return true;
298     }
299
300     return false;
301 }
302
303 /*!
304     Writes the document fragment specified by \a fragment to the assigned device
305     or file and returns true if successful; otherwise returns false.
306 */
307 bool QTextDocumentWriter::write(const QTextDocumentFragment &fragment)
308 {
309     if (fragment.d == 0)
310         return false; // invalid fragment.
311     QTextDocument *doc = fragment.d->doc;
312     if (doc)
313         return write(doc);
314     return false;
315 }
316
317 /*!
318     Sets the codec for this stream to \a codec. The codec is used for
319     encoding any data that is written. By default, QTextDocumentWriter
320     uses UTF-8.
321 */
322
323 #ifndef QT_NO_TEXTCODEC
324 void QTextDocumentWriter::setCodec(QTextCodec *codec)
325 {
326     if (codec == 0)
327         codec = QTextCodec::codecForName("UTF-8");
328     Q_ASSERT(codec);
329     d->codec = codec;
330 }
331 #endif
332
333 /*!
334     Returns the codec that is currently assigned to the writer.
335 */
336 #ifndef QT_NO_TEXTCODEC
337 QTextCodec *QTextDocumentWriter::codec() const
338 {
339     return d->codec;
340 }
341 #endif
342
343 /*!
344     Returns the list of document formats supported by QTextDocumentWriter.
345
346     By default, Qt can write the following formats:
347
348     \table
349     \header \li Format    \li Description
350     \row    \li plaintext \li Plain text
351     \row    \li HTML      \li HyperText Markup Language
352     \row    \li ODF       \li OpenDocument Format
353     \endtable
354
355     \sa setFormat()
356 */
357 QList<QByteArray> QTextDocumentWriter::supportedDocumentFormats()
358 {
359     QList<QByteArray> answer;
360     answer << "plaintext";
361
362 #ifndef QT_NO_TEXTHTMLPARSER
363     answer << "HTML";
364 #endif
365 #ifndef QT_NO_TEXTODFWRITER
366     answer << "ODF";
367 #endif // QT_NO_TEXTODFWRITER
368
369     qSort(answer);
370     return answer;
371 }
372
373 QT_END_NAMESPACE