filters
csvexport.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <csvexport.h>
00022
00023 #include <qfile.h>
00024 #include <qtextcodec.h>
00025
00026 #include <kdebug.h>
00027 #include <kmessagebox.h>
00028 #include <kgenericfactory.h>
00029 #include <KoFilterChain.h>
00030 #include <KoFilterManager.h>
00031
00032 #include <kspread_map.h>
00033 #include <kspread_sheet.h>
00034 #include <kspread_doc.h>
00035 #include <kspread_view.h>
00036 #include <selection.h>
00037
00038 #include <csvexportdialog.h>
00039
00040 using namespace KSpread;
00041
00042 typedef KGenericFactory<CSVExport, KoFilter> CSVExportFactory;
00043 K_EXPORT_COMPONENT_FACTORY( libcsvexport, CSVExportFactory( "kofficefilters" ) )
00044
00045 class Cell
00046 {
00047 public:
00048 int row, col;
00049 QString text;
00050
00051 bool operator < ( const Cell & c ) const
00052 {
00053 return row < c.row || ( row == c.row && col < c.col );
00054 }
00055 bool operator == ( const Cell & c ) const
00056 {
00057 return row == c.row && col == c.col;
00058 }
00059 };
00060
00061
00062 CSVExport::CSVExport( KoFilter *, const char *, const QStringList & )
00063 : KoFilter(), m_eol("\n")
00064 {
00065 }
00066
00067 QString CSVExport::exportCSVCell( Sheet const * const sheet, int col, int row, QChar const & textQuote )
00068 {
00069
00070
00071
00072
00073
00074
00075 KSpread::Cell const * const cell = sheet->cellAt( col, row );
00076 QString text;
00077
00078 if ( !cell->isDefault() && !cell->isEmpty() )
00079 {
00080 if ( cell->isFormula() )
00081 text = cell->strOutText();
00082 else if ( !cell->link().isEmpty() )
00083 text = cell->text();
00084 else if( cell->isTime() )
00085 text = cell->value().asTime().toString("hh:mm:ss");
00086 else if( cell->isDate() )
00087 text = cell->value().asDate().toString("yyyy-MM-dd");
00088 else
00089 text = cell->strOutText();
00090 }
00091
00092 if ( !text.isEmpty() )
00093 {
00094 if ( text.find( textQuote ) != -1 )
00095 {
00096 QString doubleTextQuote(textQuote);
00097 doubleTextQuote.append(textQuote);
00098 text.replace(textQuote, doubleTextQuote);
00099 }
00100
00101 text.prepend(textQuote);
00102 text.append(textQuote);
00103 }
00104
00105 return text;
00106 }
00107
00108
00109
00110 KoFilter::ConversionStatus CSVExport::convert( const QCString & from, const QCString & to )
00111 {
00112 kdDebug(30501) << "CSVExport::convert" << endl;
00113 KoDocument* document = m_chain->inputDocument();
00114
00115 if ( !document )
00116 return KoFilter::StupidError;
00117
00118 if ( !::qt_cast<const KSpread::Doc *>( document ) )
00119 {
00120 kdWarning(30501) << "document isn't a KSpread::Doc but a " << document->className() << endl;
00121 return KoFilter::NotImplemented;
00122 }
00123 if ( ( to != "text/x-csv" && to != "text/plain" ) || from != "application/x-kspread" )
00124 {
00125 kdWarning(30501) << "Invalid mimetypes " << to << " " << from << endl;
00126 return KoFilter::NotImplemented;
00127 }
00128
00129 Doc const * const ksdoc = static_cast<const Doc *>(document);
00130
00131 if ( ksdoc->mimeType() != "application/x-kspread" )
00132 {
00133 kdWarning(30501) << "Invalid document mimetype " << ksdoc->mimeType() << endl;
00134 return KoFilter::NotImplemented;
00135 }
00136
00137 CSVExportDialog *expDialog = 0;
00138 if (!m_chain->manager()->getBatchMode())
00139 {
00140 expDialog= new CSVExportDialog( 0 );
00141
00142 if (!expDialog)
00143 {
00144 kdError(30501) << "Dialog has not been created! Aborting!" << endl;
00145 return KoFilter::StupidError;
00146 }
00147 expDialog->fillSheet( ksdoc->map() );
00148
00149 if ( !expDialog->exec() )
00150 {
00151 delete expDialog;
00152 return KoFilter::UserCancelled;
00153 }
00154 }
00155
00156 QTextCodec* codec = 0;
00157 QChar csvDelimiter;
00158 if (expDialog)
00159 {
00160 codec = expDialog->getCodec();
00161 if ( !codec )
00162 {
00163 delete expDialog;
00164 return KoFilter::StupidError;
00165 }
00166 csvDelimiter = expDialog->getDelimiter();
00167 }
00168 else
00169 {
00170 codec = QTextCodec::codecForName("UTF-8");
00171 csvDelimiter = ',';
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 bool first = true;
00181 QString str;
00182 QChar textQuote;
00183 if (expDialog)
00184 textQuote = expDialog->getTextQuote();
00185 else
00186 textQuote = '"';
00187
00188 if ( expDialog && expDialog->exportSelectionOnly() )
00189 {
00190 kdDebug(30501) << "Export as selection mode" << endl;
00191 View const * const view = static_cast<View*>(ksdoc->views().getFirst());
00192
00193 if ( !view )
00194 {
00195 delete expDialog;
00196 return KoFilter::StupidError;
00197 }
00198
00199 Sheet const * const sheet = view->activeSheet();
00200
00201 QRect selection = view->selectionInfo()->lastRange();
00202
00203
00204
00205 int right = selection.right();
00206 int bottom = selection.bottom();
00207 int CSVMaxRow = 0;
00208 int CSVMaxCol = 0;
00209
00210 for ( int idxRow = 1, row = selection.top(); row <= bottom; ++row, ++idxRow )
00211 {
00212 for ( int idxCol = 1, col = selection.left(); col <= right; ++col, ++idxCol )
00213 {
00214 if( ! sheet->cellAt( col, row )->isEmpty() )
00215 {
00216 if ( idxRow > CSVMaxRow )
00217 CSVMaxRow = idxRow;
00218
00219 if ( idxCol > CSVMaxCol )
00220 CSVMaxCol = idxCol;
00221 }
00222 }
00223 }
00224
00225 for ( int idxRow = 1, row = selection.top();
00226 row <= bottom && idxRow <= CSVMaxRow; ++row, ++idxRow )
00227 {
00228 int idxCol = 1;
00229 for ( int col = selection.left();
00230 col <= right && idxCol <= CSVMaxCol; ++col, ++idxCol )
00231 {
00232 str += exportCSVCell( sheet, col, row, textQuote );
00233
00234 if ( idxCol < CSVMaxCol )
00235 str += csvDelimiter;
00236 }
00237
00238
00239 for ( ; idxCol < CSVMaxCol; ++idxCol )
00240 str += csvDelimiter;
00241
00242 str += m_eol;
00243 }
00244 }
00245 else
00246 {
00247 kdDebug(30501) << "Export as full mode" << endl;
00248 QPtrListIterator<Sheet> it( ksdoc->map()->sheetList() );
00249 for( ; it.current(); ++it )
00250 {
00251 Sheet const * const sheet = it.current();
00252
00253 if (expDialog && !expDialog->exportSheet( sheet->sheetName() ) )
00254 {
00255 continue;
00256 }
00257
00258
00259
00260
00261 int sheetMaxRow = sheet->maxRow();
00262 int sheetMaxCol = sheet->maxColumn();
00263 int CSVMaxRow = 0;
00264 int CSVMaxCol = 0;
00265
00266 for ( int row = 1 ; row <= sheetMaxRow ; ++row)
00267 {
00268 for ( int col = 1 ; col <= sheetMaxCol ; col++ )
00269 {
00270 if( ! sheet->cellAt( col, row )->isEmpty() )
00271 {
00272 if ( row > CSVMaxRow )
00273 CSVMaxRow = row;
00274
00275 if ( col > CSVMaxCol )
00276 CSVMaxCol = col;
00277 }
00278 }
00279 }
00280
00281
00282 if ( CSVMaxRow + CSVMaxCol == 0)
00283 continue;
00284
00285 kdDebug(30501) << "Max row x column: " << CSVMaxRow << " x " << CSVMaxCol << endl;
00286
00287
00288 if ( !first || ( expDialog && expDialog->printAlwaysSheetDelimiter() ) )
00289 {
00290 if ( !first)
00291 str += m_eol;
00292
00293 QString name;
00294 if (expDialog)
00295 name = expDialog->getSheetDelimiter();
00296 else
00297 name = "********<SHEETNAME>********";
00298 const QString tname( i18n("<SHEETNAME>") );
00299 int pos = name.find( tname );
00300 if ( pos != -1 )
00301 {
00302 name.replace( pos, tname.length(), sheet->sheetName() );
00303 }
00304 str += name;
00305 str += m_eol;
00306 str += m_eol;
00307 }
00308
00309 first = false;
00310
00311
00312
00313
00314 int value = 0;
00315 int step = CSVMaxRow > 50 ? CSVMaxRow/50 : 1;
00316
00317
00318 for ( int row = 1, i = 1 ; row <= CSVMaxRow ; ++row, ++i )
00319 {
00320 if ( i > step )
00321 {
00322 value += 2;
00323 emit sigProgress(value);
00324 i = 0;
00325 }
00326
00327 for ( int col = 1 ; col <= CSVMaxCol ; col++ )
00328 {
00329 str += exportCSVCell( sheet, col, row, textQuote );
00330
00331 if ( col < CSVMaxCol )
00332 str += csvDelimiter;
00333 }
00334
00335 str += m_eol;
00336 }
00337 }
00338 }
00339
00340 emit sigProgress(100);
00341
00342 QFile out(m_chain->outputFile());
00343 if ( !out.open( IO_WriteOnly ) )
00344 {
00345 kdError(30501) << "Unable to open output file!" << endl;
00346 out.close();
00347 delete expDialog;
00348 return KoFilter::StupidError;
00349 }
00350
00351 QTextStream outStream( &out );
00352 outStream.setCodec( codec );
00353
00354 outStream << str;
00355
00356 out.close();
00357 delete expDialog;
00358 return KoFilter::OK;
00359 }
00360
00361 #include <csvexport.moc>
|