summaryrefslogtreecommitdiffabout
path: root/kaddressbook/xxport/csvimportdialog.cpp
Unidiff
Diffstat (limited to 'kaddressbook/xxport/csvimportdialog.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--kaddressbook/xxport/csvimportdialog.cpp922
1 files changed, 922 insertions, 0 deletions
diff --git a/kaddressbook/xxport/csvimportdialog.cpp b/kaddressbook/xxport/csvimportdialog.cpp
new file mode 100644
index 0000000..1093f9c
--- a/dev/null
+++ b/kaddressbook/xxport/csvimportdialog.cpp
@@ -0,0 +1,922 @@
1/*
2 This file is part of KAddressBook.
3 Copyright (C) 2003 Tobias Koenig <tokoe@kde.org>
4 based on the code of KSpread's CSV Import Dialog
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., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20*/
21
22/*
23Enhanced Version of the file for platform independent KDE tools.
24Copyright (c) 2004 Ulf Schenk
25
26$Id$
27*/
28
29
30#include <qbuttongroup.h>
31#include <qcheckbox.h>
32#include <qcombobox.h>
33#include <qinputdialog.h>
34#include <qlabel.h>
35#include <qlineedit.h>
36#include <qpushbutton.h>
37#include <qradiobutton.h>
38#include <qtable.h>
39#include <qlayout.h>
40#include <qtextstream.h>
41#include <qfile.h>
42
43#include <kapplication.h>
44#include <kdebug.h>
45#include <kdialogbase.h>
46#include <kfiledialog.h>
47#include <klineedit.h>
48#include <klocale.h>
49#include <kglobal.h>
50#include <kmessagebox.h>
51#include <kstandarddirs.h>
52#include <kurlrequester.h>
53
54#ifdef DESKTOP_VERSION
55#include "qtable.h"
56#else
57#include "qcombotableitem.h"
58#endif
59#include "csvimportdialog.h"
60
61CSVImportDialog::CSVImportDialog( KABC::AddressBook *ab, QWidget *parent,
62 const char * name )
63 : KDialogBase( Plain, i18n ( "CSV Import Dialog" ), Ok | Cancel | User1 |
64 User2, Ok, parent, name, true, true ),
65 mAdjustRows( false ),
66 mStartLine( 0 ),
67 mTextQuote( '"' ),
68 mDelimiter( "," ),
69 mAddressBook( ab )
70{
71 initGUI();
72
73 mTypeMap.insert( i18n( "Undefined" ), Undefined );
74 mTypeMap.insert( KABC::Addressee::formattedNameLabel(), FormattedName );
75 mTypeMap.insert( KABC::Addressee::familyNameLabel(), FamilyName );
76 mTypeMap.insert( KABC::Addressee::givenNameLabel(), GivenName );
77 mTypeMap.insert( KABC::Addressee::additionalNameLabel(), AdditionalName );
78 mTypeMap.insert( KABC::Addressee::prefixLabel(), Prefix );
79 mTypeMap.insert( KABC::Addressee::suffixLabel(), Suffix );
80 mTypeMap.insert( KABC::Addressee::nickNameLabel(), NickName );
81 mTypeMap.insert( KABC::Addressee::birthdayLabel(), Birthday );
82
83 mTypeMap.insert( KABC::Addressee::homeAddressStreetLabel(), HomeAddressStreet );
84 mTypeMap.insert( KABC::Addressee::homeAddressLocalityLabel(),
85 HomeAddressLocality );
86 mTypeMap.insert( KABC::Addressee::homeAddressRegionLabel(), HomeAddressRegion );
87 mTypeMap.insert( KABC::Addressee::homeAddressPostalCodeLabel(),
88 HomeAddressPostalCode );
89 mTypeMap.insert( KABC::Addressee::homeAddressCountryLabel(),
90 HomeAddressCountry );
91 mTypeMap.insert( KABC::Addressee::homeAddressLabelLabel(), HomeAddressLabel );
92
93 mTypeMap.insert( KABC::Addressee::businessAddressStreetLabel(),
94 BusinessAddressStreet );
95 mTypeMap.insert( KABC::Addressee::businessAddressLocalityLabel(),
96 BusinessAddressLocality );
97 mTypeMap.insert( KABC::Addressee::businessAddressRegionLabel(),
98 BusinessAddressRegion );
99 mTypeMap.insert( KABC::Addressee::businessAddressPostalCodeLabel(),
100 BusinessAddressPostalCode );
101 mTypeMap.insert( KABC::Addressee::businessAddressCountryLabel(),
102 BusinessAddressCountry );
103 mTypeMap.insert( KABC::Addressee::businessAddressLabelLabel(),
104 BusinessAddressLabel );
105
106 mTypeMap.insert( KABC::Addressee::homePhoneLabel(), HomePhone );
107 mTypeMap.insert( KABC::Addressee::businessPhoneLabel(), BusinessPhone );
108 mTypeMap.insert( KABC::Addressee::mobilePhoneLabel(), MobilePhone );
109 mTypeMap.insert( KABC::Addressee::homeFaxLabel(), HomeFax );
110 mTypeMap.insert( KABC::Addressee::businessFaxLabel(), BusinessFax );
111 mTypeMap.insert( KABC::Addressee::carPhoneLabel(), CarPhone );
112 mTypeMap.insert( KABC::Addressee::isdnLabel(), Isdn );
113 mTypeMap.insert( KABC::Addressee::pagerLabel(), Pager );
114 mTypeMap.insert( KABC::Addressee::emailLabel(), Email );
115 mTypeMap.insert( KABC::Addressee::mailerLabel(), Mailer );
116 mTypeMap.insert( KABC::Addressee::titleLabel(), Title );
117 mTypeMap.insert( KABC::Addressee::roleLabel(), Role );
118 mTypeMap.insert( KABC::Addressee::organizationLabel(), Organization );
119 mTypeMap.insert( KABC::Addressee::noteLabel(), Note );
120 mTypeMap.insert( KABC::Addressee::urlLabel(), URL );
121
122 mCustomCounter = mTypeMap.count();
123 int count = mCustomCounter;
124
125 KABC::Field::List fields = mAddressBook->fields( KABC::Field::CustomCategory );
126 KABC::Field::List::Iterator it;
127 for ( it = fields.begin(); it != fields.end(); ++it, ++count )
128 mTypeMap.insert( (*it)->label(), count );
129
130 connect( mDelimiterBox, SIGNAL( clicked( int ) ),
131 this, SLOT( delimiterClicked( int ) ) );
132 connect( mDelimiterEdit, SIGNAL( returnPressed() ),
133 this, SLOT( returnPressed() ) );
134 connect( mDelimiterEdit, SIGNAL( textChanged ( const QString& ) ),
135 this, SLOT( textChanged ( const QString& ) ) );
136 connect( mComboLine, SIGNAL( activated( const QString& ) ),
137 this, SLOT( lineSelected( const QString& ) ) );
138 connect( mComboQuote, SIGNAL( activated( const QString& ) ),
139 this, SLOT( textquoteSelected( const QString& ) ) );
140 connect( mIgnoreDuplicates, SIGNAL( stateChanged( int ) ),
141 this, SLOT( ignoreDuplicatesChanged( int ) ) );
142
143 connect( mUrlRequester, SIGNAL( returnPressed( const QString& ) ),
144 this, SLOT( setFile( const QString& ) ) );
145 connect( mUrlRequester, SIGNAL( urlSelected( const QString& ) ),
146 this, SLOT( setFile( const QString& ) ) );
147 connect( mUrlRequester->lineEdit(), SIGNAL( textChanged ( const QString& ) ),
148 this, SLOT( urlChanged( const QString& ) ) );
149
150 connect( this, SIGNAL( user1Clicked() ),
151 this, SLOT( applyTemplate() ) );
152
153 connect( this, SIGNAL( user2Clicked() ),
154 this, SLOT( saveTemplate() ) );
155
156 // if ( QApplication::desktop()->width() < 321 )
157 QIconSet icon = SmallIcon("filesave");
158
159 findButton( User2 )->setIconSet (icon ) ;
160 icon = SmallIcon("fileopen");
161 findButton( User1 )->setIconSet (icon ) ;
162 int wid = findButton( User2 )->sizeHint().height();
163 findButton( User2 )->setMaximumWidth( wid+4 );
164 findButton( User1 )->setMaximumWidth( wid+4 );
165}
166
167CSVImportDialog::~CSVImportDialog()
168{
169}
170
171KABC::AddresseeList CSVImportDialog::contacts() const
172{
173 KABC::AddresseeList contacts;
174
175 for ( int row = 1; row < mTable->numRows(); ++row ) {
176 KABC::Addressee a;
177 bool emptyRow = true;
178 KABC::Address addrHome( KABC::Address::Home );
179 KABC::Address addrWork( KABC::Address::Work );
180 for ( int col = 0; col < mTable->numCols(); ++col ) {
181
182 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0, col ) );
183
184 if ( !item ) {
185 qDebug( "ERROR: item cast failed" );
186 continue;
187 }
188
189 QString value = mTable->text( row, col );
190 if ( !value.isEmpty() )
191 emptyRow = false;
192
193 switch ( posToType( item->currentItem() ) )
194 {
195 case Undefined:
196 continue;
197 break;
198 case FormattedName:
199 a.setFormattedName( value );
200 break;
201 case GivenName:
202 a.setGivenName( value );
203 break;
204 case FamilyName:
205 a.setFamilyName( value );
206 break;
207 case AdditionalName:
208 a.setAdditionalName( value );
209 break;
210 case Prefix:
211 a.setPrefix( value );
212 break;
213 case Suffix:
214 a.setSuffix( value );
215 break;
216 case NickName:
217 a.setNickName( value );
218 break;
219 case Birthday:
220//US
221//the generated code had the following format: a.setBirthday( QDate::fromString( value, Qt::ISODate ) );
222// But Qt::IsoDate and QDate::fromString was not specified. Do I have the wrong QT version ?
223 {
224 QDate dt = KGlobal::locale()->readDate( value, "%Y-%m-%d"); // = Qt::ISODate
225 a.setBirthday(dt);
226 }
227 break;
228 case Email:
229 if ( !value.isEmpty() )
230 a.insertEmail( value, true );
231 break;
232 case Role:
233 a.setRole( value );
234 break;
235 case Title:
236 a.setTitle( value );
237 break;
238 case Mailer:
239 a.setMailer( value );
240 break;
241 case URL:
242 a.setUrl( value );
243 break;
244 case Organization:
245 a.setOrganization( value );
246 break;
247 case Note:
248 a.setNote( value );
249 break;
250
251 case HomePhone:
252 if ( !value.isEmpty() ) {
253 KABC::PhoneNumber number( value, KABC::PhoneNumber::Home );
254 a.insertPhoneNumber( number );
255 }
256 break;
257 case BusinessPhone:
258 if ( !value.isEmpty() ) {
259 KABC::PhoneNumber number( value, KABC::PhoneNumber::Work );
260 a.insertPhoneNumber( number );
261 }
262 break;
263 case MobilePhone:
264 if ( !value.isEmpty() ) {
265 KABC::PhoneNumber number( value, KABC::PhoneNumber::Cell );
266 a.insertPhoneNumber( number );
267 }
268 break;
269 case HomeFax:
270 if ( !value.isEmpty() ) {
271 KABC::PhoneNumber number( value, KABC::PhoneNumber::Home |
272 KABC::PhoneNumber::Fax );
273 a.insertPhoneNumber( number );
274 }
275 break;
276 case BusinessFax:
277 if ( !value.isEmpty() ) {
278 KABC::PhoneNumber number( value, KABC::PhoneNumber::Work |
279 KABC::PhoneNumber::Fax );
280 a.insertPhoneNumber( number );
281 }
282 break;
283 case CarPhone:
284 if ( !value.isEmpty() ) {
285 KABC::PhoneNumber number( value, KABC::PhoneNumber::Car );
286 a.insertPhoneNumber( number );
287 }
288 break;
289 case Isdn:
290 if ( !value.isEmpty() ) {
291 KABC::PhoneNumber number( value, KABC::PhoneNumber::Isdn );
292 a.insertPhoneNumber( number );
293 }
294 break;
295 case Pager:
296 if ( !value.isEmpty() ) {
297 KABC::PhoneNumber number( value, KABC::PhoneNumber::Pager );
298 a.insertPhoneNumber( number );
299 }
300 break;
301
302 case HomeAddressStreet:
303 addrHome.setStreet( value );
304 break;
305 case HomeAddressLocality:
306 addrHome.setLocality( value );
307 break;
308 case HomeAddressRegion:
309 addrHome.setRegion( value );
310 break;
311 case HomeAddressPostalCode:
312 addrHome.setPostalCode( value );
313 break;
314 case HomeAddressCountry:
315 addrHome.setCountry( value );
316 break;
317 case HomeAddressLabel:
318 addrHome.setLabel( value );
319 break;
320
321 case BusinessAddressStreet:
322 addrWork.setStreet( value );
323 break;
324 case BusinessAddressLocality:
325 addrWork.setLocality( value );
326 break;
327 case BusinessAddressRegion:
328 addrWork.setRegion( value );
329 break;
330 case BusinessAddressPostalCode:
331 addrWork.setPostalCode( value );
332 break;
333 case BusinessAddressCountry:
334 addrWork.setCountry( value );
335 break;
336 case BusinessAddressLabel:
337 addrWork.setLabel( value );
338 break;
339 default:
340 KABC::Field::List fields = mAddressBook->fields( KABC::Field::CustomCategory );
341 KABC::Field::List::Iterator it;
342
343 int counter = 0;
344 for ( it = fields.begin(); it != fields.end(); ++it ) {
345 if ( counter == (int)( posToType( item->currentItem() ) - mCustomCounter ) )
346 {
347 (*it)->setValue( a, value );
348 continue;
349 }
350 ++counter;
351 }
352 break;
353 }
354 }
355
356 if ( !addrHome.isEmpty() )
357 a.insertAddress( addrHome );
358 if ( !addrWork.isEmpty() )
359 a.insertAddress( addrWork );
360
361 if ( !emptyRow && !a.isEmpty() )
362 contacts.append( a );
363 }
364
365 return contacts;
366}
367
368void CSVImportDialog::initGUI()
369{
370 QWidget* page = plainPage();
371
372 QGridLayout *layout = new QGridLayout( page, 1, 1, marginHintSmall(),
373 spacingHintSmall() );
374 QHBoxLayout *hbox = new QHBoxLayout();
375 hbox->setSpacing( spacingHint() );
376
377 QLabel *label = new QLabel( i18n( "File to import:" ), page );
378 hbox->addWidget( label );
379
380 mUrlRequester = new KURLRequester( page );
381 mUrlRequester->setFilter( "*.csv" );
382 hbox->addWidget( mUrlRequester );
383
384 layout->addMultiCellLayout( hbox, 0, 0, 0, 1 );
385
386 // Delimiter: comma, semicolon, tab, space, other
387 mDelimiterBox = new QButtonGroup( i18n( "Delimiter" ), page );
388 mDelimiterBox->setColumnLayout( 0, Qt::Vertical );
389 mDelimiterBox->layout()->setSpacing( spacingHint() );
390 mDelimiterBox->layout()->setMargin( marginHint() );
391 QGridLayout *delimiterLayout = new QGridLayout( mDelimiterBox->layout() );
392 delimiterLayout->setAlignment( Qt::AlignTop );
393 layout->addMultiCellWidget( mDelimiterBox, 1, 1, 0, 1 );
394
395 mRadioComma = new QRadioButton( i18n( "Comma" ), mDelimiterBox );
396 mRadioComma->setChecked( true );
397 delimiterLayout->addWidget( mRadioComma, 0, 0 );
398
399 mRadioSemicolon = new QRadioButton( i18n( "Semicolon" ), mDelimiterBox );
400 delimiterLayout->addWidget( mRadioSemicolon, 0, 1 );
401
402 mRadioTab = new QRadioButton( i18n( "Tabulator" ), mDelimiterBox );
403 delimiterLayout->addWidget( mRadioTab, 1, 0 );
404
405 mRadioSpace = new QRadioButton( i18n( "Space" ), mDelimiterBox );
406 delimiterLayout->addWidget( mRadioSpace, 1, 1 );
407
408 mRadioOther = new QRadioButton( i18n( "Other" ), mDelimiterBox );
409 delimiterLayout->addWidget( mRadioOther, 0, 2 );
410
411 mDelimiterEdit = new QLineEdit( mDelimiterBox );
412 delimiterLayout->addWidget( mDelimiterEdit, 1, 2 );
413
414 mComboLine = new QComboBox( false, page );
415 mComboLine->insertItem( i18n( "1" ) );
416 layout->addWidget( mComboLine, 3, 1 );
417
418 mComboQuote = new QComboBox( false, page );
419 mComboQuote->insertItem( i18n( "\"" ), 0 );
420 mComboQuote->insertItem( i18n( "'" ), 1 );
421 mComboQuote->insertItem( i18n( "None" ), 2 );
422 layout->addWidget( mComboQuote, 3, 0 );
423
424 label = new QLabel( i18n( "Start at line:" ), page );
425 layout->addWidget( label, 2, 1 );
426
427 label = new QLabel( i18n( "Textquote:" ), page );
428 layout->addWidget( label, 2, 0 );
429
430 mIgnoreDuplicates = new QCheckBox( page );
431 mIgnoreDuplicates->setText( i18n( "Ignore duplicate delimiters" ) );
432 layout->addMultiCellWidget( mIgnoreDuplicates, 4, 4, 0, 1 );
433
434 mTable = new QTable( 0, 0, page );
435 mTable->setSelectionMode( QTable::NoSelection );
436 //mTable->horizontalHeader()->hide();
437 layout->addMultiCellWidget( mTable, 5, 5, 0, 1 );
438/*US
439 setButtonText( User1, i18n( "Apply Template" ) );
440 setButtonText( User2, i18n( "Save Template" ) );
441*/
442
443 enableButtonOK( false );
444
445 findButton( User1 )->setEnabled( false );
446 findButton( User2 )->setEnabled( false );
447
448#ifdef DESKTOP_VERSION
449 resize( 500, 300 );
450#else
451 showMaximized();
452#endif
453}
454
455void CSVImportDialog::fillTable()
456{
457 int row, column;
458 bool lastCharDelimiter = false;
459 bool ignoreDups = mIgnoreDuplicates->isChecked();
460 enum { S_START, S_QUOTED_FIELD, S_MAYBE_END_OF_QUOTED_FIELD, S_END_OF_QUOTED_FIELD,
461 S_MAYBE_NORMAL_FIELD, S_NORMAL_FIELD } state = S_START;
462
463 QChar x;
464 QString field = "";
465
466 // store previous assignment
467 QValueList<int> mTypeOld = mTypeStore;
468
469 mTypeStore.clear();
470 for ( column = 0; column < mTable->numCols(); ++column ) {
471 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0, column ) );
472
473 if ( !item || mClearTypeStore )
474 mTypeStore.append( typeToPos( Undefined ) );
475 else if ( item )
476 mTypeStore.append( item->currentItem() );
477 }
478
479 clearTable();
480
481 row = column = 1;
482 mData = QString( mFileArray );
483
484 QTextStream inputStream( mData, IO_ReadOnly );
485 inputStream.setEncoding( QTextStream::Locale );
486
487 int maxColumn = 0;
488 while ( !inputStream.atEnd() ) {
489 inputStream >> x; // read one char
490
491 if ( x == '\r' ) inputStream >> x; // eat '\r', to handle DOS/LOSEDOWS files correctly
492
493 switch ( state ) {
494 case S_START :
495 if ( x == mTextQuote ) {
496 state = S_QUOTED_FIELD;
497 } else if ( x == mDelimiter ) {
498 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
499 ++column;
500 lastCharDelimiter = true;
501 } else if ( x == '\n' ) {
502 ++row;
503 column = 1;
504 } else {
505 field += x;
506 state = S_MAYBE_NORMAL_FIELD;
507 }
508 break;
509 case S_QUOTED_FIELD :
510 if ( x == mTextQuote ) {
511 state = S_MAYBE_END_OF_QUOTED_FIELD;
512 } else if ( x == '\n' ) {
513 setText( row - mStartLine + 1, column, field );
514 field = "";
515 if ( x == '\n' ) {
516 ++row;
517 column = 1;
518 } else {
519 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
520 ++column;
521 lastCharDelimiter = true;
522 }
523 state = S_START;
524 } else {
525 field += x;
526 }
527 break;
528 case S_MAYBE_END_OF_QUOTED_FIELD :
529 if ( x == mTextQuote ) {
530 field += x;
531 state = S_QUOTED_FIELD;
532 } else if ( x == mDelimiter || x == '\n' ) {
533 setText( row - mStartLine + 1, column, field );
534 field = "";
535 if ( x == '\n' ) {
536 ++row;
537 column = 1;
538 } else {
539 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
540 ++column;
541 lastCharDelimiter = true;
542 }
543 state = S_START;
544 } else {
545 state = S_END_OF_QUOTED_FIELD;
546 }
547 break;
548 case S_END_OF_QUOTED_FIELD :
549 if ( x == mDelimiter || x == '\n' ) {
550 setText( row - mStartLine + 1, column, field );
551 field = "";
552 if ( x == '\n' ) {
553 ++row;
554 column = 1;
555 } else {
556 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
557 ++column;
558 lastCharDelimiter = true;
559 }
560 state = S_START;
561 } else {
562 state = S_END_OF_QUOTED_FIELD;
563 }
564 break;
565 case S_MAYBE_NORMAL_FIELD :
566 if ( x == mTextQuote ) {
567 field = "";
568 state = S_QUOTED_FIELD;
569 break;
570 }
571 case S_NORMAL_FIELD :
572 if ( x == mDelimiter || x == '\n' ) {
573 setText( row - mStartLine + 1, column, field );
574 field = "";
575 if ( x == '\n' ) {
576 ++row;
577 column = 1;
578 } else {
579 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
580 ++column;
581 lastCharDelimiter = true;
582 }
583 state = S_START;
584 } else {
585 field += x;
586 }
587 }
588 if ( x != mDelimiter )
589 lastCharDelimiter = false;
590
591 if ( column > maxColumn )
592 maxColumn = column;
593 }
594
595 // file with only one line without '\n'
596 if ( field.length() > 0 ) {
597 setText( row - mStartLine + 1, column, field );
598 ++row;
599 field = "";
600 }
601
602 adjustRows( row - mStartLine );
603 mTable->setNumCols( maxColumn );
604
605//US begin
606 QStringList keys;
607 QMap<QString, uint>::ConstIterator it;
608 for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it)
609 keys << it.key();
610//US end
611
612 for ( column = 0; column < mTable->numCols(); ++column ) {
613
614//US QComboTableItem *item = new QComboTableItem( mTable, mTypeMap.keys() );
615 QComboTableItem *item = new QComboTableItem( mTable, keys );
616 mTable->setItem( 0, column, item );
617 if ( column < mTypeStore.count() )
618 item->setCurrentItem( mTypeStore[ column ] );
619 else
620 item->setCurrentItem( typeToPos( Undefined ) );
621
622 mTable->adjustColumn( column );
623 }
624}
625
626void CSVImportDialog::clearTable()
627{
628 for ( int row = 0; row < mTable->numRows(); ++row )
629 for ( int column = 0; column < mTable->numCols(); ++column )
630 mTable->clearCell( row, column );
631}
632
633void CSVImportDialog::fillComboBox()
634{
635 mComboLine->clear();
636 for ( int row = 1; row < mTable->numRows() + 1; ++row )
637 mComboLine->insertItem( QString::number( row ), row - 1 );
638}
639
640void CSVImportDialog::setText( int row, int col, const QString& text )
641{
642 if ( row < 1 ) // skipped by the user
643 return;
644
645 if ( mTable->numRows() < row ) {
646 mTable->setNumRows( row + 5000 ); // We add 5000 at a time to limit recalculations
647 mAdjustRows = true;
648 }
649
650 if ( mTable->numCols() < col )
651 mTable->setNumCols( col + 50 ); // We add 50 at a time to limit recalculation
652
653 mTable->setText( row - 1, col - 1, text );
654}
655
656/*
657 * Called after the first fillTable() when number of rows are unknown.
658 */
659void CSVImportDialog::adjustRows( int rows )
660{
661 if ( mAdjustRows ) {
662 mTable->setNumRows( rows );
663 mAdjustRows = false;
664 }
665}
666
667void CSVImportDialog::returnPressed()
668{
669 if ( mDelimiterBox->id( mDelimiterBox->selected() ) != 4 )
670 return;
671
672 mDelimiter = mDelimiterEdit->text();
673 fillTable();
674}
675
676void CSVImportDialog::textChanged ( const QString& )
677{
678 mRadioOther->setChecked ( true );
679 delimiterClicked( 4 ); // other
680}
681
682void CSVImportDialog::delimiterClicked( int id )
683{
684 switch ( id ) {
685 case 0: // comma
686 mDelimiter = ",";
687 break;
688 case 4: // other
689 mDelimiter = mDelimiterEdit->text();
690 break;
691 case 2: // tab
692 mDelimiter = "\t";
693 break;
694 case 3: // space
695 mDelimiter = " ";
696 break;
697 case 1: // semicolon
698 mDelimiter = ";";
699 break;
700 }
701
702 fillTable();
703}
704
705void CSVImportDialog::textquoteSelected( const QString& mark )
706{
707 if ( mComboQuote->currentItem() == 2 )
708 mTextQuote = 0;
709 else
710 mTextQuote = mark[ 0 ];
711
712 fillTable();
713}
714
715void CSVImportDialog::lineSelected( const QString& line )
716{
717 mStartLine = line.toInt() - 1;
718 fillTable();
719}
720
721void CSVImportDialog::slotOk()
722{
723 bool assigned = false;
724
725 for ( int column = 0; column < mTable->numCols(); ++column ) {
726 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
727 column ) );
728 if ( item && posToType( item->currentItem() ) != Undefined )
729 assigned = true;
730 }
731
732 if ( assigned )
733 KDialogBase::slotOk();
734 else
735 KMessageBox::sorry( this, i18n( "You have to assign at least one column." ) );
736}
737
738void CSVImportDialog::applyTemplate()
739{
740 QMap<uint,int> columnMap;
741 QMap<QString, QString> fileMap;
742 QStringList templates;
743
744 // load all template files
745/*US QStringList list = KGlobal::dirs()->findAllResources( "data" , QString( kapp->name() ) +
746 "/csv-templates/*.desktop", true, true );
747*/
748 QStringList list = KGlobal::dirs()->findAllResources( "data" , KGlobal::getAppName() +
749 "/csv-templates/*.desktop", true, true );
750
751 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
752 {
753 qDebug("for ");
754//US KSimpleConfig config( *it, true );
755 KConfig config( *it );
756
757 if ( !config.hasGroup( "csv column map" ) )
758 continue;
759
760 config.setGroup( "Misc" );
761 templates.append( config.readEntry( "Name" ) );
762 fileMap.insert( config.readEntry( "Name" ), *it );
763 }
764 qDebug("weiter ");
765 // let the user chose, what to take
766 bool ok = false;
767 QString tmp;
768 tmp = QInputDialog::getItem( i18n( "Template Selection" ),
769 i18n( "Please select a template, that matches the CSV file." ),
770 templates, 0, false, &ok, this );
771
772 if ( !ok )
773 return;
774
775//US KSimpleConfig config( fileMap[ tmp ], true );
776 KConfig config( fileMap[ tmp ] );
777 config.setGroup( "General" );
778//US uint numColumns = config.readUnsignedNumEntry( "Columns" );
779 uint numColumns = (uint)config.readNumEntry( "Columns" );
780
781 mDelimiterEdit->setText( config.readEntry( "DelimiterOther" ) );
782 mDelimiterBox->setButton( config.readNumEntry( "DelimiterType" ) );
783 delimiterClicked( config.readNumEntry( "DelimiterType" ) );
784 int quoteType = config.readNumEntry( "QuoteType" );
785 mComboQuote->setCurrentItem( quoteType );
786 textquoteSelected( mComboQuote->currentText() );
787
788 // create the column map
789 config.setGroup( "csv column map" );
790 for ( uint i = 0; i < numColumns; ++i ) {
791 int col = config.readNumEntry( QString::number( i ) );
792 columnMap.insert( i, col );
793 }
794
795 // apply the column map
796 for ( uint column = 0; column < columnMap.count(); ++column ) {
797 int type = columnMap[ column ];
798 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
799 column ) );
800 if ( item )
801 item->setCurrentItem( typeToPos( type ) );
802 }
803}
804
805void CSVImportDialog::saveTemplate()
806{
807/*US
808 QString fileName = KFileDialog::getSaveFileName(
809 locateLocal( "data", QString( kapp->name() ) + "/csv-templates/" ),
810 "*.desktop", this );
811*/
812 QString fileName = KFileDialog::getSaveFileName(
813 locateLocal( "data", KGlobal::getAppName() + "/csv-templates/" )+
814 "*.desktop",i18n("Save file name") , this );
815
816 if ( fileName.isEmpty() )
817 return;
818
819 if ( !fileName.contains( ".desktop" ) )
820 fileName += ".desktop";
821
822 QString name = QInputDialog::getText( i18n( "Template name" ), i18n( "Please enter a name for the template" ) );
823
824 if ( name.isEmpty() )
825 return;
826
827 KConfig config( fileName );
828 config.setGroup( "General" );
829 config.writeEntry( "Columns", mTable->numCols() );
830 config.writeEntry( "DelimiterType", mDelimiterBox->id( mDelimiterBox->selected() ) );
831 config.writeEntry( "DelimiterOther", mDelimiterEdit->text() );
832 config.writeEntry( "QuoteType", mComboQuote->currentItem() );
833
834 config.setGroup( "Misc" );
835 config.writeEntry( "Name", name );
836
837 config.setGroup( "csv column map" );
838
839 for ( uint column = 0; column < mTable->numCols(); ++column ) {
840 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
841 column ) );
842 if ( item )
843 config.writeEntry( QString::number( column ), posToType(
844 item->currentItem() ) );
845 else
846 config.writeEntry( QString::number( column ), 0 );
847 }
848
849 config.sync();
850}
851
852QString CSVImportDialog::getText( int row, int col )
853{
854 return mTable->text( row, col );
855}
856
857uint CSVImportDialog::posToType( int pos ) const
858{
859 uint counter = 0;
860 QMap<QString, uint>::ConstIterator it;
861 for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it, ++counter )
862 if ( counter == (uint)pos )
863 return it.data();
864
865 return 0;
866}
867
868int CSVImportDialog::typeToPos( uint type ) const
869{
870 uint counter = 0;
871 QMap<QString, uint>::ConstIterator it;
872 for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it, ++counter )
873 if ( it.data() == type )
874 return counter;
875
876 return -1;
877}
878
879void CSVImportDialog::ignoreDuplicatesChanged( int )
880{
881 fillTable();
882}
883
884void CSVImportDialog::setFile( const QString &fileName )
885{
886 if ( fileName.isEmpty() )
887 return;
888
889 QFile file( fileName );
890 if ( !file.open( IO_ReadOnly ) ) {
891 KMessageBox::sorry( this, i18n( "Cannot open input file!" ) );
892 file.close();
893 return;
894 }
895
896 mFileArray = file.readAll();
897 file.close();
898
899 mClearTypeStore = true;
900 clearTable();
901 mTable->setNumCols( 0 );
902 mTable->setNumRows( 0 );
903 fillTable();
904 mClearTypeStore = false;
905
906 fillComboBox();
907}
908
909void CSVImportDialog::urlChanged( const QString &file )
910{
911 bool state = !file.isEmpty();
912
913 enableButtonOK( state );
914
915 findButton( User1 )->setEnabled( state );
916 findButton( User2 )->setEnabled( state );
917
918}
919
920#ifndef KAB_EMBEDDED
921#include <csvimportdialog.moc>
922#endif //KAB_EMBEDDED