26 #include <KApplication> 
   29 #include <KFileDialog> 
   30 #include <KInputDialog> 
   33 #include <KMessageBox> 
   34 #include <KProgressDialog> 
   35 #include <KStandardDirs> 
   36 #include <KUrlRequester> 
   38 #include <QtCore/QPointer> 
   39 #include <QtCore/QTextCodec> 
   40 #include <QtCore/QThread> 
   41 #include <QtCore/QUuid> 
   42 #include <QButtonGroup> 
   44 #include <QGridLayout> 
   46 #include <QHBoxLayout> 
   47 #include <QHeaderView> 
   49 #include <QPushButton> 
   50 #include <QRadioButton> 
   51 #include <QStyledItemDelegate> 
   62 class ContactFieldComboBox : 
public KComboBox
 
   66     ContactFieldComboBox( QWidget *parent = 0 )
 
   73       QMapIterator<QString, ContactFields::Field> it( mFieldMap );
 
   74       while ( it.hasNext() ) {
 
   77         addItem( it.key(), QVariant( it.value() ) );
 
   81       for ( 
int i = 0; i < count(); ++i ) {
 
   82         maxLength = qMax( maxLength, itemText( i ).length() );
 
   85       setMinimumContentsLength( maxLength );
 
   86       setSizeAdjustPolicy( AdjustToMinimumContentsLength );
 
   87       setFixedSize( sizeHint() );
 
   92       setCurrentIndex( findData( (uint)field ) );
 
  101     static void fillFieldMap()
 
  103       if ( !mFieldMap.isEmpty() ) {
 
  110       for ( 
int i = 0; i < fields.count(); ++i ) {
 
  115     static QMap<QString, ContactFields::Field> mFieldMap;
 
  118 QMap<QString, ContactFields::Field> ContactFieldComboBox::mFieldMap;
 
  120 class ContactFieldDelegate : 
public QStyledItemDelegate
 
  123     ContactFieldDelegate( 
QObject *parent = 0 )
 
  124       : QStyledItemDelegate( parent )
 
  128     QString displayText( 
const QVariant &value, 
const QLocale & )
 const 
  133     QWidget *createEditor( QWidget *parent, 
const QStyleOptionViewItem &,
 
  134                            const QModelIndex & )
 const 
  136       ContactFieldComboBox *editor = 
new ContactFieldComboBox( parent );
 
  141     void setEditorData( QWidget *editor, 
const QModelIndex &index )
 const 
  143       const unsigned int value = index.model()->data( index, Qt::EditRole ).toUInt();
 
  145       ContactFieldComboBox *fieldCombo = 
static_cast<ContactFieldComboBox*
>( editor );
 
  149     void setModelData( QWidget *editor, QAbstractItemModel *model, 
const QModelIndex &index )
 const 
  151       ContactFieldComboBox *fieldCombo = 
static_cast<ContactFieldComboBox*
>( editor );
 
  153       model->setData( index, fieldCombo->currentField(), Qt::EditRole );
 
  156     void updateEditorGeometry( QWidget *editor, 
const QStyleOptionViewItem &option,
 
  157                                const QModelIndex & )
 const 
  159       editor->setGeometry( option.rect );
 
  162     void paint( QPainter *painter, 
const QStyleOptionViewItem &option,
 
  163                 const QModelIndex &index )
 const 
  165       if ( index.row() == 0 ) {
 
  166         QStyleOptionViewItem headerOption( option );
 
  167         headerOption.font.setBold( 
true );
 
  169         QStyledItemDelegate::paint( painter, headerOption, index );
 
  171         QStyledItemDelegate::paint( painter, option, index );
 
  177   : 
KDialog( parent ), mDevice( 0 )
 
  179   setCaption( i18nc( 
"@title:window", 
"CSV Import Dialog" ) );
 
  180   setButtons( Ok | Cancel | User1 | User2 );
 
  181   setDefaultButton( Ok );
 
  183   showButtonSeparator( 
true );
 
  191   connect( mUrlRequester, SIGNAL(returnPressed(QString)),
 
  192            this, SLOT(setFile(QString)) );
 
  193   connect( mUrlRequester, SIGNAL(urlSelected(KUrl)),
 
  194            this, SLOT(setFile(KUrl)) );
 
  195   connect( mUrlRequester->lineEdit(), SIGNAL(textChanged(QString)),
 
  196            this, SLOT(urlChanged(QString)) );
 
  197   connect( mDelimiterGroup, SIGNAL(buttonClicked(
int)),
 
  198            this, SLOT(delimiterClicked(
int)) );
 
  199   connect( mDelimiterEdit, SIGNAL(returnPressed()),
 
  200            this, SLOT(customDelimiterChanged()) );
 
  201   connect( mDelimiterEdit, SIGNAL(textChanged(QString)),
 
  202            this, SLOT(customDelimiterChanged(QString)) );
 
  203   connect( mComboQuote, SIGNAL(activated(QString)),
 
  204            this, SLOT(textQuoteChanged(QString)) );
 
  205   connect( mCodecCombo, SIGNAL(activated(QString)),
 
  206            this, SLOT(codecChanged()) );
 
  207   connect( mSkipFirstRow, SIGNAL(toggled(
bool)),
 
  208            this, SLOT(skipFirstRowChanged(
bool)) );
 
  210   connect( mModel, SIGNAL(finishedLoading()), 
this, SLOT(modelFinishedLoading()) );
 
  212   delimiterClicked( 0 );
 
  213   textQuoteChanged( QLatin1String(
"\"") );
 
  214   skipFirstRowChanged( 
false );
 
  225   DateParser dateParser( mDatePatternEdit->text() );
 
  227   KProgressDialog progressDialog( const_cast<CSVImportDialog*>( 
this )->mainWidget() );
 
  228   progressDialog.setAutoClose( 
true );
 
  229   progressDialog.progressBar()->setMaximum( mModel->
rowCount() );
 
  230   progressDialog.setLabelText( i18nc( 
"@label", 
"Importing contacts" ) );
 
  231   progressDialog.show();
 
  233   kapp->processEvents();
 
  235   for ( 
int row = 1; row < mModel->
rowCount(); ++row ) {
 
  236     KABC::Addressee contact;
 
  237     bool emptyRow = 
true;
 
  239     for ( 
int column = 0; column < mModel->
columnCount(); ++column ) {
 
  240       QString value = mModel->
data( mModel->index( row, column ), Qt::DisplayRole ).toString();
 
  242       if ( !value.isEmpty() ) {
 
  250           value = dateParser.parse( value ).toString( Qt::ISODate );
 
  253         value.replace( QLatin1String(
"\\n"), QLatin1String(
"\n") );
 
  259     kapp->processEvents();
 
  261     if ( progressDialog.wasCancelled() ) {
 
  262       return KABC::AddresseeList();
 
  265     progressDialog.progressBar()->setValue( progressDialog.progressBar()->value() + 1 );
 
  267     if ( !emptyRow && !contact.isEmpty() ) {
 
  268       contacts.append( contact );
 
  275 void CSVImportDialog::initGUI()
 
  277   QWidget *page = 
new QWidget( 
this );
 
  278   setMainWidget( page );
 
  280   QGridLayout *layout = 
new QGridLayout( page );
 
  281   layout->setSpacing( spacingHint() );
 
  282   layout->setMargin( 0 );
 
  284   QHBoxLayout *hbox = 
new QHBoxLayout();
 
  285   hbox->setSpacing( spacingHint() );
 
  287   QLabel *label = 
new QLabel( i18nc( 
"@label", 
"File to import:" ), page );
 
  288   hbox->addWidget( label );
 
  290   mUrlRequester = 
new KUrlRequester( page );
 
  291   mUrlRequester->setFilter( QLatin1String(
"*.csv") );
 
  292   mUrlRequester->lineEdit()->setTrapReturnKey( 
true );
 
  293   mUrlRequester->setToolTip(
 
  294     i18nc( 
"@info:tooltip", 
"Select a csv file to import" ) );
 
  295   mUrlRequester->setWhatsThis(
 
  296     i18nc( 
"@info:whatsthis",
 
  297            "Click this button to start a file chooser that will allow you to " 
  298            "select a csv file to import." ) );
 
  299   hbox->addWidget( mUrlRequester );
 
  301   layout->addLayout( hbox, 0, 0, 1, 5 );
 
  304   QGroupBox *group = 
new QGroupBox( i18nc( 
"@title:group", 
"Delimiter" ), page );
 
  305   QGridLayout *delimiterLayout = 
new QGridLayout;
 
  306   delimiterLayout->setMargin( marginHint() );
 
  307   delimiterLayout->setSpacing( spacingHint() );
 
  308   group->setLayout( delimiterLayout );
 
  309   delimiterLayout->setAlignment( Qt::AlignTop );
 
  310   layout->addWidget( group, 1, 0, 4, 1 );
 
  312   mDelimiterGroup = 
new QButtonGroup( 
this );
 
  313   mDelimiterGroup->setExclusive( 
true );
 
  315   QRadioButton *button = 
new QRadioButton( i18nc( 
"@option:radio Field separator", 
"Comma" ) );
 
  317     i18nc( 
"@info:tooltip", 
"Set the field separator to a comma" ) );
 
  318   button->setWhatsThis(
 
  319     i18nc( 
"@info:whatsthis",
 
  320            "Select this option if your csv file uses the comma as a field separator." ) );
 
  321   button->setChecked( 
true );
 
  322   mDelimiterGroup->addButton( button, 0 );
 
  323   delimiterLayout->addWidget( button, 0, 0 );
 
  325   button = 
new QRadioButton( i18nc( 
"@option:radio Field separator", 
"Semicolon" ) );
 
  327     i18nc( 
"@info:tooltip", 
"Set the field separator to a semicolon" ) );
 
  328   button->setWhatsThis(
 
  329     i18nc( 
"@info:whatsthis",
 
  330            "Select this option if your csv file uses the semicolon as a field separator." ) );
 
  331   mDelimiterGroup->addButton( button, 1 );
 
  332   delimiterLayout->addWidget( button, 0, 1 );
 
  334   button = 
new QRadioButton( i18nc( 
"@option:radio Field separator", 
"Tabulator" ) );
 
  336     i18nc( 
"@info:tooltip", 
"Set the field separator to a tab character" ) );
 
  337   button->setWhatsThis(
 
  338     i18nc( 
"@info:whatsthis",
 
  339            "Select this option if your csv file uses the tab character as a field separator." ) );
 
  340   mDelimiterGroup->addButton( button, 2 );
 
  341   delimiterLayout->addWidget( button, 1, 0 );
 
  343   button = 
new QRadioButton( i18nc( 
"@option:radio Field separator", 
"Space" ) );
 
  345     i18nc( 
"@info:tooltip", 
"Set the field separator to a space character" ) );
 
  346   button->setWhatsThis(
 
  347     i18nc( 
"@info:whatsthis",
 
  348            "Select this option if your csv file uses the space character as a field separator." ) );
 
  349   mDelimiterGroup->addButton( button, 3 );
 
  350   delimiterLayout->addWidget( button, 1, 1 );
 
  352   button = 
new QRadioButton( i18nc( 
"@option:radio Custum field separator", 
"Other" ) );
 
  354     i18nc( 
"@info:tooltip", 
"Set the field separator to a custom character" ) );
 
  355   button->setWhatsThis(
 
  356     i18nc( 
"@info:whatsthis",
 
  357            "Select this option if to use some other character as the field delimiter " 
  358            "for the data in your csv file." ) );
 
  359   mDelimiterGroup->addButton( button, 4 );
 
  360   delimiterLayout->addWidget( button, 0, 2 );
 
  362   mDelimiterEdit = 
new KLineEdit( group );
 
  363   mDelimiterEdit->setToolTip(
 
  364     i18nc( 
"@info:tooltip",
 
  365           "Set the custom delimiter character" ) );
 
  366   mDelimiterEdit->setWhatsThis(
 
  367     i18nc( 
"@info:whatsthis",
 
  368            "Enter a custom character to use as the delimiter character. " 
  369            "If you enter more than 1 character, only the first will be used and " 
  370            "the remaining characters will be ignored." ) );
 
  371   delimiterLayout->addWidget( mDelimiterEdit, 1, 2 );
 
  374   label = 
new QLabel( i18nc( 
"@label:listbox", 
"Text quote:" ), page );
 
  375   layout->addWidget( label, 1, 2 );
 
  377   mComboQuote = 
new KComboBox( page );
 
  378   mComboQuote->setToolTip(
 
  379     i18nc( 
"@info:tooltip", 
"Select the quote character" ) );
 
  380   mComboQuote->setWhatsThis(
 
  381     i18nc( 
"@info:whatsthis",
 
  382            "Choose the character that your csv data uses to \"quote\" the field delimiter " 
  383            "if that character happens to occur within the data.  For example, if the " 
  384            "comma is the field delimiter, then any comma occurring with the data " 
  385            "will be \"quoted\" by the character specified here." ) );
 
  386   mComboQuote->setEditable( 
false );
 
  387   mComboQuote->addItem( i18nc( 
"@item:inlistbox Qoute character option", 
"\"" ), 0 );
 
  388   mComboQuote->addItem( i18nc( 
"@item:inlistbox Quote character option", 
"'" ), 1 );
 
  389   mComboQuote->addItem( i18nc( 
"@item:inlistbox Quote character option", 
"None" ), 2 );
 
  390   layout->addWidget( mComboQuote, 1, 3 );
 
  393   label = 
new QLabel( i18nc( 
"@label:listbox", 
"Date format:" ), page );
 
  394   layout->addWidget( label, 2, 2 );
 
  396   mDatePatternEdit = 
new KLineEdit( page );
 
  397   mDatePatternEdit->setText( QLatin1String(
"Y-M-D") ); 
 
  398   mDatePatternEdit->setToolTip(
 
  399     i18nc( 
"@info:tooltip",
 
  400            "<para><list><item>y: year with 2 digits</item>" 
  401            "<item>Y: year with 4 digits</item>" 
  402            "<item>m: month with 1 or 2 digits</item>" 
  403            "<item>M: month with 2 digits</item>" 
  404            "<item>d: day with 1 or 2 digits</item>" 
  405            "<item>D: day with 2 digits</item>" 
  406            "<item>H: hours with 2 digits</item>" 
  407            "<item>I: minutes with 2 digits</item>" 
  408            "<item>S: seconds with 2 digits</item>" 
  409            "</list></para>" ) );
 
  410   mDatePatternEdit->setWhatsThis(
 
  411     i18nc( 
"@info:whatsthis",
 
  412            "<para>Specify a format to use for dates included in your csv data. " 
  413            "Use the following sequences to help you define the format:</para>" 
  414            "<para><list><item>y: year with 2 digits</item>" 
  415            "<item>Y: year with 4 digits</item>" 
  416            "<item>m: month with 1 or 2 digits</item>" 
  417            "<item>M: month with 2 digits</item>" 
  418            "<item>d: day with 1 or 2 digits</item>" 
  419            "<item>D: day with 2 digits</item>" 
  420            "<item>H: hours with 2 digits</item>" 
  421            "<item>I: minutes with 2 digits</item>" 
  422            "<item>S: seconds with 2 digits</item>" 
  424            "<para>Example: \"Y-M-D\" corresponds to a date like \"2012-01-04\"</para>" ) );
 
  425   layout->addWidget( mDatePatternEdit, 2, 3 );
 
  428   label = 
new QLabel( i18nc( 
"@label:listbox", 
"Text codec:" ), page );
 
  429   layout->addWidget( label, 3, 2 );
 
  431   mCodecCombo = 
new KComboBox( page );
 
  432   mCodecCombo->setToolTip(
 
  433     i18nc( 
"@info:tooltip", 
"Select the text codec" ) );
 
  434   mCodecCombo->setWhatsThis(
 
  435     i18nc( 
"@info:whatsthis",
 
  436            "Choose the character encoding of the data in your csv file." ) );
 
  437   layout->addWidget( mCodecCombo, 3, 3 );
 
  440   mSkipFirstRow = 
new QCheckBox( i18nc( 
"@option:check", 
"Skip first row of file" ), page );
 
  441   mSkipFirstRow->setToolTip(
 
  442     i18nc( 
"@info:tooltip", 
"Skip first row of csv file when importing" ) );
 
  443   mSkipFirstRow->setWhatsThis(
 
  444     i18nc( 
"@info:whatsthis",
 
  445            "Check this box if you want the import to skip over the first row " 
  446            "of the csv data. In many cases, the first line of a csv file will be a " 
  447            "comment line describing the order of the data fields included in the file." ) );
 
  448   layout->addWidget( mSkipFirstRow, 4, 2, 1, 2 );
 
  451   mTable = 
new QTableView( page );
 
  452   mTable->setModel( mModel );
 
  453   mTable->setItemDelegateForRow( 0, 
new ContactFieldDelegate( 
this ) );
 
  454   mTable->horizontalHeader()->hide();
 
  455   mTable->verticalHeader()->hide();
 
  456   mTable->setEditTriggers( QAbstractItemView::CurrentChanged );
 
  457   mTable->setHorizontalScrollMode( QAbstractItemView::ScrollPerPixel );
 
  458   layout->addWidget( mTable, 5, 0, 1, 5 );
 
  460   setButtonText( User1, i18nc( 
"@action:button", 
"Apply Template..." ) );
 
  461   setButtonText( User2, i18nc( 
"@action:button", 
"Save Template..." ) );
 
  463   enableButton( Ok, 
false );
 
  464   enableButton( User1, 
false );
 
  465   enableButton( User2, 
false );
 
  470 void CSVImportDialog::reloadCodecs()
 
  472   mCodecCombo->clear();
 
  476   Q_FOREACH ( 
const QByteArray &name, QTextCodec::availableCodecs() ) {
 
  477     mCodecs.append( QTextCodec::codecForName( name ) );
 
  480   mCodecCombo->addItem( i18nc( 
"@item:inlistbox Codec setting", 
"Local (%1)",
 
  481                                QLatin1String( QTextCodec::codecForLocale()->name() ) ), 
Local );
 
  482   mCodecCombo->addItem( i18nc( 
"@item:inlistbox Codec setting", 
"Latin1" ), 
Latin1 );
 
  483   mCodecCombo->addItem( i18nc( 
"@item:inlistbox Codec setting", 
"Unicode" ), 
Uni );
 
  484   mCodecCombo->addItem( i18nc( 
"@item:inlistbox Codec setting", 
"Microsoft Unicode" ), 
MSBug );
 
  486   for ( 
int i = 0; i < mCodecs.count(); ++i ) {
 
  487     mCodecCombo->addItem( QLatin1String(mCodecs.at( i )->name()), 
Codec + i );
 
  491 void CSVImportDialog::customDelimiterChanged()
 
  493   if ( mDelimiterGroup->checkedId() == 4 ) {
 
  494     delimiterClicked( 4 );
 
  498 void CSVImportDialog::customDelimiterChanged( 
const QString &, 
bool reload )
 
  500   mDelimiterGroup->button( 4 )->setChecked ( 
true );
 
  501   delimiterClicked( 4, reload ); 
 
  504 void CSVImportDialog::delimiterClicked( 
int id, 
bool reload )
 
  511     mDelimiterEdit->setFocus( Qt::OtherFocusReason );
 
  512     if ( !mDelimiterEdit->text().isEmpty() ) {
 
  527   if ( mDevice && reload ) {
 
  528     mModel->
load( mDevice );
 
  532 void CSVImportDialog::textQuoteChanged( 
const QString &mark, 
bool reload )
 
  534   if ( mComboQuote->currentIndex() == 2 ) {
 
  540   if ( mDevice && reload ) {
 
  541     mModel->
load( mDevice );
 
  545 void CSVImportDialog::skipFirstRowChanged( 
bool checked, 
bool reload )
 
  547   mFieldSelection.clear();
 
  548   for ( 
int column = 0; column < mModel->
columnCount(); ++column ) {
 
  549     mFieldSelection.append(
 
  559   if ( mDevice && reload ) {
 
  560     mModel->
load( mDevice );
 
  566   if ( button == KDialog::Ok ) {
 
  567     bool assigned = 
false;
 
  569     for ( 
int column = 0; column < mModel->
columnCount(); ++column ) {
 
  570       if ( mModel->
data( mModel->index( 0, column ),
 
  580         i18nc( 
"@info:status", 
"You must assign at least one column." ) );
 
  584   } 
else if ( button == User1 ) {
 
  586   } 
else if ( button == User2 ) {
 
  588   } 
else if ( button == KDialog::Cancel ) {
 
  593 void CSVImportDialog::applyTemplate()
 
  596   if ( !dlg->templatesAvailable() ) {
 
  599       i18nc( 
"@label", 
"There are no templates available yet." ),
 
  600       i18nc( 
"@title:window", 
"No templates available" ) );
 
  605   if ( !dlg->exec() || !dlg ) {
 
  610   const QString templateFileName = dlg->selectedTemplate();
 
  613   KConfig config( templateFileName, KConfig::SimpleConfig );
 
  615   const KConfigGroup generalGroup( &config, 
"General" );
 
  616   mDatePatternEdit->setText( generalGroup.readEntry( 
"DatePattern", 
"Y-M-D" ) );
 
  617   mDelimiterEdit->setText( generalGroup.readEntry( 
"DelimiterOther" ) );
 
  619   const int delimiterButton = generalGroup.readEntry( 
"DelimiterType", 0 );
 
  620   const int quoteType = generalGroup.readEntry( 
"QuoteType", 0 );
 
  621   const bool skipFirstRow = generalGroup.readEntry( 
"SkipFirstRow", 
false );
 
  623   mDelimiterGroup->button( delimiterButton )->setChecked( 
true );
 
  624   delimiterClicked( delimiterButton, 
false );
 
  626   mComboQuote->setCurrentIndex( quoteType );
 
  627   textQuoteChanged( mComboQuote->currentText(), false );
 
  631   mSkipFirstRow->blockSignals( 
true );
 
  632   mSkipFirstRow->setChecked( skipFirstRow );
 
  633   mSkipFirstRow->blockSignals( 
false );
 
  635   skipFirstRowChanged( skipFirstRow, 
false );
 
  638     mModel->
load( mDevice );
 
  641   setProperty( 
"TemplateFileName", templateFileName );
 
  642   connect( mModel, SIGNAL(finishedLoading()), 
this, SLOT(finalizeApplyTemplate()) );
 
  645 void CSVImportDialog::finalizeApplyTemplate()
 
  647   const QString templateFileName = property( 
"TemplateFileName" ).toString();
 
  649   KConfig config( templateFileName, KConfig::SimpleConfig );
 
  651   const KConfigGroup generalGroup( &config, 
"General" );
 
  652   const uint columns = generalGroup.readEntry( 
"Columns", 0 );
 
  655   const KConfigGroup columnMapGroup( &config, 
"csv column map" );
 
  657   for ( uint i = 0; i < columns; ++i ) {
 
  658     const uint assignedField = columnMapGroup.readEntry( QString::number( i ), 0 );
 
  659     mModel->
setData( mModel->index( 0, i ), assignedField, Qt::EditRole );
 
  663 void CSVImportDialog::saveTemplate()
 
  666     KInputDialog::getText( i18nc( 
"@title:window", 
"Template Name" ),
 
  667                            i18nc( 
"@info", 
"Please enter a name for the template:" ) );
 
  669   if ( name.isEmpty() ) {
 
  673   const QString fileName =
 
  674     KStandardDirs::locateLocal( 
"data", QLatin1String( 
"kaddressbook/csv-templates/") +
 
  675                                                  QUuid::createUuid().toString() +
 
  676                                                  QLatin1String(
".desktop" ));
 
  678   KConfig config( fileName );
 
  679   KConfigGroup generalGroup( &config, 
"General" );
 
  680   generalGroup.writeEntry( 
"DatePattern", mDatePatternEdit->text() );
 
  681   generalGroup.writeEntry( 
"Columns", mModel->
columnCount() );
 
  682   generalGroup.writeEntry( 
"DelimiterType", mDelimiterGroup->checkedId() );
 
  683   generalGroup.writeEntry( 
"DelimiterOther", mDelimiterEdit->text() );
 
  684   generalGroup.writeEntry( 
"SkipFirstRow", mSkipFirstRow->isChecked() );
 
  685   generalGroup.writeEntry( 
"QuoteType", mComboQuote->currentIndex() );
 
  687   KConfigGroup miscGroup( &config, 
"Misc" );
 
  688   miscGroup.writeEntry( 
"Name", name );
 
  690   KConfigGroup columnMapGroup( &config, 
"csv column map" );
 
  691   for ( 
int column = 0; column < mModel->
columnCount(); ++column ) {
 
  692     columnMapGroup.writeEntry( QString::number( column ),
 
  693                                mModel->
data( mModel->index( 0, column ),
 
  694                                              Qt::DisplayRole ).toUInt() );
 
  700 void CSVImportDialog::setFile( 
const KUrl &fileName )
 
  702    setFile( fileName.toLocalFile() );
 
  705 void CSVImportDialog::setFile( 
const QString &fileName )
 
  707   if ( fileName.isEmpty() ) {
 
  711   QFile *file = 
new QFile( fileName );
 
  712   if ( !file->open( QIODevice::ReadOnly ) ) {
 
  713     KMessageBox::sorry( 
this, i18nc( 
"@info:status", 
"Cannot open input file." ) );
 
  722   mModel->
load( mDevice );
 
  725 void CSVImportDialog::urlChanged( 
const QString &file )
 
  727   bool state = !file.isEmpty();
 
  729   enableButton( Ok, state );
 
  730   enableButton( User1, state );
 
  731   enableButton( User2, state );
 
  734 void CSVImportDialog::codecChanged( 
bool reload )
 
  736   const int code = mCodecCombo->currentIndex();
 
  738   if ( code == 
Local ) {
 
  740   } 
else if ( code >= 
Codec ) {
 
  742   } 
else if ( code == 
Uni ) {
 
  743     mModel->
setTextCodec( QTextCodec::codecForName( 
"UTF-16" ) );
 
  744   } 
else if ( code == 
MSBug ) {
 
  745     mModel->
setTextCodec( QTextCodec::codecForName( 
"UTF-16LE" ) );
 
  746   } 
else if ( code == 
Latin1 ) {
 
  747     mModel->
setTextCodec( QTextCodec::codecForName( 
"ISO 8859-1" ) );
 
  749     mModel->
setTextCodec( QTextCodec::codecForName( 
"UTF-8" ) );
 
  752   if ( mDevice && reload ) {
 
  753     mModel->
load( mDevice );
 
  757 void CSVImportDialog::modelFinishedLoading()
 
  759   ContactFieldComboBox *box = 
new ContactFieldComboBox();
 
  760   int preferredWidth = box->sizeHint().width();
 
  763   for ( 
int i = 0; i < mModel->
columnCount(); ++i ) {
 
  764     mTable->setColumnWidth( i, preferredWidth );
 
  767   for ( 
int column = 0; column < mFieldSelection.count(); ++column ) {
 
  768     mModel->
setData( mModel->index( 0, column ), mFieldSelection.at( column ), Qt::EditRole );
 
  770   mFieldSelection.clear();
 
  773 #include <csvimportdialog.moc> 
void setTextCodec(QTextCodec *textCodec)
Sets the text codec that shall be used for parsing the csv list. 
 
KABC::AddresseeList contacts() const 
 
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const 
Inherited from QAbstractTableModel. 
 
void setStartRow(uint startRow)
Sets the row from where the parsing shall be started. 
 
void setDelimiter(const QChar &delimiter)
Sets the character that is used as delimiter for fields. 
 
virtual void slotButtonClicked(int)
 
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const 
Inherited from QAbstractTableModel. 
 
This class parses the datetime out of a given string with the help of a pattern. 
 
bool load(QIODevice *device)
Loads the data from the device into the model. 
 
CSVImportDialog(QWidget *parent=0)
 
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const 
Inherited from QAbstractTableModel. 
 
void setTextQuote(const QChar &textQuote)
Sets the character that is used for quoting. 
 
virtual bool setData(const QModelIndex &index, const QVariant &data, int role=Qt::EditRole)
Inherited from QAbstractTableModel.