1/*
2 This file is part of libkabc.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "phonenumber.h"
22
23#include <klocalizedstring.h>
24#include <krandom.h>
25
26#include <QtCore/QDataStream>
27#include <QtCore/QSharedData>
28
29using namespace KABC;
30
31static QString cleanupNumber( const QString &input )
32{
33 return input.simplified();
34}
35
36class PhoneNumber::Private : public QSharedData
37{
38 public:
39 Private( Type type )
40 : mId( KRandom::randomString( 8 ) ), mType( type )
41 {
42 }
43
44 Private( const Private &other )
45 : QSharedData( other )
46 {
47 mId = other.mId;
48 mType = other.mType;
49 mNumber = other.mNumber;
50 }
51
52 QString mId;
53 Type mType;
54 QString mNumber;
55};
56
57PhoneNumber::PhoneNumber()
58 : d( new Private( Home ) )
59{
60}
61
62PhoneNumber::PhoneNumber( const QString &number, Type type )
63 : d( new Private( type ) )
64{
65 d->mNumber = cleanupNumber( number );
66}
67
68PhoneNumber::PhoneNumber( const PhoneNumber &other )
69 : d( other.d )
70{
71}
72
73PhoneNumber::~PhoneNumber()
74{
75}
76
77bool PhoneNumber::operator==( const PhoneNumber &other ) const
78{
79 if ( d->mId != other.d->mId ) {
80 return false;
81 }
82
83 if ( d->mNumber != other.d->mNumber ) {
84 return false;
85 }
86
87 if ( d->mType != other.d->mType ) {
88 return false;
89 }
90
91 return true;
92}
93
94bool PhoneNumber::operator!=( const PhoneNumber &other ) const
95{
96 return !( other == *this );
97}
98
99PhoneNumber &PhoneNumber::operator=( const PhoneNumber &other )
100{
101 if ( this != &other ) {
102 d = other.d;
103 }
104
105 return *this;
106}
107
108bool PhoneNumber::isEmpty() const
109{
110 return d->mNumber.isEmpty();
111}
112
113void PhoneNumber::setId( const QString &id )
114{
115 d->mId = id;
116}
117
118QString PhoneNumber::id() const
119{
120 return d->mId;
121}
122
123void PhoneNumber::setNumber( const QString &number )
124{
125 d->mNumber = cleanupNumber( number );
126}
127
128QString PhoneNumber::number() const
129{
130 return d->mNumber;
131}
132
133void PhoneNumber::setType( Type type )
134{
135 d->mType = type;
136}
137
138PhoneNumber::Type PhoneNumber::type() const
139{
140 return d->mType;
141}
142
143QString PhoneNumber::typeLabel() const
144{
145 return typeLabel( type() );
146}
147
148PhoneNumber::TypeList PhoneNumber::typeList()
149{
150 static TypeList list;
151
152 if ( list.isEmpty() ) {
153 list << Home << Work << Msg << Pref << Voice << Fax << Cell << Video
154 << Bbs << Modem << Car << Isdn << Pcs << Pager;
155 }
156
157 return list;
158}
159
160QString PhoneNumber::typeFlagLabel( TypeFlag type )
161{
162 switch ( type ) {
163 case Home:
164 return i18nc( "Home phone", "Home" );
165 break;
166 case Work:
167 return i18nc( "Work phone", "Work" );
168 break;
169 case Msg:
170 return i18n( "Messenger" );
171 break;
172 case Pref:
173 return i18nc( "Preferred phone", "Preferred" );
174 break;
175 case Voice:
176 return i18n( "Voice" );
177 break;
178 case Fax:
179 return i18n( "Fax" );
180 break;
181 case Cell:
182 return i18nc( "Mobile Phone", "Mobile" );
183 break;
184 case Video:
185 return i18nc( "Video phone", "Video" );
186 break;
187 case Bbs:
188 return i18n( "Mailbox" );
189 break;
190 case Modem:
191 return i18n( "Modem" );
192 break;
193 case Car:
194 return i18nc( "Car Phone", "Car" );
195 break;
196 case Isdn:
197 return i18n( "ISDN" );
198 break;
199 case Pcs:
200 return i18n( "PCS" );
201 break;
202 case Pager:
203 return i18n( "Pager" );
204 break;
205 default:
206 return i18nc( "another type of phone", "Other" );
207 }
208}
209
210QString PhoneNumber::typeLabel( Type type )
211{
212 QString label;
213 bool first = true;
214
215 // special cases
216 // Pref stand alone -> Preferred Number
217 // Home+Fax or Work+Fax -> combine as initial string
218 if ( type == Pref ) {
219 return i18n( "Preferred Number" );
220 }
221
222 if ( type & Fax ) {
223 if ( type & Home ) {
224 label = i18n( "Home Fax" );
225 first = false;
226 type &= ~Fax;
227 type &= ~Home;
228 } else if ( type & Work ) {
229 label = i18n( "Work Fax" );
230 first = false;
231 type &= ~Fax;
232 type &= ~Work;
233 }
234 }
235
236 const TypeList list = typeList();
237
238 TypeList::ConstIterator it;
239 TypeList::ConstIterator end( list.end() );
240 for ( it = list.begin(); it != end; ++it ) {
241 // these are actually flags
242 const TypeFlag flag = static_cast<TypeFlag>( static_cast<int>( *it ) );
243 if ( type & flag ) {
244 if ( !first ) {
245 label.append( QLatin1Char( '/' ) );
246 }
247
248 label.append( typeFlagLabel( flag ) );
249
250 if ( first ) {
251 first = false;
252 }
253 }
254 }
255
256 return label;
257}
258
259QString PhoneNumber::toString() const
260{
261 QString str;
262
263 str += QString::fromLatin1( "PhoneNumber {\n" );
264 str += QString::fromLatin1( " Id: %1\n" ).arg( d->mId );
265 str += QString::fromLatin1( " Type: %1\n" ).arg( typeLabel( d->mType ) );
266 str += QString::fromLatin1( " Number: %1\n" ).arg( d->mNumber );
267 str += QString::fromLatin1( "}\n" );
268
269 return str;
270}
271
272QDataStream &KABC::operator<<( QDataStream &s, const PhoneNumber &phone )
273{
274 return s << phone.d->mId << (uint)phone.d->mType << phone.d->mNumber;
275}
276
277QDataStream &KABC::operator>>( QDataStream &s, PhoneNumber &phone )
278{
279 uint type;
280 s >> phone.d->mId >> type >> phone.d->mNumber;
281 phone.d->mType = PhoneNumber::Type( type );
282
283 return s;
284}
285