00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qbuttongroup.h>
00024 #include <qcheckbox.h>
00025 #include <qcombobox.h>
00026 #include <qlabel.h>
00027 #include <qlayout.h>
00028 #include <qlineedit.h>
00029 #include <qpushbutton.h>
00030 #include <qradiobutton.h>
00031 #include <qtable.h>
00032 #include <qtooltip.h>
00033
00034 #include <kapplication.h>
00035 #include <kdebug.h>
00036 #include <kdialogbase.h>
00037 #include <kfiledialog.h>
00038 #include <klineedit.h>
00039 #include <klocale.h>
00040 #include <kinputdialog.h>
00041 #include <kmessagebox.h>
00042 #include <kprogress.h>
00043 #include <kstandarddirs.h>
00044 #include <kurlrequester.h>
00045
00046 #include "dateparser.h"
00047
00048 #include "csvimportdialog.h"
00049
00050 CSVImportDialog::CSVImportDialog( KABC::AddressBook *ab, QWidget *parent,
00051 const char * name )
00052 : KDialogBase( Plain, i18n ( "CSV Import Dialog" ), Ok | Cancel | User1 |
00053 User2, Ok, parent, name, true, true ),
00054 mAdjustRows( false ),
00055 mStartLine( 0 ),
00056 mTextQuote( '"' ),
00057 mDelimiter( "," ),
00058 mAddressBook( ab )
00059 {
00060 initGUI();
00061
00062 mTypeMap.insert( i18n( "Undefined" ), Undefined );
00063 mTypeMap.insert( KABC::Addressee::formattedNameLabel(), FormattedName );
00064 mTypeMap.insert( KABC::Addressee::familyNameLabel(), FamilyName );
00065 mTypeMap.insert( KABC::Addressee::givenNameLabel(), GivenName );
00066 mTypeMap.insert( KABC::Addressee::additionalNameLabel(), AdditionalName );
00067 mTypeMap.insert( KABC::Addressee::prefixLabel(), Prefix );
00068 mTypeMap.insert( KABC::Addressee::suffixLabel(), Suffix );
00069 mTypeMap.insert( KABC::Addressee::nickNameLabel(), NickName );
00070 mTypeMap.insert( KABC::Addressee::birthdayLabel(), Birthday );
00071
00072 mTypeMap.insert( KABC::Addressee::homeAddressStreetLabel(), HomeAddressStreet );
00073 mTypeMap.insert( KABC::Addressee::homeAddressLocalityLabel(),
00074 HomeAddressLocality );
00075 mTypeMap.insert( KABC::Addressee::homeAddressRegionLabel(), HomeAddressRegion );
00076 mTypeMap.insert( KABC::Addressee::homeAddressPostalCodeLabel(),
00077 HomeAddressPostalCode );
00078 mTypeMap.insert( KABC::Addressee::homeAddressCountryLabel(),
00079 HomeAddressCountry );
00080 mTypeMap.insert( KABC::Addressee::homeAddressLabelLabel(), HomeAddressLabel );
00081
00082 mTypeMap.insert( KABC::Addressee::businessAddressStreetLabel(),
00083 BusinessAddressStreet );
00084 mTypeMap.insert( KABC::Addressee::businessAddressLocalityLabel(),
00085 BusinessAddressLocality );
00086 mTypeMap.insert( KABC::Addressee::businessAddressRegionLabel(),
00087 BusinessAddressRegion );
00088 mTypeMap.insert( KABC::Addressee::businessAddressPostalCodeLabel(),
00089 BusinessAddressPostalCode );
00090 mTypeMap.insert( KABC::Addressee::businessAddressCountryLabel(),
00091 BusinessAddressCountry );
00092 mTypeMap.insert( KABC::Addressee::businessAddressLabelLabel(),
00093 BusinessAddressLabel );
00094
00095 mTypeMap.insert( KABC::Addressee::homePhoneLabel(), HomePhone );
00096 mTypeMap.insert( KABC::Addressee::businessPhoneLabel(), BusinessPhone );
00097 mTypeMap.insert( KABC::Addressee::mobilePhoneLabel(), MobilePhone );
00098 mTypeMap.insert( KABC::Addressee::homeFaxLabel(), HomeFax );
00099 mTypeMap.insert( KABC::Addressee::businessFaxLabel(), BusinessFax );
00100 mTypeMap.insert( KABC::Addressee::carPhoneLabel(), CarPhone );
00101 mTypeMap.insert( KABC::Addressee::isdnLabel(), Isdn );
00102 mTypeMap.insert( KABC::Addressee::pagerLabel(), Pager );
00103 mTypeMap.insert( KABC::Addressee::emailLabel(), Email );
00104 mTypeMap.insert( KABC::Addressee::mailerLabel(), Mailer );
00105 mTypeMap.insert( KABC::Addressee::titleLabel(), Title );
00106 mTypeMap.insert( KABC::Addressee::roleLabel(), Role );
00107 mTypeMap.insert( KABC::Addressee::organizationLabel(), Organization );
00108 mTypeMap.insert( KABC::Addressee::noteLabel(), Note );
00109 mTypeMap.insert( KABC::Addressee::urlLabel(), URL );
00110
00111 mCustomCounter = mTypeMap.count();
00112 int count = mCustomCounter;
00113
00114 KABC::Field::List fields = mAddressBook->fields( KABC::Field::CustomCategory );
00115 KABC::Field::List::Iterator it;
00116 for ( it = fields.begin(); it != fields.end(); ++it, ++count )
00117 mTypeMap.insert( (*it)->label(), count );
00118
00119 connect( mDelimiterBox, SIGNAL( clicked( int ) ),
00120 this, SLOT( delimiterClicked( int ) ) );
00121 connect( mDelimiterEdit, SIGNAL( returnPressed() ),
00122 this, SLOT( returnPressed() ) );
00123 connect( mDelimiterEdit, SIGNAL( textChanged ( const QString& ) ),
00124 this, SLOT( textChanged ( const QString& ) ) );
00125 connect( mComboLine, SIGNAL( activated( const QString& ) ),
00126 this, SLOT( lineSelected( const QString& ) ) );
00127 connect( mComboQuote, SIGNAL( activated( const QString& ) ),
00128 this, SLOT( textquoteSelected( const QString& ) ) );
00129 connect( mIgnoreDuplicates, SIGNAL( stateChanged( int ) ),
00130 this, SLOT( ignoreDuplicatesChanged( int ) ) );
00131
00132 connect( mUrlRequester, SIGNAL( returnPressed( const QString& ) ),
00133 this, SLOT( setFile( const QString& ) ) );
00134 connect( mUrlRequester, SIGNAL( urlSelected( const QString& ) ),
00135 this, SLOT( setFile( const QString& ) ) );
00136 connect( mUrlRequester->lineEdit(), SIGNAL( textChanged ( const QString& ) ),
00137 this, SLOT( urlChanged( const QString& ) ) );
00138
00139 connect( this, SIGNAL( user1Clicked() ),
00140 this, SLOT( applyTemplate() ) );
00141
00142 connect( this, SIGNAL( user2Clicked() ),
00143 this, SLOT( saveTemplate() ) );
00144 }
00145
00146 CSVImportDialog::~CSVImportDialog()
00147 {
00148 }
00149
00150 KABC::AddresseeList CSVImportDialog::contacts() const
00151 {
00152 DateParser dateParser( mDatePatternEdit->text() );
00153 KABC::AddresseeList contacts;
00154
00155 KProgressDialog progressDialog( mPage );
00156 progressDialog.setAutoClose( true );
00157 progressDialog.progressBar()->setTotalSteps( mTable->numRows() );
00158 progressDialog.setLabel( i18n( "Importing contacts" ) );
00159 progressDialog.show();
00160
00161 kapp->processEvents();
00162
00163 for ( int row = 1; row < mTable->numRows(); ++row ) {
00164 KABC::Addressee a;
00165 bool emptyRow = true;
00166 KABC::Address addrHome( KABC::Address::Home );
00167 KABC::Address addrWork( KABC::Address::Work );
00168 for ( int col = 0; col < mTable->numCols(); ++col ) {
00169 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
00170 col ) );
00171 if ( !item ) {
00172 kdError() << "ERROR: item cast failed" << endl;
00173 continue;
00174 }
00175
00176 QString value = mTable->text( row, col );
00177 if ( !value.isEmpty() )
00178 emptyRow = false;
00179
00180 switch ( posToType( item->currentItem() ) ) {
00181 case Undefined:
00182 continue;
00183 break;
00184 case FormattedName:
00185 a.setFormattedName( value );
00186 break;
00187 case GivenName:
00188 a.setGivenName( value );
00189 break;
00190 case FamilyName:
00191 a.setFamilyName( value );
00192 break;
00193 case AdditionalName:
00194 a.setAdditionalName( value );
00195 break;
00196 case Prefix:
00197 a.setPrefix( value );
00198 break;
00199 case Suffix:
00200 a.setSuffix( value );
00201 break;
00202 case NickName:
00203 a.setNickName( value );
00204 break;
00205 case Birthday:
00206 a.setBirthday( dateParser.parse( value ) );
00207 break;
00208 case Email:
00209 if ( !value.isEmpty() )
00210 a.insertEmail( value, true );
00211 break;
00212 case Role:
00213 a.setRole( value );
00214 break;
00215 case Title:
00216 a.setTitle( value );
00217 break;
00218 case Mailer:
00219 a.setMailer( value );
00220 break;
00221 case URL:
00222 a.setUrl( KURL( value ) );
00223 break;
00224 case Organization:
00225 a.setOrganization( value );
00226 break;
00227 case Note:
00228 a.setNote( value );
00229 break;
00230
00231 case HomePhone:
00232 if ( !value.isEmpty() ) {
00233 KABC::PhoneNumber number( value, KABC::PhoneNumber::Home );
00234 a.insertPhoneNumber( number );
00235 }
00236 break;
00237 case BusinessPhone:
00238 if ( !value.isEmpty() ) {
00239 KABC::PhoneNumber number( value, KABC::PhoneNumber::Work );
00240 a.insertPhoneNumber( number );
00241 }
00242 break;
00243 case MobilePhone:
00244 if ( !value.isEmpty() ) {
00245 KABC::PhoneNumber number( value, KABC::PhoneNumber::Cell );
00246 a.insertPhoneNumber( number );
00247 }
00248 break;
00249 case HomeFax:
00250 if ( !value.isEmpty() ) {
00251 KABC::PhoneNumber number( value, KABC::PhoneNumber::Home |
00252 KABC::PhoneNumber::Fax );
00253 a.insertPhoneNumber( number );
00254 }
00255 break;
00256 case BusinessFax:
00257 if ( !value.isEmpty() ) {
00258 KABC::PhoneNumber number( value, KABC::PhoneNumber::Work |
00259 KABC::PhoneNumber::Fax );
00260 a.insertPhoneNumber( number );
00261 }
00262 break;
00263 case CarPhone:
00264 if ( !value.isEmpty() ) {
00265 KABC::PhoneNumber number( value, KABC::PhoneNumber::Car );
00266 a.insertPhoneNumber( number );
00267 }
00268 break;
00269 case Isdn:
00270 if ( !value.isEmpty() ) {
00271 KABC::PhoneNumber number( value, KABC::PhoneNumber::Isdn );
00272 a.insertPhoneNumber( number );
00273 }
00274 break;
00275 case Pager:
00276 if ( !value.isEmpty() ) {
00277 KABC::PhoneNumber number( value, KABC::PhoneNumber::Pager );
00278 a.insertPhoneNumber( number );
00279 }
00280 break;
00281
00282 case HomeAddressStreet:
00283 addrHome.setStreet( value );
00284 break;
00285 case HomeAddressLocality:
00286 addrHome.setLocality( value );
00287 break;
00288 case HomeAddressRegion:
00289 addrHome.setRegion( value );
00290 break;
00291 case HomeAddressPostalCode:
00292 addrHome.setPostalCode( value );
00293 break;
00294 case HomeAddressCountry:
00295 addrHome.setCountry( value );
00296 break;
00297 case HomeAddressLabel:
00298 addrHome.setLabel( value );
00299 break;
00300
00301 case BusinessAddressStreet:
00302 addrWork.setStreet( value );
00303 break;
00304 case BusinessAddressLocality:
00305 addrWork.setLocality( value );
00306 break;
00307 case BusinessAddressRegion:
00308 addrWork.setRegion( value );
00309 break;
00310 case BusinessAddressPostalCode:
00311 addrWork.setPostalCode( value );
00312 break;
00313 case BusinessAddressCountry:
00314 addrWork.setCountry( value );
00315 break;
00316 case BusinessAddressLabel:
00317 addrWork.setLabel( value );
00318 break;
00319 default:
00320 KABC::Field::List fields = mAddressBook->fields( KABC::Field::CustomCategory );
00321 KABC::Field::List::Iterator it;
00322
00323 int counter = 0;
00324 for ( it = fields.begin(); it != fields.end(); ++it ) {
00325 if ( counter == (int)( posToType( item->currentItem() ) - mCustomCounter ) ) {
00326 (*it)->setValue( a, value );
00327 continue;
00328 }
00329 ++counter;
00330 }
00331 break;
00332 }
00333 }
00334
00335 kapp->processEvents();
00336
00337 if ( progressDialog.wasCancelled() )
00338 return KABC::AddresseeList();
00339
00340 progressDialog.progressBar()->advance( 1 );
00341
00342 if ( !addrHome.isEmpty() )
00343 a.insertAddress( addrHome );
00344 if ( !addrWork.isEmpty() )
00345 a.insertAddress( addrWork );
00346
00347 if ( !emptyRow && !a.isEmpty() )
00348 contacts.append( a );
00349 }
00350
00351 return contacts;
00352 }
00353
00354 void CSVImportDialog::initGUI()
00355 {
00356 mPage = plainPage();
00357
00358 QGridLayout *layout = new QGridLayout( mPage, 1, 1, marginHint(),
00359 spacingHint() );
00360 QHBoxLayout *hbox = new QHBoxLayout();
00361 hbox->setSpacing( spacingHint() );
00362
00363 QLabel *label = new QLabel( i18n( "File to import:" ), mPage );
00364 hbox->addWidget( label );
00365
00366 mUrlRequester = new KURLRequester( mPage );
00367 mUrlRequester->setFilter( "*.csv" );
00368 hbox->addWidget( mUrlRequester );
00369
00370 layout->addMultiCellLayout( hbox, 0, 0, 0, 4 );
00371
00372
00373 mDelimiterBox = new QButtonGroup( i18n( "Delimiter" ), mPage );
00374 mDelimiterBox->setColumnLayout( 0, Qt::Vertical );
00375 mDelimiterBox->layout()->setSpacing( spacingHint() );
00376 mDelimiterBox->layout()->setMargin( marginHint() );
00377 QGridLayout *delimiterLayout = new QGridLayout( mDelimiterBox->layout() );
00378 delimiterLayout->setAlignment( Qt::AlignTop );
00379 layout->addMultiCellWidget( mDelimiterBox, 1, 3, 0, 0 );
00380
00381 mRadioComma = new QRadioButton( i18n( "Comma" ), mDelimiterBox );
00382 mRadioComma->setChecked( true );
00383 delimiterLayout->addWidget( mRadioComma, 0, 0 );
00384
00385 mRadioSemicolon = new QRadioButton( i18n( "Semicolon" ), mDelimiterBox );
00386 delimiterLayout->addWidget( mRadioSemicolon, 0, 1 );
00387
00388 mRadioTab = new QRadioButton( i18n( "Tabulator" ), mDelimiterBox );
00389 delimiterLayout->addWidget( mRadioTab, 1, 0 );
00390
00391 mRadioSpace = new QRadioButton( i18n( "Space" ), mDelimiterBox );
00392 delimiterLayout->addWidget( mRadioSpace, 1, 1 );
00393
00394 mRadioOther = new QRadioButton( i18n( "Other" ), mDelimiterBox );
00395 delimiterLayout->addWidget( mRadioOther, 0, 2 );
00396
00397 mDelimiterEdit = new QLineEdit( mDelimiterBox );
00398 delimiterLayout->addWidget( mDelimiterEdit, 1, 2 );
00399
00400 mComboLine = new QComboBox( false, mPage );
00401 mComboLine->insertItem( i18n( "1" ) );
00402 layout->addWidget( mComboLine, 2, 3 );
00403
00404 mComboQuote = new QComboBox( false, mPage );
00405 mComboQuote->insertItem( i18n( "\"" ), 0 );
00406 mComboQuote->insertItem( i18n( "'" ), 1 );
00407 mComboQuote->insertItem( i18n( "None" ), 2 );
00408 layout->addWidget( mComboQuote, 2, 2 );
00409
00410 mDatePatternEdit = new QLineEdit( mPage );
00411 mDatePatternEdit->setText( "Y-M-D" );
00412 QToolTip::add( mDatePatternEdit, i18n( "<ul><li>y: year with 2 digits</li>"
00413 "<li>Y: year with 4 digits</li>"
00414 "<li>m: month with 1 or 2 digits</li>"
00415 "<li>M: month with 2 digits</li>"
00416 "<li>d: day with 1 or 2 digits</li>"
00417 "<li>D: day with 2 digits</li></ul>" ) );
00418 layout->addWidget( mDatePatternEdit, 2, 4 );
00419
00420 label = new QLabel( i18n( "Start at line:" ), mPage );
00421 layout->addWidget( label, 1, 3 );
00422
00423 label = new QLabel( i18n( "Textquote:" ), mPage );
00424 layout->addWidget( label, 1, 2 );
00425
00426 label = new QLabel( i18n( "Date format:" ), mPage );
00427 layout->addWidget( label, 1, 4 );
00428
00429 mIgnoreDuplicates = new QCheckBox( mPage );
00430 mIgnoreDuplicates->setText( i18n( "Ignore duplicate delimiters" ) );
00431 layout->addMultiCellWidget( mIgnoreDuplicates, 3, 3, 2, 4 );
00432
00433 mTable = new QTable( 0, 0, mPage );
00434 mTable->setSelectionMode( QTable::NoSelection );
00435 mTable->horizontalHeader()->hide();
00436 layout->addMultiCellWidget( mTable, 4, 4, 0, 4 );
00437
00438 setButtonText( User1, i18n( "Apply Template" ) );
00439 setButtonText( User2, i18n( "Save Template" ) );
00440
00441 enableButtonOK( false );
00442 actionButton( User1 )->setEnabled( false );
00443 actionButton( User2 )->setEnabled( false );
00444
00445 resize( 400, 300 );
00446 }
00447
00448 void CSVImportDialog::fillTable()
00449 {
00450 int row, column;
00451 bool lastCharDelimiter = false;
00452 bool ignoreDups = mIgnoreDuplicates->isChecked();
00453 enum { S_START, S_QUOTED_FIELD, S_MAYBE_END_OF_QUOTED_FIELD, S_END_OF_QUOTED_FIELD,
00454 S_MAYBE_NORMAL_FIELD, S_NORMAL_FIELD } state = S_START;
00455
00456 QChar x;
00457 QString field;
00458
00459
00460 mTypeStore.clear();
00461 for ( column = 0; column < mTable->numCols(); ++column ) {
00462 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
00463 column ) );
00464 if ( !item || mClearTypeStore )
00465 mTypeStore.append( typeToPos( Undefined ) );
00466 else if ( item )
00467 mTypeStore.append( item->currentItem() );
00468 }
00469
00470 clearTable();
00471
00472 row = column = 1;
00473 mData = QString( mFileArray );
00474
00475 QTextStream inputStream( mData, IO_ReadOnly );
00476 inputStream.setEncoding( QTextStream::Locale );
00477
00478 int maxColumn = 0;
00479 while ( !inputStream.atEnd() ) {
00480 inputStream >> x;
00481
00482 if ( x == '\r' ) inputStream >> x;
00483
00484 switch ( state ) {
00485 case S_START :
00486 if ( x == mTextQuote ) {
00487 state = S_QUOTED_FIELD;
00488 } else if ( x == mDelimiter ) {
00489 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
00490 ++column;
00491 lastCharDelimiter = true;
00492 } else if ( x == '\n' ) {
00493 ++row;
00494 column = 1;
00495 } else {
00496 field += x;
00497 state = S_MAYBE_NORMAL_FIELD;
00498 }
00499 break;
00500 case S_QUOTED_FIELD :
00501 if ( x == mTextQuote ) {
00502 state = S_MAYBE_END_OF_QUOTED_FIELD;
00503 } else if ( x == '\n' ) {
00504 setText( row - mStartLine + 1, column, field );
00505 field = "";
00506 if ( x == '\n' ) {
00507 ++row;
00508 column = 1;
00509 } else {
00510 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
00511 ++column;
00512 lastCharDelimiter = true;
00513 }
00514 state = S_START;
00515 } else {
00516 field += x;
00517 }
00518 break;
00519 case S_MAYBE_END_OF_QUOTED_FIELD :
00520 if ( x == mTextQuote ) {
00521 field += x;
00522 state = S_QUOTED_FIELD;
00523 } else if ( x == mDelimiter || x == '\n' ) {
00524 setText( row - mStartLine + 1, column, field );
00525 field = "";
00526 if ( x == '\n' ) {
00527 ++row;
00528 column = 1;
00529 } else {
00530 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
00531 ++column;
00532 lastCharDelimiter = true;
00533 }
00534 state = S_START;
00535 } else {
00536 state = S_END_OF_QUOTED_FIELD;
00537 }
00538 break;
00539 case S_END_OF_QUOTED_FIELD :
00540 if ( x == mDelimiter || x == '\n' ) {
00541 setText( row - mStartLine + 1, column, field );
00542 field = "";
00543 if ( x == '\n' ) {
00544 ++row;
00545 column = 1;
00546 } else {
00547 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
00548 ++column;
00549 lastCharDelimiter = true;
00550 }
00551 state = S_START;
00552 } else {
00553 state = S_END_OF_QUOTED_FIELD;
00554 }
00555 break;
00556 case S_MAYBE_NORMAL_FIELD :
00557 if ( x == mTextQuote ) {
00558 field = "";
00559 state = S_QUOTED_FIELD;
00560 break;
00561 }
00562 case S_NORMAL_FIELD :
00563 if ( x == mDelimiter || x == '\n' ) {
00564 setText( row - mStartLine + 1, column, field );
00565 field = "";
00566 if ( x == '\n' ) {
00567 ++row;
00568 column = 1;
00569 } else {
00570 if ( ( ignoreDups == false ) || ( lastCharDelimiter == false ) )
00571 ++column;
00572 lastCharDelimiter = true;
00573 }
00574 state = S_START;
00575 } else {
00576 field += x;
00577 }
00578 }
00579 if ( x != mDelimiter )
00580 lastCharDelimiter = false;
00581
00582 if ( column > maxColumn )
00583 maxColumn = column;
00584 }
00585
00586
00587 if ( field.length() > 0 ) {
00588 setText( row - mStartLine + 1, column, field );
00589 ++row;
00590 field = "";
00591 }
00592
00593 adjustRows( row - mStartLine );
00594 mTable->setNumCols( maxColumn );
00595
00596 for ( column = 0; column < mTable->numCols(); ++column ) {
00597 QComboTableItem *item = new QComboTableItem( mTable, mTypeMap.keys() );
00598 mTable->setItem( 0, column, item );
00599 if ( column < (int)mTypeStore.count() )
00600 item->setCurrentItem( mTypeStore[ column ] );
00601 else
00602 item->setCurrentItem( typeToPos( Undefined ) );
00603 mTable->adjustColumn( column );
00604 }
00605 }
00606
00607 void CSVImportDialog::clearTable()
00608 {
00609 for ( int row = 0; row < mTable->numRows(); ++row )
00610 for ( int column = 0; column < mTable->numCols(); ++column )
00611 mTable->clearCell( row, column );
00612 }
00613
00614 void CSVImportDialog::fillComboBox()
00615 {
00616 mComboLine->clear();
00617 for ( int row = 1; row < mTable->numRows() + 1; ++row )
00618 mComboLine->insertItem( QString::number( row ), row - 1 );
00619 }
00620
00621 void CSVImportDialog::setText( int row, int col, const QString& text )
00622 {
00623 if ( row < 1 )
00624 return;
00625
00626 if ( mTable->numRows() < row ) {
00627 mTable->setNumRows( row + 5000 );
00628 mAdjustRows = true;
00629 }
00630
00631 if ( mTable->numCols() < col )
00632 mTable->setNumCols( col + 50 );
00633
00634 mTable->setText( row - 1, col - 1, text );
00635 }
00636
00637
00638
00639
00640 void CSVImportDialog::adjustRows( int rows )
00641 {
00642 if ( mAdjustRows ) {
00643 mTable->setNumRows( rows );
00644 mAdjustRows = false;
00645 }
00646 }
00647
00648 void CSVImportDialog::returnPressed()
00649 {
00650 if ( mDelimiterBox->id( mDelimiterBox->selected() ) != 4 )
00651 return;
00652
00653 mDelimiter = mDelimiterEdit->text();
00654 fillTable();
00655 }
00656
00657 void CSVImportDialog::textChanged ( const QString& )
00658 {
00659 mRadioOther->setChecked ( true );
00660 delimiterClicked( 4 );
00661 }
00662
00663 void CSVImportDialog::delimiterClicked( int id )
00664 {
00665 switch ( id ) {
00666 case 0:
00667 mDelimiter = ",";
00668 break;
00669 case 4:
00670 mDelimiter = mDelimiterEdit->text();
00671 break;
00672 case 2:
00673 mDelimiter = "\t";
00674 break;
00675 case 3:
00676 mDelimiter = " ";
00677 break;
00678 case 1:
00679 mDelimiter = ";";
00680 break;
00681 }
00682
00683 fillTable();
00684 }
00685
00686 void CSVImportDialog::textquoteSelected( const QString& mark )
00687 {
00688 if ( mComboQuote->currentItem() == 2 )
00689 mTextQuote = 0;
00690 else
00691 mTextQuote = mark[ 0 ];
00692
00693 fillTable();
00694 }
00695
00696 void CSVImportDialog::lineSelected( const QString& line )
00697 {
00698 mStartLine = line.toInt() - 1;
00699 fillTable();
00700 }
00701
00702 void CSVImportDialog::slotOk()
00703 {
00704 bool assigned = false;
00705
00706 for ( int column = 0; column < mTable->numCols(); ++column ) {
00707 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
00708 column ) );
00709 if ( item && posToType( item->currentItem() ) != Undefined )
00710 assigned = true;
00711 }
00712
00713 if ( assigned )
00714 KDialogBase::slotOk();
00715 else
00716 KMessageBox::sorry( this, i18n( "You have to assign at least one column." ) );
00717 }
00718
00719 void CSVImportDialog::applyTemplate()
00720 {
00721 QMap<uint,int> columnMap;
00722 QMap<QString, QString> fileMap;
00723 QStringList templates;
00724
00725
00726 QStringList list = KGlobal::dirs()->findAllResources( "data" , QString( kapp->name() ) +
00727 "/csv-templates/*.desktop", true, true );
00728
00729 for ( QStringList::iterator it = list.begin(); it != list.end(); ++it )
00730 {
00731 KSimpleConfig config( *it, true );
00732
00733 if ( !config.hasGroup( "csv column map" ) )
00734 continue;
00735
00736 config.setGroup( "Misc" );
00737 templates.append( config.readEntry( "Name" ) );
00738 fileMap.insert( config.readEntry( "Name" ), *it );
00739 }
00740
00741
00742 bool ok = false;
00743 QString tmp;
00744 tmp = KInputDialog::getItem( i18n( "Template Selection" ),
00745 i18n( "Please select a template, that matches the CSV file:" ),
00746 templates, 0, false, &ok, this );
00747
00748 if ( !ok )
00749 return;
00750
00751 KSimpleConfig config( fileMap[ tmp ], true );
00752 config.setGroup( "General" );
00753 mDatePatternEdit->setText( config.readEntry( "DatePattern", "Y-M-D" ) );
00754 uint numColumns = config.readUnsignedNumEntry( "Columns" );
00755 mDelimiterEdit->setText( config.readEntry( "DelimiterOther" ) );
00756 mDelimiterBox->setButton( config.readNumEntry( "DelimiterType" ) );
00757 delimiterClicked( config.readNumEntry( "DelimiterType" ) );
00758 int quoteType = config.readNumEntry( "QuoteType" );
00759 mComboQuote->setCurrentItem( quoteType );
00760 textquoteSelected( mComboQuote->currentText() );
00761
00762
00763 config.setGroup( "csv column map" );
00764 for ( uint i = 0; i < numColumns; ++i ) {
00765 int col = config.readNumEntry( QString::number( i ) );
00766 columnMap.insert( i, col );
00767 }
00768
00769
00770 for ( uint column = 0; column < columnMap.count(); ++column ) {
00771 int type = columnMap[ column ];
00772 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
00773 column ) );
00774 if ( item )
00775 item->setCurrentItem( typeToPos( type ) );
00776 }
00777 }
00778
00779 void CSVImportDialog::saveTemplate()
00780 {
00781 QString fileName = KFileDialog::getSaveFileName(
00782 locateLocal( "data", QString( kapp->name() ) + "/csv-templates/" ),
00783 "*.desktop", this );
00784
00785 if ( fileName.isEmpty() )
00786 return;
00787
00788 if ( !fileName.contains( ".desktop" ) )
00789 fileName += ".desktop";
00790
00791 QString name = KInputDialog::getText( i18n( "Template Name" ), i18n( "Please enter a name for the template:" ) );
00792
00793 if ( name.isEmpty() )
00794 return;
00795
00796 KConfig config( fileName );
00797 config.setGroup( "General" );
00798 config.writeEntry( "DatePattern", mDatePatternEdit->text() );
00799 config.writeEntry( "Columns", mTable->numCols() );
00800 config.writeEntry( "DelimiterType", mDelimiterBox->id( mDelimiterBox->selected() ) );
00801 config.writeEntry( "DelimiterOther", mDelimiterEdit->text() );
00802 config.writeEntry( "QuoteType", mComboQuote->currentItem() );
00803
00804 config.setGroup( "Misc" );
00805 config.writeEntry( "Name", name );
00806
00807 config.setGroup( "csv column map" );
00808
00809 for ( int column = 0; column < mTable->numCols(); ++column ) {
00810 QComboTableItem *item = static_cast<QComboTableItem*>( mTable->item( 0,
00811 column ) );
00812 if ( item )
00813 config.writeEntry( QString::number( column ), posToType(
00814 item->currentItem() ) );
00815 else
00816 config.writeEntry( QString::number( column ), 0 );
00817 }
00818
00819 config.sync();
00820 }
00821
00822 QString CSVImportDialog::getText( int row, int col )
00823 {
00824 return mTable->text( row, col );
00825 }
00826
00827 uint CSVImportDialog::posToType( int pos ) const
00828 {
00829 uint counter = 0;
00830 QMap<QString, uint>::ConstIterator it;
00831 for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it, ++counter )
00832 if ( counter == (uint)pos )
00833 return it.data();
00834
00835 return 0;
00836 }
00837
00838 int CSVImportDialog::typeToPos( uint type ) const
00839 {
00840 uint counter = 0;
00841 QMap<QString, uint>::ConstIterator it;
00842 for ( it = mTypeMap.begin(); it != mTypeMap.end(); ++it, ++counter )
00843 if ( it.data() == type )
00844 return counter;
00845
00846 return -1;
00847 }
00848
00849 void CSVImportDialog::ignoreDuplicatesChanged( int )
00850 {
00851 fillTable();
00852 }
00853
00854 void CSVImportDialog::setFile( const QString &fileName )
00855 {
00856 if ( fileName.isEmpty() )
00857 return;
00858
00859 QFile file( fileName );
00860 if ( !file.open( IO_ReadOnly ) ) {
00861 KMessageBox::sorry( this, i18n( "Cannot open input file!" ) );
00862 file.close();
00863 return;
00864 }
00865
00866 mFileArray = file.readAll();
00867 file.close();
00868
00869 mClearTypeStore = true;
00870 clearTable();
00871 mTable->setNumCols( 0 );
00872 mTable->setNumRows( 0 );
00873 fillTable();
00874 mClearTypeStore = false;
00875
00876 fillComboBox();
00877 }
00878
00879 void CSVImportDialog::urlChanged( const QString &file )
00880 {
00881 bool state = !file.isEmpty();
00882
00883 enableButtonOK( state );
00884 actionButton( User1 )->setEnabled( state );
00885 actionButton( User2 )->setEnabled( state );
00886 }
00887
00888 #include <csvimportdialog.moc>