24#include <tqtextcodec.h>
27#include <tdemessagebox.h>
28#include <kgenericfactory.h>
29#include <KoFilterChain.h>
30#include <KoFilterManager.h>
32#include <kspread_map.h>
33#include <kspread_sheet.h>
34#include <kspread_doc.h>
35#include <kspread_view.h>
38#include <csvexportdialog.h>
40using namespace KSpread;
42typedef KGenericFactory<CSVExport, KoFilter> CSVExportFactory;
43K_EXPORT_COMPONENT_FACTORY( libcsvexport, CSVExportFactory(
"kofficefilters" ) )
51 bool operator < (
const Cell & c )
const
53 return row < c.row || ( row == c.row && col < c.col );
55 bool operator == (
const Cell & c )
const
57 return row == c.row && col == c.col;
62CSVExport::CSVExport( KoFilter *,
const char *,
const TQStringList & )
63 : KoFilter(), m_eol(
"\n")
67TQString CSVExport::exportCSVCell( Sheet
const *
const sheet,
int col,
int row, TQChar
const & textQuote, TQChar csvDelimiter )
75 KSpread::Cell
const *
const cell = sheet->cellAt( col, row );
78 if ( !cell->isDefault() && !cell->isEmpty() )
80 if ( cell->isFormula() )
81 text = cell->strOutText();
82 else if ( !cell->link().isEmpty() )
84 else if( cell->isTime() )
85 text = cell->value().asTime().toString(
"hh:mm:ss");
86 else if( cell->isDate() )
87 text = cell->value().asDate().toString(
"yyyy-MM-dd");
89 text = cell->strOutText();
94 if ( !text.isEmpty() )
96 if ( text.find( textQuote ) != -1 )
98 TQString doubleTextQuote(textQuote);
99 doubleTextQuote.append(textQuote);
100 text.replace(textQuote, doubleTextQuote);
103 }
else if ( text[0].isSpace() || text[text.length()-1].isSpace() )
105 else if ( text.find( csvDelimiter ) != -1 )
107 else if ( text.find(
"\n" ) != -1 || text.find(
"\r" ) != -1 )
112 text.prepend(textQuote);
113 text.append(textQuote);
121KoFilter::ConversionStatus CSVExport::convert(
const TQCString & from,
const TQCString & to )
123 kdDebug(30501) <<
"CSVExport::convert" << endl;
124 KoDocument* document = m_chain->inputDocument();
127 return KoFilter::StupidError;
129 if ( !::tqt_cast<const KSpread::Doc *>( document ) )
131 kdWarning(30501) <<
"document isn't a KSpread::Doc but a " << document->className() << endl;
132 return KoFilter::NotImplemented;
134 if ( ( to !=
"text/x-csv" && to !=
"text/plain" ) || from !=
"application/x-kspread" )
136 kdWarning(30501) <<
"Invalid mimetypes " << to <<
" " << from << endl;
137 return KoFilter::NotImplemented;
140 Doc
const *
const ksdoc =
static_cast<const Doc *
>(document);
142 if ( ksdoc->mimeType() !=
"application/x-kspread" )
144 kdWarning(30501) <<
"Invalid document mimetype " << ksdoc->mimeType() << endl;
145 return KoFilter::NotImplemented;
148 CSVExportDialog *expDialog = 0;
149 if (!m_chain->manager()->getBatchMode())
151 expDialog=
new CSVExportDialog( 0 );
155 kdError(30501) <<
"Dialog has not been created! Aborting!" << endl;
156 return KoFilter::StupidError;
158 expDialog->fillSheet( ksdoc->map() );
160 if ( !expDialog->exec() )
163 return KoFilter::UserCancelled;
167 TQTextCodec* codec = 0;
171 codec = expDialog->getCodec();
175 return KoFilter::StupidError;
177 csvDelimiter = expDialog->getDelimiter();
178 m_eol = expDialog->getEndOfLine();
182 codec = TQTextCodec::codecForName(
"UTF-8");
196 textQuote = expDialog->getTextQuote();
200 if ( expDialog && expDialog->exportSelectionOnly() )
202 kdDebug(30501) <<
"Export as selection mode" << endl;
203 View
const *
const view =
static_cast<View*
>(ksdoc->views().getFirst());
208 return KoFilter::StupidError;
211 Sheet
const *
const sheet = view->activeSheet();
213 TQRect selection = view->selectionInfo()->lastRange();
217 int right = selection.right();
218 int bottom = selection.bottom();
222 for (
int idxRow = 1, row = selection.top(); row <= bottom; ++row, ++idxRow )
224 for (
int idxCol = 1, col = selection.left(); col <= right; ++col, ++idxCol )
226 if( ! sheet->cellAt( col, row )->isEmpty() )
228 if ( idxRow > CSVMaxRow )
231 if ( idxCol > CSVMaxCol )
237 for (
int idxRow = 1, row = selection.top();
238 row <= bottom && idxRow <= CSVMaxRow; ++row, ++idxRow )
241 for (
int col = selection.left();
242 col <= right && idxCol <= CSVMaxCol; ++col, ++idxCol )
244 str += exportCSVCell( sheet, col, row, textQuote, csvDelimiter );
246 if ( idxCol < CSVMaxCol )
251 for ( ; idxCol < CSVMaxCol; ++idxCol )
259 kdDebug(30501) <<
"Export as full mode" << endl;
260 TQPtrListIterator<Sheet> it( ksdoc->map()->sheetList() );
261 for( ; it.current(); ++it )
263 Sheet
const *
const sheet = it.current();
265 if (expDialog && !expDialog->exportSheet( sheet->sheetName() ) )
273 int sheetMaxRow = sheet->maxRow();
274 int sheetMaxCol = sheet->maxColumn();
278 for (
int row = 1 ; row <= sheetMaxRow ; ++row)
280 for (
int col = 1 ; col <= sheetMaxCol ; col++ )
282 if( ! sheet->cellAt( col, row )->isEmpty() )
284 if ( row > CSVMaxRow )
287 if ( col > CSVMaxCol )
294 if ( CSVMaxRow + CSVMaxCol == 0)
297 kdDebug(30501) <<
"Max row x column: " << CSVMaxRow <<
" x " << CSVMaxCol << endl;
300 if ( !first || ( expDialog && expDialog->printAlwaysSheetDelimiter() ) )
307 name = expDialog->getSheetDelimiter();
309 name =
"********<SHEETNAME>********";
310 const TQString tname( i18n(
"<SHEETNAME>") );
311 int pos = name.find( tname );
314 name.replace( pos, tname.length(), sheet->sheetName() );
327 int step = CSVMaxRow > 50 ? CSVMaxRow/50 : 1;
330 for (
int row = 1, i = 1 ; row <= CSVMaxRow ; ++row, ++i )
335 emit sigProgress(value);
341 for (
int col = 1 ; col <= CSVMaxCol ; col++ )
343 const TQString txt = exportCSVCell( sheet, col, row, textQuote, csvDelimiter );
346 if (!txt.isEmpty()) {
347 str += collect + txt;
348 collect = TQString();
351 collect += csvDelimiter;
361 emit sigProgress(100);
363 TQFile out(m_chain->outputFile());
364 if ( !out.open( IO_WriteOnly ) )
366 kdError(30501) <<
"Unable to open output file!" << endl;
369 return KoFilter::StupidError;
372 TQTextStream outStream( &out );
373 outStream.setCodec( codec );
382#include <csvexport.moc>