1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2015 The Qt Company Ltd. |
4 | ** Contact: http://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtVersit module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL21$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see http://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at http://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 or version 3 as published by the Free |
20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and |
21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the |
22 | ** following information to ensure the GNU Lesser General Public License |
23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and |
24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
25 | ** |
26 | ** As a special exception, The Qt Company gives you certain additional |
27 | ** rights. These rights are described in The Qt Company LGPL Exception |
28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
29 | ** |
30 | ** $QT_END_LICENSE$ |
31 | ** |
32 | ****************************************************************************/ |
33 | |
34 | #include "qversitwriter_p.h" |
35 | |
36 | #include <QtCore/qbuffer.h> |
37 | #include <QtCore/qstringlist.h> |
38 | #include <QtCore/qtextcodec.h> |
39 | |
40 | #include "qvcard21writer_p.h" |
41 | #include "qvcard30writer_p.h" |
42 | #include "qversitdocumentwriter_p.h" |
43 | #include "qversitutils_p.h" |
44 | |
45 | QT_BEGIN_NAMESPACE_VERSIT |
46 | |
47 | /*! Constructs a writer. */ |
48 | QVersitWriterPrivate::QVersitWriterPrivate() |
49 | : mIoDevice(0), |
50 | mState(QVersitWriter::InactiveState), |
51 | mError(QVersitWriter::NoError), |
52 | mIsCanceling(false), |
53 | mDefaultCodec(0) |
54 | { |
55 | } |
56 | |
57 | /*! Destroys a writer. */ |
58 | QVersitWriterPrivate::~QVersitWriterPrivate() |
59 | { |
60 | } |
61 | |
62 | /*! Links the signals from this to the signals of \a writer. */ |
63 | void QVersitWriterPrivate::init(QVersitWriter* writer) |
64 | { |
65 | qRegisterMetaType<QVersitWriter::State>(typeName: "QVersitWriter::State" ); |
66 | connect(sender: this, SIGNAL(stateChanged(QVersitWriter::State)), |
67 | receiver: writer, SIGNAL(stateChanged(QVersitWriter::State)), Qt::DirectConnection); |
68 | } |
69 | |
70 | /*! |
71 | * Do the actual writing and set the error and state appropriately. |
72 | */ |
73 | void QVersitWriterPrivate::write() |
74 | { |
75 | bool canceled = false; |
76 | |
77 | // Try to get the type from the parameter to startWriting... |
78 | QVersitDocument::VersitType type = documentType(); |
79 | |
80 | foreach (const QVersitDocument& document, mInput) { |
81 | if (isCanceling()) { |
82 | canceled = true; |
83 | break; |
84 | } |
85 | |
86 | // Get type from the document if not specified in startWriting |
87 | if (type == QVersitDocument::InvalidType) |
88 | type = document.type(); |
89 | |
90 | QScopedPointer<QVersitDocumentWriter> writer(writerForType(type, document)); |
91 | QTextCodec* codec = mDefaultCodec; |
92 | if (codec == NULL) { |
93 | if (type == QVersitDocument::VCard21Type) { |
94 | codec = QTextCodec::codecForName(name: "ISO-8859-1" ); |
95 | writer->setAsciiCodec(); |
96 | } else { |
97 | codec = QTextCodec::codecForName(name: "UTF-8" ); |
98 | } |
99 | } |
100 | writer->setCodec(codec); |
101 | writer->setDevice(mIoDevice); |
102 | if (!writer->encodeVersitDocument(document)) { |
103 | setError(QVersitWriter::IOError); |
104 | break; |
105 | } |
106 | } |
107 | if (canceled) |
108 | setState(QVersitWriter::CanceledState); |
109 | else |
110 | setState(QVersitWriter::FinishedState); |
111 | } |
112 | |
113 | /*! |
114 | * Inherited from QThread, called by QThread when the thread has been started. |
115 | */ |
116 | void QVersitWriterPrivate::run() |
117 | { |
118 | write(); |
119 | } |
120 | |
121 | void QVersitWriterPrivate::setState(QVersitWriter::State state) |
122 | { |
123 | mMutex.lock(); |
124 | mState = state; |
125 | mMutex.unlock(); |
126 | emit stateChanged(state); |
127 | } |
128 | |
129 | QVersitWriter::State QVersitWriterPrivate::state() const |
130 | { |
131 | QMutexLocker locker(&mMutex); |
132 | return mState; |
133 | } |
134 | |
135 | void QVersitWriterPrivate::setError(QVersitWriter::Error error) |
136 | { |
137 | QMutexLocker locker(&mMutex); |
138 | mError = error; |
139 | } |
140 | |
141 | QVersitWriter::Error QVersitWriterPrivate::error() const |
142 | { |
143 | QMutexLocker locker(&mMutex); |
144 | return mError; |
145 | } |
146 | |
147 | /*! |
148 | * Returns a QVersitDocumentWriter that can encode a QVersitDocument of type \a type. |
149 | * The caller is responsible for deleting the object. |
150 | */ |
151 | QVersitDocumentWriter* QVersitWriterPrivate::writerForType(QVersitDocument::VersitType type, const QVersitDocument& document) |
152 | { |
153 | switch (type) { |
154 | case QVersitDocument::InvalidType: |
155 | { |
156 | // Neither startWriting or the document provided the type. |
157 | // Need to infer the type from the document's componentType |
158 | QString componentType(document.componentType()); |
159 | if (componentType == QStringLiteral("VCARD" )) { |
160 | return new QVCard30Writer(QVersitDocument::VCard30Type); |
161 | } else if (componentType == QStringLiteral("VCALENDAR" ) |
162 | || componentType == QStringLiteral("VEVENT" ) |
163 | || componentType == QStringLiteral("VTODO" ) |
164 | || componentType == QStringLiteral("VJOURNAL" ) |
165 | || componentType == QStringLiteral("VTIMEZONE" ) |
166 | || componentType == QStringLiteral("VALARM" )) { |
167 | return new QVCard30Writer(QVersitDocument::ICalendar20Type); |
168 | } else { |
169 | return new QVCard30Writer(QVersitDocument::VCard30Type); |
170 | } |
171 | } |
172 | case QVersitDocument::VCard21Type: |
173 | return new QVCard21Writer(type); |
174 | case QVersitDocument::VCard30Type: |
175 | return new QVCard30Writer(type); |
176 | default: |
177 | return new QVCard30Writer(type); |
178 | } |
179 | } |
180 | |
181 | void QVersitWriterPrivate::setCanceling(bool canceling) |
182 | { |
183 | QMutexLocker locker(&mMutex); |
184 | mIsCanceling = canceling; |
185 | } |
186 | |
187 | bool QVersitWriterPrivate::isCanceling() const |
188 | { |
189 | QMutexLocker locker(&mMutex); |
190 | return mIsCanceling; |
191 | } |
192 | |
193 | void QVersitWriterPrivate::setDocumentType(QVersitDocument::VersitType type) |
194 | { |
195 | QMutexLocker locker(&mMutex); |
196 | mType = type; |
197 | } |
198 | |
199 | QVersitDocument::VersitType QVersitWriterPrivate::documentType() const |
200 | { |
201 | QMutexLocker locker(&mMutex); |
202 | return mType; |
203 | } |
204 | |
205 | #include "moc_qversitwriter_p.cpp" |
206 | QT_END_NAMESPACE_VERSIT |
207 | |