22#include <htmlexport.h>
23#include <exportdialog.h>
26#include <tqtextcodec.h>
29#include <kgenericfactory.h>
30#include <KoFilterChain.h>
31#include <KoDocumentInfo.h>
32#include <kofficeversion.h>
34#include <kspread_map.h>
35#include <kspread_sheet.h>
36#include <kspread_doc.h>
37#include <kspread_util.h>
39using namespace KSpread;
41typedef KGenericFactory<HTMLExport, KoFilter> HTMLExportFactory;
42K_EXPORT_COMPONENT_FACTORY( libkspreadhtmlexport, HTMLExportFactory(
"kofficefilters" ) )
44const TQString html_table_tag = "table";
45const TQString html_table_options = TQString(" border=\"%1\" cellspacing=\"%2\"");
46const TQString html_row_tag = "tr";
47const TQString html_row_options = "";
48const TQString html_cell_tag = "td";
49const TQString html_cell_options = "";
50const TQString html_bold = "b";
51const TQString html_italic = "i";
52const TQString html_underline = "u";
53const TQString html_right= "right";
54const TQString html_left= "left";
55const TQString html_center= "center";
56const TQString html_top="top";
57const TQString html_bottom="bottom";
58const TQString html_middle="middle";
59const TQString html_h1="h1";
61HTMLExport::HTMLExport(KoFilter *, const
char *, const TQStringList&) :
62 KoFilter(), m_dialog( new ExportDialog() )
66HTMLExport::~HTMLExport()
72const TQString strAmp (
"&");
73const TQString nbsp (
" ");
74const TQString strLt (
"<");
75const TQString strGt (
">");
79KoFilter::ConversionStatus HTMLExport::convert(
const TQCString& from,
const TQCString& to )
81 if(to!=
"text/html" || from!=
"application/x-kspread")
83 kdWarning(30501) <<
"Invalid mimetypes " << to <<
" " << from << endl;
84 return KoFilter::NotImplemented;
87 KoDocument* document = m_chain->inputDocument();
90 return KoFilter::StupidError;
92 if( !::tqt_cast<const KSpread::Doc *>( document ) )
94 kdWarning(30501) <<
"document isn't a KSpread::Doc but a " << document->className() << endl;
95 return KoFilter::NotImplemented;
98 const Doc * ksdoc=
static_cast<const Doc *
>(document);
100 if( ksdoc->mimeType() !=
"application/x-kspread" )
102 kdWarning(30501) <<
"Invalid document mimetype " << ksdoc->mimeType() << endl;
103 return KoFilter::NotImplemented;
106 Sheet *sheet = ksdoc->map()->firstSheet();
107 TQString filenameBase = m_chain->outputFile();
108 filenameBase = filenameBase.left( filenameBase.findRev(
'.' ) );
115 detectFilledCells( sheet, rows, columns );
116 m_rowmap[ sheet->sheetName() ] = rows;
117 m_columnmap[ sheet->sheetName() ] = columns;
119 if( rows > 0 && columns > 0 )
121 sheets.append( sheet->sheetName() );
123 sheet = ksdoc->map()->nextSheet();
125 m_dialog->setSheets( sheets );
127 if( m_dialog->exec() == TQDialog::Rejected )
128 return KoFilter::UserCancelled;
130 sheets = m_dialog->sheets();
132 for( uint i = 0; i < sheets.count() ; ++i )
134 sheet = ksdoc->map()->findSheet( sheets[i] );
136 TQString file = fileName( filenameBase, sheet->sheetName(), sheets.count() > 1 );
138 if( m_dialog->separateFiles() || sheets[i] == sheets.first() )
141 openPage( sheet, document, str );
142 writeTOC( sheets, filenameBase, str );
145 convertSheet( sheet, str, m_rowmap[ sheet->sheetName() ], m_columnmap[ sheet->sheetName() ] );
147 if( m_dialog->separateFiles() || sheets[i] == sheets.last() )
151 if(!out.open(IO_WriteOnly)) {
152 kdError(30501) <<
"Unable to open output file!" << endl;
154 return KoFilter::FileNotFound;
156 TQTextStream streamOut(&out);
157 streamOut.setCodec( m_dialog->encoding() );
158 streamOut << str << endl;
162 if( !m_dialog->separateFiles() )
164 createSheetSeparator( str );
169 emit sigProgress(100);
173void HTMLExport::openPage( Sheet *sheet, KoDocument *document, TQString &str )
176 KoDocumentInfo *info = document->documentInfo();
177 KoDocumentInfoAbout *aboutPage =
static_cast<KoDocumentInfoAbout *
>(info->page(
"about" ));
178 if ( aboutPage && !aboutPage->title().isEmpty() )
179 title = aboutPage->title() +
" - ";
181 title += sheet->sheetName();
184 str =
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" ";
185 str +=
" \"http://www.w3.org/TR/html4/loose.dtd\"> \n";
188 str +=
"<meta http-equiv=\"Content-Type\" ";
189 str += TQString(
"content=\"text/html; charset=%1\">\n").arg( m_dialog->encoding()->mimeName() );
190 str +=
"<meta name=\"Generator\" ";
191 str +=
"content=\"KSpread HTML Export Filter Version = ";
192 str += KOFFICE_VERSION_STRING;
196 if( !m_dialog->customStyleURL().isEmpty() )
198 str +=
"<link ref=\"stylesheet\" type=\"text/css\" href=\"";
199 str += m_dialog->customStyleURL();
200 str +=
"\" title=\"Style\" >\n";
203 str +=
"<title>" + title +
"</title>\n";
205 str += TQString(
"<body bgcolor=\"#FFFFFF\" dir=\"%1\">\n").arg(
206 sheet->isRightToLeft()?
"rtl":
"ltr");
208 str +=
"<a name=\"__top\">\n";
211void HTMLExport::closePage( TQString &str )
213 str +=
"<p align=\"" + html_center +
"\"><a href=\"#__top\">" + i18n(
"Top") +
"</a></p>\n";
215 str +=
"</html>\n\n";
218void HTMLExport::convertSheet( Sheet *sheet, TQString &str,
int iMaxUsedRow,
int iMaxUsedColumn )
224 int iMaxRow = sheet->maxRow();
226 if( !m_dialog->separateFiles() )
227 str +=
"<a name=\"" + sheet->sheetName().lower().stripWhiteSpace() +
"\">\n";
229 str += (
"<h1>" + sheet->sheetName() +
"</h1><br>\n");
234 int step=iMaxRow > 50 ? iMaxRow/50 : 1;
237 str +=
"<" + html_table_tag + html_table_options.arg( m_dialog->useBorders() ?
"1" :
"0" ).arg( m_dialog->pixelsBetweenCells() ) +
238 TQString(
"dir=\"%1\">\n").arg(sheet->isRightToLeft()?
"rtl":
"ltr");
240 unsigned int nonempty_cells_prev=0;
242 for (
int currentrow = 1 ; currentrow <= iMaxUsedRow ; ++currentrow, ++i )
246 emit sigProgress(value);
252 unsigned int nonempty_cells=0;
253 unsigned int colspan_cells=0;
255 for (
int currentcolumn = 1 ; currentcolumn <= iMaxUsedColumn ; currentcolumn++ )
257 Cell * cell = sheet->cellAt( currentcolumn, currentrow,
false );
258 colspan_cells=cell->extraXCells();
259 if (cell->needsPrinting())
262 TQColor bgcolor = cell->bgColor(currentcolumn,currentrow);
267 if ( !cell->link().isEmpty() )
269 if ( localReferenceAnchor(cell->link()) )
275 text =
" <A href=\"" + cell->link() +
"\">" + cell->text() +
"</A>";
280 text=cell->strOutText();
282 switch( cell->content() ) {
287 case Cell::VisualFormula:
292 text = cell->valueString();
295 text = cell->prefix(currentrow, currentcolumn) +
" " + text +
" "
296 + cell->postfix(currentrow, currentcolumn);
298 line +=
" <" + html_cell_tag + html_cell_options;
299 if (text.isRightToLeft() != sheet->isRightToLeft())
300 line += TQString(
" dir=\"%1\" ").arg(text.isRightToLeft()?
"rtl":
"ltr");
301 if (bgcolor.isValid() && bgcolor.name()!=
"#ffffff")
302 line +=
" bgcolor=\"" + bgcolor.name() +
"\"";
304 switch((Format::Align)cell->defineAlignX())
307 line+=
" align=\"" + html_left +
"\"";
310 line+=
" align=\"" + html_right +
"\"";
313 line+=
" align=\"" + html_center +
"\"";
315 case Format::Undefined:
318 switch((Format::AlignY)cell-> format()->alignY(currentrow, currentcolumn))
321 line+=
" valign=\"" + html_top +
"\"";
324 line+=
" valign=\"" + html_middle +
"\"";
327 line+=
" valign=\"" + html_bottom +
"\"";
329 case Format::UndefinedY:
332 line+=
" width=\""+TQString::number(cell->width())+
"\"";
333 line+=
" height=\""+TQString::number(cell->height())+
"\"";
335 if (cell->extraXCells()>0)
338 int extra_cells=cell->extraXCells();
339 line +=
" colspan=\"" + tmp.setNum(extra_cells+1) +
"\"";
340 currentcolumn += extra_cells;
342 text = text.stripWhiteSpace();
343 if( text.at(0) ==
'!' ) {
345 text = text.right(text.length()-1);
346 }
else if ( !link ) {
348 text.replace (
'&' , strAmp)
349 .replace (
'<' , strLt)
350 .replace (
'>' , strGt)
351 .replace (
' ' , nbsp);
355 if (cell->format()->textFontBold(currentcolumn,currentrow))
357 text.insert(0,
"<" + html_bold +
">");
358 text.append(
"</" + html_bold +
">");
360 if (cell->format()->textFontItalic(currentcolumn,currentrow))
362 text.insert(0,
"<" + html_italic +
">");
363 text.append(
"</" + html_italic +
">");
365 if (cell->format()->textFontUnderline(currentcolumn,currentrow))
367 text.insert(0,
"<" + html_underline +
">");
368 text.append(
"</" + html_underline +
">");
370 TQColor textColor = cell->format()->textColor(currentcolumn,currentrow);
371 if (textColor.isValid() && textColor.name()!=
"#000000")
373 text.insert(0,
"<font color=\"" + textColor.name() +
"\">");
374 text.append(
"</font>");
377 line +=
"\n </" + html_cell_tag +
">\n";
380 if (nonempty_cells == 0 && nonempty_cells_prev == 0) {
381 nonempty_cells_prev = nonempty_cells;
385 nonempty_cells_prev = nonempty_cells;
387 str +=
"<" + html_row_tag + html_row_options +
">\n";
389 str +=
"</" + html_row_tag +
">";
390 emptyLines = TQString();
396 str +=
"\n</" + html_table_tag +
">\n<br>\n";
399void HTMLExport::createSheetSeparator( TQString &str )
401 str += (
"<p align=\"" + html_center +
"\"><a href=\"#__top\">" + i18n(
"Top") +
"</a></p>\n" );
402 str +=
"<hr width=\"80%\">\n";
405void HTMLExport::writeTOC(
const TQStringList &sheets,
const TQString &base, TQString &str )
408 if( sheets.count() == 1 )
411 str +=
"<p align=\"" + html_center +
"\">\n";
413 for( uint i = 0 ; i < sheets.count() ; ++i )
417 if( m_dialog->separateFiles() )
419 str += fileName( base, sheets[i], sheets.count() > 1 );
423 str +=
"#" + sheets[i].lower().stripWhiteSpace();
426 str +=
"\">" + sheets[i] +
"</a>\n";
427 if( i != sheets.count() -1 )
431 str +=
"</p><hr width=\"80%\">\n";
434TQString HTMLExport::fileName(
const TQString &base,
const TQString &sheetName,
bool multipleFiles )
436 TQString fileName = base;
437 if( m_dialog->separateFiles() && multipleFiles )
439 fileName +=
"-" + sheetName;
446void HTMLExport::detectFilledCells( Sheet *sheet,
int &rows,
int &columns )
448 int iMaxColumn = sheet->maxColumn();
449 int iMaxRow = sheet->maxRow();
453 for (
int currentrow = 1 ; currentrow <= iMaxRow ; ++currentrow)
457 for (
int currentcolumn = 1 ; currentcolumn <= iMaxColumn ; currentcolumn++ )
459 cell = sheet->cellAt( currentcolumn, currentrow,
false );
461 if ( !cell->isDefault() && !cell->isEmpty() )
463 iUsedColumn = currentcolumn;
467 iUsedColumn += cell->extraXCells();
468 if (iUsedColumn > columns)
469 columns = iUsedColumn;
470 if ( iUsedColumn > 0 )
475#include <htmlexport.moc>