27 #include <tqbuttongroup.h>
31 #include <tqlineedit.h>
32 #include <tqlistview.h>
33 #include <tqradiobutton.h>
36 #include <tqtextstream.h>
39 #include <tdeapplication.h>
41 #include <kcombobox.h>
42 #include <kinputdialog.h>
43 #include <klineedit.h>
44 #include <tdelocale.h>
45 #include <kprogress.h>
46 #include <ksimpleconfig.h>
47 #include <kstandarddirs.h>
48 #include <kurlrequester.h>
49 #include <tdefiledialog.h>
51 #include "kimportdialog.h"
52 #include "kimportdialog.moc"
54 KImportColumn::KImportColumn(KImportDialog *dlg,
const TQString &header,
int count)
60 mFormats.append(FormatPlain);
61 mFormats.append(FormatUnquoted);
64 mDefaultFormat = FormatUnquoted;
66 mDialog->addColumn(
this);
69 TQValueList<int> KImportColumn::formats()
74 TQString KImportColumn::formatName(
int format)
80 return i18n(
"Unquoted");
82 return i18n(
"Bracketed");
84 return i18n(
"Undefined");
88 int KImportColumn::defaultFormat()
90 return mDefaultFormat;
93 TQString KImportColumn::preview(
const TQString &value,
int format)
95 if (format == FormatBracketed) {
96 return "(" + value +
")";
97 }
else if (format == FormatUnquoted) {
98 if (value.left(1) ==
"\"" && value.right(1) ==
"\"") {
99 return value.mid(1,value.length()-2);
108 void KImportColumn::addColId(
int id)
113 void KImportColumn::removeColId(
int id)
118 TQValueList<int> KImportColumn::colIdList()
123 TQString KImportColumn::convert()
125 TQValueList<int>::ConstIterator it = mColIds.begin();
126 if (it == mColIds.end())
return "";
127 else return mDialog->cell(*it);
131 class ColumnItem :
public TQListViewItem {
133 ColumnItem(KImportColumn *col,TQListView *parent) : TQListViewItem(parent), mColumn(col)
135 setText(0,mColumn->header());
138 KImportColumn *column() {
return mColumn; }
141 KImportColumn *mColumn;
151 KImportDialog::KImportDialog(TQWidget* parent)
152 : KDialogBase(parent,
"importdialog",true,i18n(
"Import Text File"),Ok|Cancel),
156 mData.setAutoDelete(
true );
158 TQVBox *topBox =
new TQVBox(
this);
159 setMainWidget(topBox);
160 topBox->setSpacing(spacingHint());
162 TQHBox *fileBox =
new TQHBox(topBox);
163 fileBox->setSpacing(spacingHint());
164 new TQLabel(i18n(
"File to import:"),fileBox);
165 KURLRequester *urlRequester =
new KURLRequester(fileBox);
166 urlRequester->setFilter(
"*.csv" );
167 connect(urlRequester,TQ_SIGNAL(returnPressed(
const TQString &)),
168 TQ_SLOT(setFile(
const TQString &)));
169 connect(urlRequester,TQ_SIGNAL(urlSelected(
const TQString &)),
170 TQ_SLOT(setFile(
const TQString &)));
171 connect(urlRequester->lineEdit(),TQ_SIGNAL(textChanged (
const TQString & )),
172 TQ_SLOT(slotUrlChanged(
const TQString & )));
173 mTable =
new TQTable(5,5,topBox);
174 mTable->setMinimumHeight( 150 );
175 connect(mTable,TQ_SIGNAL(selectionChanged()),TQ_SLOT(tableSelected()));
177 TQHBox *separatorBox =
new TQHBox( topBox );
178 separatorBox->setSpacing( spacingHint() );
180 new TQLabel( i18n(
"Separator:" ), separatorBox );
182 mSeparatorCombo =
new KComboBox( separatorBox );
183 mSeparatorCombo->insertItem(
"," );
184 mSeparatorCombo->insertItem( i18n(
"Tab" ) );
185 mSeparatorCombo->insertItem( i18n(
"Space" ) );
186 mSeparatorCombo->insertItem(
"=" );
187 mSeparatorCombo->insertItem(
";" );
188 connect(mSeparatorCombo, TQ_SIGNAL( activated(
int) ),
189 this, TQ_SLOT( separatorClicked(
int) ) );
190 mSeparatorCombo->setCurrentItem( 0 );
192 TQHBox *rowsBox =
new TQHBox( topBox );
193 rowsBox->setSpacing( spacingHint() );
195 new TQLabel( i18n(
"Import starts at row:" ), rowsBox );
196 mStartRow =
new TQSpinBox( rowsBox );
197 mStartRow->setMinValue( 1 );
203 TQVBox *assignBox =
new TQVBox(topBox);
204 assignBox->setSpacing(spacingHint());
206 TQHBox *listsBox =
new TQHBox(assignBox);
207 listsBox->setSpacing(spacingHint());
209 mHeaderList =
new TQListView(listsBox);
210 mHeaderList->addColumn(i18n(
"Header"));
211 connect(mHeaderList, TQ_SIGNAL(selectionChanged(TQListViewItem*)),
212 this, TQ_SLOT(headerSelected(TQListViewItem*)));
213 connect(mHeaderList,TQ_SIGNAL(doubleClicked(TQListViewItem*)),
214 TQ_SLOT(assignColumn(TQListViewItem *)));
216 mFormatCombo =
new KComboBox( listsBox );
217 mFormatCombo->setDuplicatesEnabled(
false );
219 TQPushButton *assignButton =
new TQPushButton(i18n(
"Assign to Selected Column"),
221 connect(assignButton,TQ_SIGNAL(clicked()),TQ_SLOT(assignColumn()));
223 TQPushButton *removeButton =
new TQPushButton(i18n(
"Remove Assignment From Selected Column"),
225 connect(removeButton,TQ_SIGNAL(clicked()),TQ_SLOT(removeColumn()));
227 TQPushButton *assignTemplateButton =
new TQPushButton(i18n(
"Assign with Template..."),
229 connect(assignTemplateButton,TQ_SIGNAL(clicked()),TQ_SLOT(assignTemplate()));
231 TQPushButton *saveTemplateButton =
new TQPushButton(i18n(
"Save Current Template"),
233 connect(saveTemplateButton,TQ_SIGNAL(clicked()),TQ_SLOT(saveTemplate()));
237 connect(
this,TQ_SIGNAL(okClicked()),TQ_SLOT(applyConverter()));
238 connect(
this,TQ_SIGNAL(applyClicked()),TQ_SLOT(applyConverter()));
239 enableButtonOK(!urlRequester->lineEdit()->text().isEmpty());
242 void KImportDialog::slotUrlChanged(
const TQString & text)
244 enableButtonOK(!text.isEmpty());
247 bool KImportDialog::setFile(
const TQString& file)
249 enableButtonOK(!file.isEmpty());
250 kdDebug(5300) <<
"KImportDialog::setFile(): " << file << endl;
254 if (f.open(IO_ReadOnly)) {
267 kdDebug(5300) <<
" Open failed" << endl;
272 void KImportDialog::registerColumns()
274 TQPtrListIterator<KImportColumn> colIt(mColumns);
275 for (; colIt.current(); ++colIt) {
276 new ColumnItem(*colIt,mHeaderList);
278 mHeaderList->setSelected(mHeaderList->firstChild(),
true);
281 void KImportDialog::fillTable()
287 for (row = 0; row < mTable->numRows(); ++row)
288 for (column = 0; column < mTable->numCols(); ++column)
289 mTable->clearCell(row, column);
291 for ( row = 0; row < int(mData.count()); ++row ) {
292 TQValueVector<TQString> *rowVector = mData[ row ];
293 for( column = 0; column < int(rowVector->size()); ++column ) {
294 setCellText( row, column, rowVector->at( column ) );
299 void KImportDialog::readFile(
int rows )
301 kdDebug(5300) <<
"KImportDialog::readFile(): " << rows << endl;
306 enum { S_START, S_QUOTED_FIELD, S_MAYBE_END_OF_QUOTED_FIELD, S_END_OF_QUOTED_FIELD,
307 S_MAYBE_NORMAL_FIELD, S_NORMAL_FIELD } state = S_START;
309 TQChar m_textquote =
'"';
316 TQTextStream inputStream(mFile, IO_ReadOnly);
317 inputStream.setEncoding(TQTextStream::Locale);
319 KProgressDialog pDialog(
this, 0, i18n(
"Loading Progress"),
320 i18n(
"Please wait while the file is loaded."),
true);
321 pDialog.setAllowCancel(
true);
322 pDialog.showCancelButton(
true);
323 pDialog.setAutoClose(
true);
325 KProgress *progress = pDialog.progressBar();
326 progress->setTotalSteps( mFile.contains(mSeparator,
false) );
327 progress->setValue(0);
328 int progressValue = 0;
330 if (progress->totalSteps() > 0)
333 while (!inputStream.atEnd() && !pDialog.wasCancelled()) {
339 progress->setValue(progressValue++);
340 if (progressValue % 15 == 0)
341 kapp->processEvents();
344 if (x ==
'\r') inputStream >> x;
348 if (x == m_textquote) {
350 state = S_QUOTED_FIELD;
351 }
else if (x == mSeparator) {
353 }
else if (x ==
'\n') {
358 state = S_MAYBE_NORMAL_FIELD;
361 case S_QUOTED_FIELD :
362 if (x == m_textquote) {
364 state = S_MAYBE_END_OF_QUOTED_FIELD;
365 }
else if (x ==
'\n') {
366 setData(row - m_startline, column, field);
379 case S_MAYBE_END_OF_QUOTED_FIELD :
380 if (x == m_textquote) {
382 state = S_QUOTED_FIELD;
383 }
else if (x == mSeparator || x ==
'\n') {
384 setData(row - m_startline, column, field);
394 state = S_END_OF_QUOTED_FIELD;
397 case S_END_OF_QUOTED_FIELD :
398 if (x == mSeparator || x ==
'\n') {
399 setData(row - m_startline, column, field);
409 state = S_END_OF_QUOTED_FIELD;
412 case S_MAYBE_NORMAL_FIELD :
413 if (x == m_textquote) {
415 state = S_QUOTED_FIELD;
417 case S_NORMAL_FIELD :
418 if (x == mSeparator || x ==
'\n') {
419 setData(row - m_startline, column, field);
433 if ( rows > 0 && row > rows )
break;
439 void KImportDialog::setCellText(
int row,
int col,
const TQString& text)
443 if ((mTable->numRows() - 1) < row) mTable->setNumRows(row + 1);
444 if ((mTable->numCols() - 1) < col) mTable->setNumCols(col + 1);
446 KImportColumn *c = mColumnDict.find(col);
447 TQString formattedText;
448 if (c) formattedText = c->preview(text,findFormat(col));
449 else formattedText = text;
450 mTable->setText(row, col, formattedText);
453 void KImportDialog::formatSelected(TQListViewItem*)
458 void KImportDialog::headerSelected(TQListViewItem* item)
460 KImportColumn *col = ((ColumnItem *)item)->column();
464 mFormatCombo->clear();
466 TQValueList<int> formats = col->formats();
468 TQValueList<int>::ConstIterator it = formats.begin();
469 TQValueList<int>::ConstIterator end = formats.end();
471 mFormatCombo->insertItem( col->formatName(*it), *it - 1 );
475 TQTableSelection selection = mTable->selection(mTable->currentSelection());
477 updateFormatSelection(selection.leftCol());
480 void KImportDialog::updateFormatSelection(
int column)
482 int format = findFormat(column);
484 if ( format == KImportColumn::FormatUndefined )
485 mFormatCombo->setCurrentItem( 0 );
487 mFormatCombo->setCurrentItem( format - 1 );
490 void KImportDialog::tableSelected()
492 TQTableSelection selection = mTable->selection(mTable->currentSelection());
494 TQListViewItem *item = mHeaderList->firstChild();
495 KImportColumn *col = mColumnDict.find(selection.leftCol());
498 if (item->text(0) == col->header()) {
501 item = item->nextSibling();
505 mHeaderList->setSelected(item,
true);
508 updateFormatSelection(selection.leftCol());
511 void KImportDialog::separatorClicked(
int id)
537 void KImportDialog::assignColumn(TQListViewItem *item)
544 ColumnItem *colItem = (ColumnItem *)item;
546 TQTableSelection selection = mTable->selection(mTable->currentSelection());
550 for(
int i=selection.leftCol();i<=selection.rightCol();++i) {
552 mTable->horizontalHeader()->setLabel(i,colItem->text(0));
553 mColumnDict.replace(i,colItem->column());
554 int format = mFormatCombo->currentItem() + 1;
555 mFormats.replace(i,format);
556 colItem->column()->addColId(i);
563 void KImportDialog::assignColumn()
565 assignColumn(mHeaderList->currentItem());
568 void KImportDialog::assignTemplate()
570 TQMap<uint,int> columnMap;
571 TQMap<TQString, TQString> fileMap;
572 TQStringList templates;
575 TQStringList list = TDEGlobal::dirs()->findAllResources(
"data" , TQString( kapp->name() ) +
576 "/csv-templates/*.desktop",
true,
true );
578 for ( TQStringList::iterator it = list.begin(); it != list.end(); ++it )
580 KSimpleConfig config( *it,
true );
582 if ( !config.hasGroup(
"csv column map" ) )
585 config.setGroup(
"Misc" );
586 templates.append( config.readEntry(
"Name" ) );
587 fileMap.insert( config.readEntry(
"Name" ), *it );
593 tmp = KInputDialog::getItem( i18n(
"Template Selection" ),
594 i18n(
"Please select a template, that matches the CSV file:" ),
595 templates, 0,
false, &ok,
this );
600 KSimpleConfig config( fileMap[ tmp ],
true );
601 config.setGroup(
"General" );
602 uint numColumns = config.readUnsignedNumEntry(
"Columns" );
603 int format = config.readNumEntry(
"Format" );
606 config.setGroup(
"csv column map" );
607 for ( uint i = 0; i < numColumns; ++i ) {
608 int col = config.readNumEntry( TQString::number( i ) );
609 columnMap.insert( i, col );
613 for ( uint i = 0; i < columnMap.count(); ++i ) {
614 int tableColumn = columnMap[i];
615 if ( tableColumn == -1 )
617 KImportColumn *col = mColumns.at(i);
618 mTable->horizontalHeader()->setLabel( tableColumn, col->header() );
619 mColumnDict.replace( tableColumn, col );
620 mFormats.replace( tableColumn, format );
621 col->addColId( tableColumn );
627 void KImportDialog::removeColumn()
629 TQTableSelection selection = mTable->selection(mTable->currentSelection());
633 for(
int i=selection.leftCol();i<=selection.rightCol();++i) {
635 mTable->horizontalHeader()->setLabel(i,TQString::number(i+1));
636 KImportColumn *col = mColumnDict.find(i);
638 mColumnDict.remove(i);
648 void KImportDialog::applyConverter()
650 kdDebug(5300) <<
"KImportDialog::applyConverter" << endl;
652 KProgressDialog pDialog(
this, 0, i18n(
"Importing Progress"),
653 i18n(
"Please wait while the data is imported."),
true);
654 pDialog.setAllowCancel(
true);
655 pDialog.showCancelButton(
true);
656 pDialog.setAutoClose(
true);
658 KProgress *progress = pDialog.progressBar();
659 progress->setTotalSteps( mTable->numRows()-1 );
660 progress->setValue(0);
665 for( uint i = mStartRow->value() - 1; i < mData.count() && !pDialog.wasCancelled(); ++i ) {
667 progress->setValue(i);
669 kapp->processEvents();
675 int KImportDialog::findFormat(
int column)
677 TQMap<int,int>::ConstIterator formatIt = mFormats.find(column);
679 if (formatIt == mFormats.end()) format = KImportColumn::FormatUndefined;
680 else format = *formatIt;
687 TQString KImportDialog::cell(uint col)
689 if ( col >= mData[ mCurrentRow ]->size() )
return "";
690 else return data( mCurrentRow, col );
693 void KImportDialog::addColumn(KImportColumn *col)
695 mColumns.append(col);
698 void KImportDialog::setData( uint row, uint col,
const TQString &value )
700 TQString val = value;
701 val.replace(
"\\n",
"\n" );
703 if ( row >= mData.count() ) {
704 mData.resize( row + 1 );
707 TQValueVector<TQString> *rowVector = mData[ row ];
709 rowVector =
new TQValueVector<TQString>;
710 mData.insert( row, rowVector );
712 if ( col >= rowVector->size() ) {
713 rowVector->resize( col + 1 );
716 KImportColumn *c = mColumnDict.find( col );
718 rowVector->at( col ) = c->preview( val, findFormat(col) );
720 rowVector->at( col ) = val;
723 TQString KImportDialog::data( uint row, uint col )
725 return mData[ row ]->at( col );
728 void KImportDialog::saveTemplate()
730 TQString fileName = KFileDialog::getSaveFileName(
731 locateLocal(
"data", TQString( kapp->name() ) +
"/csv-templates/" ),
734 if ( fileName.isEmpty() )
737 if ( !fileName.contains(
".desktop" ) )
738 fileName +=
".desktop";
740 TQString name = KInputDialog::getText( i18n(
"Template Name" ), i18n(
"Please enter a name for the template:" ) );
742 if ( name.isEmpty() )
745 TDEConfig config( fileName );
746 config.setGroup(
"General" );
747 config.writeEntry(
"Columns", mColumns.count() );
748 config.writeEntry(
"Format", mFormatCombo->currentItem() + 1 );
750 config.setGroup(
"Misc" );
751 config.writeEntry(
"Name", name );
753 config.setGroup(
"csv column map" );
755 KImportColumn *column;
757 for ( column = mColumns.first(); column; column = mColumns.next() ) {
758 TQValueList<int> list = column->colIdList();
759 if ( list.count() > 0 )
760 config.writeEntry( TQString::number( counter ), list[ 0 ] );
762 config.writeEntry( TQString::number( counter ), -1 );