Compile with clang when C++11 support is enabled
[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
79     \ingroup richtext-processing
80     \ingroup io
81
82     To write a document, construct a QTextDocumentWriter object with either a
83     file name or a device object, and specify the document format to be
84     written. You can construct a writer and set the format using setFormat()
85     later.
86
87     Call write() to write the document to the device. If the document is
88     successfully written, this function returns true. However, if an error
89     occurs when writing the document, it will return false.
90
91     Call supportedDocumentFormats() for a list of formats that
92     QTextDocumentWriter can write.
93
94     Since the capabilities of the supported output formats vary considerably,
95     the writer simply outputs the appropriate subset of objects for each format.
96     This typically includes the formatted text and images contained in a
97     document.
98 */
99
100 /*!
101     \internal
102 */
103 QTextDocumentWriterPrivate::QTextDocumentWriterPrivate(QTextDocumentWriter *qq)
104     : device(0),
105     deleteDevice(false),
106 #ifndef QT_NO_TEXTCODEC
107     codec(QTextCodec::codecForName("utf-8")),
108 #endif
109     q(qq)
110 {
111 }
112
113 /*!
114     Constructs an empty QTextDocumentWriter object. Before writing, you must
115     call setFormat() to set a document format, then setDevice() or
116     setFileName().
117 */
118 QTextDocumentWriter::QTextDocumentWriter()
119     : d(new QTextDocumentWriterPrivate(this))
120 {
121 }
122
123 /*!
124     Constructs a QTextDocumentWriter object to write to the given \a device
125     in the document format specified by \a format.
126 */
127 QTextDocumentWriter::QTextDocumentWriter(QIODevice *device, const QByteArray &format)
128     : d(new QTextDocumentWriterPrivate(this))
129 {
130     d->device = device;
131     d->format = format;
132 }
133
134 /*!
135     Constructs an QTextDocumentWriter object that will write to a file with
136     the name \a fileName, using the document format specified by \a format.
137     If \a format is not provided, QTextDocumentWriter will detect the document
138     format by inspecting the extension of \a fileName.
139 */
140 QTextDocumentWriter::QTextDocumentWriter(const QString &fileName, const QByteArray &format)
141     : d(new QTextDocumentWriterPrivate(this))
142 {
143     QFile *file = new QFile(fileName);
144     d->device = file;
145     d->deleteDevice = true;
146     d->format = format;
147 }
148
149 /*!
150     Destroys the QTextDocumentWriter object.
151 */
152 QTextDocumentWriter::~QTextDocumentWriter()
153 {
154     if (d->deleteDevice)
155         delete d->device;
156     delete d;
157 }
158
159 /*!
160     Sets the format used to write documents to the \a format specified.
161     \a format is a case insensitive text string. For example:
162
163     \snippet code/src_gui_text_qtextdocumentwriter.cpp 0
164
165     You can call supportedDocumentFormats() for the full list of formats
166     QTextDocumentWriter supports.
167
168     \sa format()
169 */
170 void QTextDocumentWriter::setFormat (const QByteArray &format)
171 {
172     d->format = format;
173 }
174
175 /*!
176     Returns the format used for writing documents.
177
178     \sa setFormat()
179 */
180 QByteArray QTextDocumentWriter::format () const
181 {
182     return d->format;
183 }
184
185 /*!
186     Sets the writer's device to the \a device specified. If a device has
187     already been set, the old device is removed but otherwise left
188     unchanged.
189
190     If the device is not already open, QTextDocumentWriter will attempt to
191     open the device in \l QIODevice::WriteOnly mode by calling open().
192
193     \note This will not work for certain devices, such as QProcess,
194     QTcpSocket and QUdpSocket, where some configuration is required before
195     the device can be opened.
196
197     \sa device(), setFileName()
198 */
199 void QTextDocumentWriter::setDevice (QIODevice *device)
200 {
201     if (d->device && d->deleteDevice)
202         delete d->device;
203
204     d->device = device;
205     d->deleteDevice = false;
206 }
207
208 /*!
209     Returns the device currently assigned, or 0 if no device has been
210     assigned.
211 */
212 QIODevice *QTextDocumentWriter::device () const
213 {
214     return d->device;
215 }
216
217 /*!
218     Sets the name of the file to be written to \a fileName. Internally,
219     QTextDocumentWriter will create a QFile and open it in \l
220     QIODevice::WriteOnly mode, and use this file when writing the document.
221
222     \sa fileName(), setDevice()
223 */
224 void QTextDocumentWriter::setFileName (const QString &fileName)
225 {
226     setDevice(new QFile(fileName));
227     d->deleteDevice = true;
228 }
229
230 /*!
231     If the currently assigned device is a QFile, or if setFileName()
232     has been called, this function returns the name of the file
233     to be written to. In all other cases, it returns an empty string.
234
235     \sa setFileName(), setDevice()
236 */
237 QString QTextDocumentWriter::fileName () const
238 {
239     QFile *file = qobject_cast<QFile *>(d->device);
240     return file ? file->fileName() : QString();
241 }
242
243 /*!
244     Writes the given \a document to the assigned device or file and
245     returns true if successful; otherwise returns false.
246 */
247 bool QTextDocumentWriter::write(const QTextDocument *document)
248 {
249     QByteArray suffix;
250
251     if (d->device && d->format.isEmpty()) {
252         // if there's no format, see if device is a file, and if so, find
253         // the file suffix
254         if (QFile *file = qobject_cast<QFile *>(d->device))
255             suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1();
256     }
257
258     QByteArray format = !d->format.isEmpty() ? d->format.toLower() : suffix;
259
260 #ifndef QT_NO_TEXTODFWRITER
261     if (format == "odf" || format == "opendocumentformat" || format == "odt") {
262         QTextOdfWriter writer(*document, d->device);
263 #ifndef QT_NO_TEXTCODEC
264         writer.setCodec(d->codec);
265 #endif
266         return writer.writeAll();
267     }
268 #endif // QT_NO_TEXTODFWRITER
269
270 #ifndef QT_NO_TEXTHTMLPARSER
271     if (format == "html" || format == "htm") {
272         if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
273             qWarning() << "QTextDocumentWriter::write: the device can not be opened for writing";
274             return false;
275         }
276         QTextStream ts(d->device);
277 #ifndef QT_NO_TEXTCODEC
278         ts.setCodec(d->codec);
279         ts << document->toHtml(d->codec->name());
280 #endif
281         d->device->close();
282         return true;
283     }
284 #endif
285     if (format == "txt" || format == "plaintext") {
286         if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) {
287             qWarning() << "QTextDocumentWriter::write: the device can not be opened for writing";
288             return false;
289         }
290         QTextStream ts(d->device);
291 #ifndef QT_NO_TEXTCODEC
292         ts.setCodec(d->codec);
293 #endif
294         ts << document->toPlainText();
295         d->device->close();
296         return true;
297     }
298
299     return false;
300 }
301
302 /*!
303     Writes the document fragment specified by \a fragment to the assigned device
304     or file and returns true if successful; otherwise returns false.
305 */
306 bool QTextDocumentWriter::write(const QTextDocumentFragment &fragment)
307 {
308     if (fragment.d == 0)
309         return false; // invalid fragment.
310     QTextDocument *doc = fragment.d->doc;
311     if (doc)
312         return write(doc);
313     return false;
314 }
315
316 /*!
317     Sets the codec for this stream to \a codec. The codec is used for
318     encoding any data that is written. By default, QTextDocumentWriter
319     uses UTF-8.
320 */
321
322 #ifndef QT_NO_TEXTCODEC
323 void QTextDocumentWriter::setCodec(QTextCodec *codec)
324 {
325     if (codec == 0)
326         codec = QTextCodec::codecForName("UTF-8");
327     Q_ASSERT(codec);
328     d->codec = codec;
329 }
330 #endif
331
332 /*!
333     Returns the codec that is currently assigned to the writer.
334 */
335 #ifndef QT_NO_TEXTCODEC
336 QTextCodec *QTextDocumentWriter::codec() const
337 {
338     return d->codec;
339 }
340 #endif
341
342 /*!
343     Returns the list of document formats supported by QTextDocumentWriter.
344
345     By default, Qt can write the following formats:
346
347     \table
348     \header \li Format    \li Description
349     \row    \li plaintext \li Plain text
350     \row    \li HTML      \li HyperText Markup Language
351     \row    \li ODF       \li OpenDocument Format
352     \endtable
353
354     \sa setFormat()
355 */
356 QList<QByteArray> QTextDocumentWriter::supportedDocumentFormats()
357 {
358     QList<QByteArray> answer;
359     answer << "plaintext";
360
361 #ifndef QT_NO_TEXTHTMLPARSER
362     answer << "HTML";
363 #endif
364 #ifndef QT_NO_TEXTODFWRITER
365     answer << "ODF";
366 #endif // QT_NO_TEXTODFWRITER
367
368     qSort(answer);
369     return answer;
370 }
371
372 QT_END_NAMESPACE