kaddressbook

phoneeditwidget.cpp
1 /*
2  This file is part of KAddressBook.
3  Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program 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
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 
19  As a special exception, permission is given to link this program
20  with any edition of TQt, and distribute the resulting executable,
21  without including the source code for TQt in the source distribution.
22 */
23 
24 #include <tqbuttongroup.h>
25 #include <tqcheckbox.h>
26 #include <tqlabel.h>
27 #include <tqlayout.h>
28 #include <tqlistbox.h>
29 #include <tqlistview.h>
30 #include <tqpushbutton.h>
31 #include <tqsignalmapper.h>
32 #include <tqstring.h>
33 #include <tqtooltip.h>
34 
35 #include <tdeapplication.h>
36 #include <kbuttonbox.h>
37 #include <kcombobox.h>
38 #include <tdeconfig.h>
39 #include <kdebug.h>
40 #include <kiconloader.h>
41 #include <klineedit.h>
42 #include <tdelistview.h>
43 #include <tdelocale.h>
44 
45 #include <tdeabc/phonenumber.h>
46 
47 #include "phoneeditwidget.h"
48 
49 PhoneTypeCombo::PhoneTypeCombo( TQWidget *parent )
50  : KComboBox( parent, "TypeCombo" ),
51  mType( TDEABC::PhoneNumber::Home ),
52  mLastSelected( 0 ),
53  mTypeList( TDEABC::PhoneNumber::typeList() )
54 {
55  mTypeList.append( -1 ); // Others...
56 
57  update();
58 
59  connect( this, TQ_SIGNAL( activated( int ) ),
60  this, TQ_SLOT( selected( int ) ) );
61  connect( this, TQ_SIGNAL( activated( int ) ),
62  this, TQ_SIGNAL( modified() ) );
63 }
64 
65 PhoneTypeCombo::~PhoneTypeCombo()
66 {
67 }
68 
69 void PhoneTypeCombo::setType( int type )
70 {
71  if ( !mTypeList.contains( type ) )
72  mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), type );
73 
74  mType = type;
75  update();
76 }
77 
78 int PhoneTypeCombo::type() const
79 {
80  return mType;
81 }
82 
83 void PhoneTypeCombo::update()
84 {
85  bool blocked = signalsBlocked();
86  blockSignals( true );
87 
88  clear();
89  TQValueList<int>::ConstIterator it;
90  for ( it = mTypeList.begin(); it != mTypeList.end(); ++it ) {
91  if ( *it == -1 ) { // "Other..." entry
92  insertItem( i18n( "Other..." ) );
93  } else {
94  TDEABC::PhoneNumber number;
95  number.setType( *it );
96  insertItem( number.typeLabel() );
97  }
98  }
99 
100  setCurrentItem( mLastSelected = mTypeList.findIndex( mType ) );
101 
102  blockSignals( blocked );
103 }
104 
105 void PhoneTypeCombo::selected( int pos )
106 {
107  if ( mTypeList[ pos ] == -1 )
108  otherSelected();
109  else {
110  mType = mTypeList[ pos ];
111  mLastSelected = pos;
112  }
113 }
114 
115 void PhoneTypeCombo::otherSelected()
116 {
117  PhoneTypeDialog dlg( mType, this );
118  if ( dlg.exec() ) {
119  mType = dlg.type();
120  if ( !mTypeList.contains( mType ) )
121  mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), mType );
122  } else {
123  setType( mTypeList[ mLastSelected ] );
124  }
125 
126  update();
127 }
128 
129 PhoneNumberWidget::PhoneNumberWidget( TQWidget *parent )
130  : TQWidget( parent )
131 {
132  TQHBoxLayout *layout = new TQHBoxLayout( this, 6, 11 );
133 
134  mTypeCombo = new PhoneTypeCombo( this );
135  mNumberEdit = new KLineEdit( this );
136 
137  layout->addWidget( mTypeCombo );
138  layout->addWidget( mNumberEdit );
139 
140  connect( mTypeCombo, TQ_SIGNAL( modified() ), TQ_SIGNAL( modified() ) );
141  connect( mNumberEdit, TQ_SIGNAL( textChanged( const TQString& ) ), TQ_SIGNAL( modified() ) );
142 }
143 
144 void PhoneNumberWidget::setNumber( const TDEABC::PhoneNumber &number )
145 {
146  mNumber = number;
147 
148  mTypeCombo->setType( number.type() );
149  mNumberEdit->setText( number.number() );
150 }
151 
152 TDEABC::PhoneNumber PhoneNumberWidget::number() const
153 {
154  TDEABC::PhoneNumber number( mNumber );
155 
156  number.setType( mTypeCombo->type() );
157  number.setNumber( mNumberEdit->text() );
158 
159  return number;
160 }
161 
162 void PhoneNumberWidget::setReadOnly( bool readOnly )
163 {
164  mTypeCombo->setEnabled( !readOnly );
165  mNumberEdit->setReadOnly( readOnly );
166 }
167 
168 
169 PhoneEditWidget::PhoneEditWidget( TQWidget *parent, const char *name )
170  : TQWidget( parent, name ), mReadOnly( false )
171 {
172  TQGridLayout *layout = new TQGridLayout( this, 2, 2 );
173  layout->setSpacing( KDialog::spacingHint() );
174 
175  mWidgetLayout = new TQVBoxLayout( layout );
176  layout->addMultiCellLayout( mWidgetLayout, 0, 0, 0, 1 );
177 
178  mAddButton = new TQPushButton( i18n( "Add" ), this );
179  mAddButton->setMaximumSize( mAddButton->sizeHint() );
180  layout->addWidget( mAddButton, 1, 0, TQt::AlignRight );
181 
182  mRemoveButton = new TQPushButton( i18n( "Remove" ), this );
183  mRemoveButton->setMaximumSize( mRemoveButton->sizeHint() );
184  layout->addWidget( mRemoveButton, 1, 1 );
185 
186  mMapper = new TQSignalMapper( this );
187  connect( mMapper, TQ_SIGNAL( mapped( int ) ), TQ_SLOT( changed( int ) ) );
188 
189  connect( mAddButton, TQ_SIGNAL( clicked() ), TQ_SLOT( add() ) );
190  connect( mRemoveButton, TQ_SIGNAL( clicked() ), TQ_SLOT( remove() ) );
191 }
192 
193 PhoneEditWidget::~PhoneEditWidget()
194 {
195 }
196 
197 void PhoneEditWidget::setReadOnly( bool readOnly )
198 {
199  mReadOnly = readOnly;
200  mAddButton->setEnabled( !readOnly );
201  mRemoveButton->setEnabled( !readOnly && mPhoneNumberList.count() > 3 );
202 
203  TQPtrListIterator<PhoneNumberWidget> it( mWidgets );
204  while ( it.current() ) {
205  it.current()->setReadOnly( readOnly );
206  ++it;
207  }
208 }
209 
210 void PhoneEditWidget::setPhoneNumbers( const TDEABC::PhoneNumber::List &list )
211 {
212  mPhoneNumberList = list;
213 
214  TDEABC::PhoneNumber::TypeList types;
215  types << TDEABC::PhoneNumber::Home;
216  types << TDEABC::PhoneNumber::Work;
217  types << TDEABC::PhoneNumber::Cell;
218 
219  // add an empty entry per default
220  if ( mPhoneNumberList.count() < 3 )
221  for ( int i = mPhoneNumberList.count(); i < 3; ++i )
222  mPhoneNumberList.append( TDEABC::PhoneNumber( "", types[ i ] ) );
223 
224  recreateNumberWidgets();
225 }
226 
227 TDEABC::PhoneNumber::List PhoneEditWidget::phoneNumbers() const
228 {
229  TDEABC::PhoneNumber::List list;
230 
231  TDEABC::PhoneNumber::List::ConstIterator it;
232  for ( it = mPhoneNumberList.begin(); it != mPhoneNumberList.end(); ++it )
233  if ( !(*it).number().isEmpty() )
234  list.append( *it );
235 
236  return list;
237 }
238 
239 void PhoneEditWidget::changed()
240 {
241  if ( !mReadOnly )
242  emit modified();
243 }
244 
245 void PhoneEditWidget::add()
246 {
247  mPhoneNumberList.append( TDEABC::PhoneNumber() );
248 
249  recreateNumberWidgets();
250 }
251 
252 void PhoneEditWidget::remove()
253 {
254  mPhoneNumberList.remove( mPhoneNumberList.last() );
255  changed();
256 
257  recreateNumberWidgets();
258 }
259 
260 void PhoneEditWidget::recreateNumberWidgets()
261 {
262  for ( TQWidget *w = mWidgets.first(); w; w = mWidgets.next() ) {
263  mWidgetLayout->remove( w );
264  w->deleteLater();
265  }
266  mWidgets.clear();
267 
268  TDEABC::PhoneNumber::List::ConstIterator it;
269  int counter = 0;
270  for ( it = mPhoneNumberList.begin(); it != mPhoneNumberList.end(); ++it ) {
271  PhoneNumberWidget *wdg = new PhoneNumberWidget( this );
272  wdg->setNumber( *it );
273 
274  mMapper->setMapping( wdg, counter );
275  connect( wdg, TQ_SIGNAL( modified() ), mMapper, TQ_SLOT( map() ) );
276 
277  mWidgetLayout->addWidget( wdg );
278  mWidgets.append( wdg );
279  wdg->show();
280 
281  ++counter;
282  }
283  setReadOnly(mReadOnly);
284 }
285 
286 void PhoneEditWidget::changed( int pos )
287 {
288  mPhoneNumberList[ pos ] = mWidgets.at( pos )->number();
289  changed();
290 }
291 
293 // PhoneTypeDialog
294 PhoneTypeDialog::PhoneTypeDialog( int type, TQWidget *parent )
295  : KDialogBase( Plain, i18n( "Edit Phone Number" ), Ok | Cancel, Ok,
296  parent, "PhoneTypeDialog", true ),
297  mType( type )
298 {
299  TQWidget *page = plainPage();
300 
301  TQVBoxLayout *layout = new TQVBoxLayout( page, spacingHint() );
302 
303  mPreferredBox = new TQCheckBox( i18n( "This is the preferred phone number" ), page );
304  layout->addWidget( mPreferredBox );
305 
306  mGroup = new TQButtonGroup( 2, TQt::Horizontal, i18n( "Types" ), page );
307  layout->addWidget( mGroup );
308 
309  // fill widgets
310  mTypeList = TDEABC::PhoneNumber::typeList();
311  mTypeList.remove( TDEABC::PhoneNumber::Pref );
312 
313  TDEABC::PhoneNumber::TypeList::ConstIterator it;
314  for ( it = mTypeList.begin(); it != mTypeList.end(); ++it )
315  new TQCheckBox( TDEABC::PhoneNumber::typeLabel( *it ), mGroup );
316 
317  for ( int i = 0; i < mGroup->count(); ++i ) {
318  TQCheckBox *box = (TQCheckBox*)mGroup->find( i );
319  box->setChecked( mType & mTypeList[ i ] );
320  }
321 
322  mPreferredBox->setChecked( mType & TDEABC::PhoneNumber::Pref );
323 }
324 
325 int PhoneTypeDialog::type() const
326 {
327  int type = 0;
328 
329  for ( int i = 0; i < mGroup->count(); ++i ) {
330  TQCheckBox *box = (TQCheckBox*)mGroup->find( i );
331  if ( box->isChecked() )
332  type += mTypeList[ i ];
333  }
334 
335  if ( mPreferredBox->isChecked() )
336  type = type | TDEABC::PhoneNumber::Pref;
337  else
338  type = type & ~TDEABC::PhoneNumber::Pref;
339 
340  return type;
341 }
342 
343 
344 #include "phoneeditwidget.moc"
Dialog for editing phone number types.