68 QVariant variant(property.variantValue()); |
68 QVariant variant(property.variantValue()); |
69 |
69 |
70 QString renderedValue; |
70 QString renderedValue; |
71 bool useUtf8 = false; |
71 bool useUtf8 = false; |
72 |
72 |
73 if (variant.type() == QVariant::String) { |
73 /* Structured values need to have their components backslash-escaped (in vCard 2.1, semicolons |
74 QString valueString = variant.toString(); |
74 must be escaped for compound values and commas must be escaped for list values). */ |
75 |
75 if (variant.type() == QVariant::StringList) { |
76 // Quoted-Printable encode the value and add Quoted-Printable parameter, if necessary |
76 QStringList values = property.variantValue().toStringList(); |
77 if (!parameters.contains(QLatin1String("ENCODING"))) { |
77 QString separator; |
78 if (quotedPrintableEncode(valueString)) |
78 if (property.valueType() == QVersitProperty::CompoundType) { |
79 parameters.insert(QLatin1String("ENCODING"), QLatin1String("QUOTED-PRINTABLE")); |
79 separator = QLatin1String(";"); |
80 } |
80 } else { |
81 |
81 if (property.valueType() != QVersitProperty::ListType) { |
82 // Add the CHARSET parameter, if necessary and encode in UTF-8 later |
82 qWarning("Variant value is a QStringList but the property's value type is neither " |
83 if (!mCodec->canEncode(valueString)) { |
83 "CompoundType or ListType"); |
84 parameters.insert(QLatin1String("CHARSET"), QLatin1String("UTF-8")); |
84 } |
85 useUtf8 = true; |
85 // Assume it's a ListType |
86 } |
86 separator = QLatin1String(","); |
87 renderedValue = valueString; |
87 } |
|
88 QString replacement = QLatin1Char('\\') + separator; |
|
89 QRegExp separatorRegex = QRegExp(separator); |
|
90 bool first = true; |
|
91 foreach (QString value, values) { |
|
92 if (!(value.isEmpty() && property.valueType() == QVersitProperty::ListType)) { |
|
93 useUtf8 |= encodeVersitValue(parameters, value); |
|
94 if (!first) { |
|
95 renderedValue += separator; |
|
96 } |
|
97 renderedValue += value.replace(separatorRegex, replacement); |
|
98 first = false; |
|
99 } |
|
100 } |
|
101 } else if (variant.type() == QVariant::String) { |
|
102 renderedValue = variant.toString(); |
|
103 useUtf8 = encodeVersitValue(parameters, renderedValue); |
88 } else if (variant.type() == QVariant::ByteArray) { |
104 } else if (variant.type() == QVariant::ByteArray) { |
89 parameters.insert(QLatin1String("ENCODING"), QLatin1String("BASE64")); |
105 parameters.insert(QLatin1String("ENCODING"), QLatin1String("BASE64")); |
90 renderedValue = QLatin1String(variant.toByteArray().toBase64().data()); |
106 renderedValue = QLatin1String(variant.toByteArray().toBase64().data()); |
91 } |
107 } |
92 |
108 |
97 writeString(QLatin1String(":")); |
113 writeString(QLatin1String(":")); |
98 if (variant.canConvert<QVersitDocument>()) { |
114 if (variant.canConvert<QVersitDocument>()) { |
99 writeCrlf(); |
115 writeCrlf(); |
100 QVersitDocument embeddedDocument = variant.value<QVersitDocument>(); |
116 QVersitDocument embeddedDocument = variant.value<QVersitDocument>(); |
101 encodeVersitDocument(embeddedDocument); |
117 encodeVersitDocument(embeddedDocument); |
102 } else if (variant.type() == QVariant::String) { |
118 } else if (variant.type() == QVariant::String || variant.type() == QVariant::StringList) { |
103 writeString(renderedValue, useUtf8); |
119 writeString(renderedValue, useUtf8); |
104 } else if (variant.type() == QVariant::ByteArray) { |
120 } else if (variant.type() == QVariant::ByteArray) { |
105 // One extra folding before the value and |
121 // One extra folding before the value and |
106 // one extra line break after the value are needed in vCard 2.1 |
122 // one extra line break after the value are needed in vCard 2.1 |
107 writeCrlf(); |
123 writeCrlf(); |
110 writeCrlf(); |
126 writeCrlf(); |
111 } |
127 } |
112 writeCrlf(); |
128 writeCrlf(); |
113 } |
129 } |
114 |
130 |
|
131 /*! Performs Quoted-Printable encoding and charset encoding on \a value as per vCard 2.1 spec. |
|
132 Returns true if the value will need to be encoded with UTF-8, false if mCodec is sufficient. */ |
|
133 bool QVCard21Writer::encodeVersitValue(QMultiHash<QString,QString>& parameters, QString& value) |
|
134 { |
|
135 // Quoted-Printable encode the value and add Quoted-Printable parameter, if necessary |
|
136 if (quotedPrintableEncode(value)) |
|
137 parameters.insert(QLatin1String("ENCODING"), QLatin1String("QUOTED-PRINTABLE")); |
|
138 |
|
139 // Add the CHARSET parameter, if necessary and encode in UTF-8 later |
|
140 if (!mCodec->canEncode(value)) { |
|
141 parameters.insert(QLatin1String("CHARSET"), QLatin1String("UTF-8")); |
|
142 return true; |
|
143 } |
|
144 return false; |
|
145 } |
|
146 |
115 /*! |
147 /*! |
116 * Encodes the \a parameters and writes it to the device. |
148 * Encodes the \a parameters and writes it to the device. |
117 */ |
149 */ |
118 void QVCard21Writer::encodeParameters(const QMultiHash<QString,QString>& parameters) |
150 void QVCard21Writer::encodeParameters(const QMultiHash<QString,QString>& parameters) |
119 { |
151 { |
120 QList<QString> names = parameters.uniqueKeys(); |
152 QList<QString> names = parameters.uniqueKeys(); |
121 foreach (QString name, names) { |
153 foreach (const QString& name, names) { |
122 QStringList values = parameters.values(name); |
154 QStringList values = parameters.values(name); |
123 foreach (QString value, values) { |
155 foreach (const QString& value, values) { |
124 writeString(QLatin1String(";")); |
156 writeString(QLatin1String(";")); |
125 QString typeParameterName(QLatin1String("TYPE")); |
157 QString typeParameterName(QLatin1String("TYPE")); |
126 if (name.length() > 0 && name != typeParameterName) { |
158 if (name.length() > 0 && name != typeParameterName) { |
127 writeString(name); |
159 writeString(name); |
128 writeString(QLatin1String("=")); |
160 writeString(QLatin1String("=")); |