1 | /* |
2 | This file is part of the kcal library. |
3 | |
4 | Copyright (c) 2002,2006,2010 David Jarvie <djarvie@kde.org> |
5 | |
6 | This library is free software; you can redistribute it and/or |
7 | modify it under the terms of the GNU Library General Public |
8 | License as published by the Free Software Foundation; either |
9 | version 2 of the License, or (at your option) any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | /** |
22 | @file |
23 | This file is part of the API for handling calendar data and |
24 | defines the CustomProperties class. |
25 | |
26 | @brief |
27 | A class to manage custom calendar properties. |
28 | |
29 | @author David Jarvie \<djarvie@kde.org\> |
30 | */ |
31 | |
32 | #include "customproperties.h" |
33 | #include <kdebug.h> |
34 | #include <QtCore/QByteArray> |
35 | |
36 | using namespace KCal; |
37 | |
38 | //@cond PRIVATE |
39 | static bool checkName( const QByteArray &name ); |
40 | |
41 | class CustomProperties::Private |
42 | { |
43 | public: |
44 | bool operator==( const Private &other ) const; |
45 | QMap<QByteArray, QString> mProperties; // custom calendar properties |
46 | }; |
47 | |
48 | bool CustomProperties::Private::operator==( const CustomProperties::Private &other ) const |
49 | { |
50 | if ( mProperties.count() != other.mProperties.count() ) { |
51 | return false; |
52 | } |
53 | for ( QMap<QByteArray, QString>::ConstIterator it = mProperties.begin(); |
54 | it != mProperties.end(); ++it ) { |
55 | QMap<QByteArray, QString>::ConstIterator itOther = |
56 | other.mProperties.find( it.key() ); |
57 | if ( itOther == other.mProperties.end() || itOther.value() != it.value() ) { |
58 | return false; |
59 | } |
60 | } |
61 | return true; |
62 | } |
63 | //@endcond |
64 | |
65 | CustomProperties::CustomProperties() |
66 | : d( new Private ) |
67 | { |
68 | } |
69 | |
70 | CustomProperties::CustomProperties( const CustomProperties &cp ) |
71 | : d( new Private( *cp.d ) ) |
72 | { |
73 | } |
74 | |
75 | CustomProperties &CustomProperties::operator=( const CustomProperties &other ) |
76 | { |
77 | // check for self assignment |
78 | if ( &other == this ) { |
79 | return *this; |
80 | } |
81 | |
82 | *d = *other.d; |
83 | return *this; |
84 | } |
85 | |
86 | CustomProperties::~CustomProperties() |
87 | { |
88 | delete d; |
89 | } |
90 | |
91 | bool CustomProperties::operator==( const CustomProperties &other ) const |
92 | { |
93 | return *d == *other.d; |
94 | } |
95 | |
96 | void CustomProperties::setCustomProperty( const QByteArray &app, const QByteArray &key, |
97 | const QString &value ) |
98 | { |
99 | if ( value.isNull() || key.isEmpty() || app.isEmpty() ) { |
100 | return; |
101 | } |
102 | QByteArray property = "X-KDE-" + app + '-' + key; |
103 | if ( !checkName( property ) ) { |
104 | return; |
105 | } |
106 | d->mProperties[property] = value; |
107 | customPropertyUpdated(); |
108 | } |
109 | |
110 | void CustomProperties::removeCustomProperty( const QByteArray &app, const QByteArray &key ) |
111 | { |
112 | removeNonKDECustomProperty( QByteArray( "X-KDE-" + app + '-' + key ) ); |
113 | } |
114 | |
115 | QString CustomProperties::customProperty( const QByteArray &app, const QByteArray &key ) const |
116 | { |
117 | return nonKDECustomProperty( QByteArray( "X-KDE-" + app + '-' + key ) ); |
118 | } |
119 | |
120 | QByteArray CustomProperties::customPropertyName( const QByteArray &app, const QByteArray &key ) |
121 | { |
122 | QByteArray property( "X-KDE-" + app + '-' + key ); |
123 | if ( !checkName( property ) ) { |
124 | return QByteArray(); |
125 | } |
126 | return property; |
127 | } |
128 | |
129 | void CustomProperties::setNonKDECustomProperty( const QByteArray &name, const QString &value ) |
130 | { |
131 | if ( value.isNull() || !checkName( name ) ) { |
132 | return; |
133 | } |
134 | d->mProperties[name] = value; |
135 | customPropertyUpdated(); |
136 | } |
137 | |
138 | void CustomProperties::removeNonKDECustomProperty( const QByteArray &name ) |
139 | { |
140 | if ( d->mProperties.remove( name ) ) { |
141 | customPropertyUpdated(); |
142 | } |
143 | } |
144 | |
145 | QString CustomProperties::nonKDECustomProperty( const QByteArray &name ) const |
146 | { |
147 | return d->mProperties.value( name ); |
148 | } |
149 | |
150 | void CustomProperties::setCustomProperties( const QMap<QByteArray, QString> &properties ) |
151 | { |
152 | bool changed = false; |
153 | for ( QMap<QByteArray, QString>::ConstIterator it = properties.begin(); |
154 | it != properties.end(); ++it ) { |
155 | // Validate the property name and convert any null string to empty string |
156 | if ( checkName( it.key() ) ) { |
157 | d->mProperties[it.key()] = it.value().isNull() ? QString( "" ) : it.value(); |
158 | changed = true; |
159 | } |
160 | } |
161 | if ( changed ) { |
162 | customPropertyUpdated(); |
163 | } |
164 | } |
165 | |
166 | QMap<QByteArray, QString> CustomProperties::customProperties() const |
167 | { |
168 | return d->mProperties; |
169 | } |
170 | |
171 | //@cond PRIVATE |
172 | bool checkName( const QByteArray &name ) |
173 | { |
174 | // Check that the property name starts with 'X-' and contains |
175 | // only the permitted characters |
176 | const char *n = name; |
177 | int len = name.length(); |
178 | if ( len < 2 || n[0] != 'X' || n[1] != '-' ) { |
179 | return false; |
180 | } |
181 | for ( int i = 2; i < len; ++i ) { |
182 | char ch = n[i]; |
183 | if ( ( ch >= 'A' && ch <= 'Z' ) || |
184 | ( ch >= 'a' && ch <= 'z' ) || |
185 | ( ch >= '0' && ch <= '9' ) || |
186 | ch == '-' ) { |
187 | continue; |
188 | } |
189 | return false; // invalid character found |
190 | } |
191 | return true; |
192 | } |
193 | //@endcond |
194 | |