//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
static const QString nbspQstr (" ");
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// constructor 1 of 1
RepGenSlotHtml::RepGenSlotHtml (RwModelReport* rep, const Slot* slotPtr)
: RepGenSlot (rep, slotPtr)
{
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
RepGenSlotHtml::~RepGenSlotHtml()
{
_modelReport = NULL;
_slot = NULL;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// virtual from RepGenSlot
void RepGenSlotHtml::writeSlotListHeader (SlotListType slotListType,
const QString& slotColLabel,
int indentLev,
cwofstream& os) const
{
const QString indentStr (indentLev, QChar (' ')); // Indent String
static const QString listRowTempl_ScalarSlot (
"INDENT\n"
"INDENT %2 | \n" // type icons / name
"INDENT Value | \n" // slot value
"INDENT Units | \n" // slot units
"INDENT
" );
static const QString listRowTempl_SeriesSlot (
"INDENT\n"
"INDENT %2 | \n" // type icons / slot name
"INDENT Units | \n" // slot units
"INDENT Rows | \n" // slot row count
"INDENT Cols | \n" // slot column count
"INDENT Step | \n" // series step size
"INDENT Start | \n" // start date
"INDENT End | \n" // end date
"INDENT
" );
static const QString listRowTempl_OtherSlot (
"INDENT\n"
"INDENT %2 | \n" // type icons / slot name
"INDENT Rows | \n" // slot row count
"INDENT Cols | \n" // slot column count
"INDENT Column Labels | \n" // slot column labels
"INDENT
" );
QString formatStr ("");
switch (slotListType)
{
case SlotList_Scalar: formatStr = listRowTempl_ScalarSlot; break;
case SlotList_Series: formatStr = listRowTempl_SeriesSlot; break;
case SlotList_Other: formatStr = listRowTempl_OtherSlot; break;
}
formatStr.replace (QString ("INDENT"), indentStr);
const QString html = formatStr
.arg (HeaderBackgroundColor)
.arg (slotColLabel);
os << qPrintable (html) << endl;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// virtual from RepGenSlot
void RepGenSlotHtml::writeSlotListRow (SlotListType slotListType,
int indentLevel, cwofstream& os) const
{
static const char (*mname) ("RepGenSlotHtml::writeScalarSlotListRow");
if (_slot == NULL) return;
//---------------------->>
static const QString IconAndNameTD_Templ (
"INDENT T_OBJ_ICON | \n" // obj type icon
"INDENT T_SLOT_ICON | \n" // slot type icon
"INDENT T_SLOT_NAME | \n" ); // slot name (no link)
static const QString ValueTD_Templ ( "INDENT T_VALUE | \n" );
static const QString UnitsTD_Templ ( "INDENT T_UNITS | \n" );
static const QString RowsTD_Templ ( "INDENT T_ROWS | \n" );
static const QString ColsTD_Templ ( "INDENT T_COLS | \n" );
static const QString LabsTD_Templ ( "INDENT T_LABS | \n" );
static const QString StepTD_Templ ( "INDENT T_STEP | \n" );
static const QString StartTD_Templ ( "INDENT T_START | \n" );
static const QString EndTD_Templ ( "INDENT T_END | \n" );
QString tabDatElement (IconAndNameTD_Templ); // three columns
switch (slotListType)
{
case SlotList_Scalar:
tabDatElement += ValueTD_Templ;
tabDatElement += UnitsTD_Templ;
break;
case SlotList_Series:
tabDatElement += UnitsTD_Templ;
tabDatElement += RowsTD_Templ;
tabDatElement += ColsTD_Templ;
tabDatElement += StepTD_Templ;
tabDatElement += StartTD_Templ;
tabDatElement += EndTD_Templ;
break;
case SlotList_Other:
tabDatElement += RowsTD_Templ;
tabDatElement += ColsTD_Templ;
tabDatElement += LabsTD_Templ;
break;
}
QString tabRowElement =
QString ("INDENT\n%1"
"INDENT
\n") .arg (tabDatElement);
// Indentation Substitution
const QString indentStr (indentLevel, QChar (' ')); // Indent String
tabRowElement.replace (QString ("INDENT"), indentStr);
// Align-Right TD Attribute
tabRowElement.replace (QString ("Align_RT"), "align=\"right\"");
// HTML IMG ALIGN ATTRIBUTE
static const QString iconAlignText (""); // (No align attribute)
const QString objIconHtml =
RepGen::html_icon (objImgFileHtml(), objImgSize(), 0, objTypHtml(),
iconAlignText);
const QString objUrl = RepGen::localSimObjUrl (_slot->getSimObj());
const QString objIconLinkHtml = RepGen::html_link (objIconHtml, objUrl);
const QString slotIconHtml =
RepGen::html_icon (slotImgFileHtml(), slotImgSize(), 0, slotTypHtml(),
iconAlignText);
QString slotNameHtmlStr (slotNameHtml()); // tentative
const bool linkSlot (slotDetailSupported());
if (linkSlot)
{
const QString slotUrl = RepGen::localSlotUrl (_slot, true); // quoted
slotNameHtmlStr = QString ("%2")
.arg (slotUrl)
.arg (slotNameHtml());
}
tabRowElement.replace (QString ("T_OBJ_ICON"), objIconLinkHtml);
tabRowElement.replace (QString ("T_SLOT_ICON"), slotIconHtml);
tabRowElement.replace (QString ("T_SLOT_NAME"), slotNameHtmlStr);
tabRowElement.replace (QString ("T_VALUE"), slotValHtml());
tabRowElement.replace (QString ("T_UNITS"), slotUnitsHtml (false));
tabRowElement.replace (QString ("T_ROWS"), slotRowsHtml());
tabRowElement.replace (QString ("T_COLS"), slotColsHtml());
tabRowElement.replace (QString ("T_LABS"), slotLabelsHtml());
tabRowElement.replace (QString ("T_STEP"), seriesStepHtml());
tabRowElement.replace (QString ("T_START"), seriesStartHtml());
tabRowElement.replace (QString ("T_END"), seriesEndHtml());
os << qPrintable (tabRowElement) << endl;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// private
void RepGenSlotHtml::writeSlotDetailTitleSection (cwofstream& os)
{
if (_slot == NULL) return;
//---------------------->>
SimObj* obj (_slot->getSimObj()); // may be NULL
// ********************************
// *** Slot HTML Named Anchor ***
// ********************************
const QString objName = (obj ? obj->getCompleteName() : "SimObj");
const QString slotName = _slot->getName();
const QString fullSlotName = _slot->getCompleteName();
const QString slotMunge = RepGen::reduceNameString (fullSlotName);
const QString slotAnchor = QString ("") .arg (slotMunge);
QString fullSlotTitle (fullSlotName);
fullSlotTitle.replace (QChar ('.'), QString (" . "));
os << qPrintable (slotAnchor) << endl;
// ****************************
// *** Slot Detail Header ***
// ****************************
static const QString fmt (
"\n"
" \n"
" | \n"
" \n"
" \n"
" \n"
" Object: | \n"
" %1 | \n"
" \n"
" \n"
" Slot: | \n"
" %2 | \n"
" \n"
" \n"
" | \n"
" \n"
" \n"
" \n"
" %3 | \n"
" | \n"
" %4 | \n"
" | \n"
" %5 | \n"
" | \n"
" %6 | \n"
" \n"
" \n"
" | \n"
" \n"
" \n"
" | \n"
" | \n"
"
\n"
"
\n" );
static const QString iconAlignText (""); // (No align attribute)
const QString objIconHtml =
RepGen::html_icon (objImgFileHtml(), objImgSize(), 0, objTypHtml(),
iconAlignText);
const QString objUrl = RepGen::localSimObjUrl (obj);
const QString objIconLinkHtml = RepGen::html_link (objIconHtml, objUrl);
const QString objLongTypStr (obj ? obj->getLongTypeName(true) : "");
const QString slotIconHtml =
RepGen::html_icon (slotImgFileHtml(), slotImgSize(), 0, slotTypHtml(),
iconAlignText);
const QString slotTitleContent = fmt .arg (objName)
.arg (slotName)
.arg (objIconLinkHtml)
.arg (objLongTypStr) // verbose
.arg (slotIconHtml)
.arg (slotTypHtml (true)); // verbose
const QString boxedTitle = RepGen::htmlTableBox (0, slotTitleContent, 3);
os << qPrintable (boxedTitle) << endl;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// private
void RepGenSlotHtml::writeSlotDataTable (cwofstream& os)
{
if (_slot == NULL) return;
//---------------------->>
// ****************************************
// *** Write Pre-Table Notes (if any) ***
// *** (1) Row Truncation Notice ***
// *** (2) Column Map Entity Name ***
// ****************************************
bool paragraphWritten (false); // tentative
const int dataRowCnt = SlotGUIUtils::getNumSlotRows (_slot);
const bool truncateRows = (dataRowCnt > MAX_SLOT_DATA_ROWS);
if (truncateRows)
{
static const QString truncMsgFmt (
"The number of rows in this slot (%1) exceeds the maximum \n"
"number of slot rows for this report (%2). Only the first and \n"
"last several rows are shown.
" );
const QString truncMsg = truncMsgFmt .arg (dataRowCnt)
.arg (MAX_SLOT_DATA_ROWS);
os << qPrintable (truncMsg) << endl;
paragraphWritten = true;
}
QString colMapEntityName ("");
const bool colMapEntityDef =
SlotGUIUtils::getColMapEntityName (_slot, colMapEntityName);
if (colMapEntityDef && !colMapEntityName.isEmpty())
{
// Write Column Map Entity description
static const QString colMapEntFmt (
"Numeric column header value entity: %1
\n");
QString colMapEntStr = colMapEntFmt .arg (colMapEntityName);
os << qPrintable (colMapEntStr) << endl;
paragraphWritten = true;
}
if (!paragraphWritten)
{
os << "
" << endl;
}
// **************************************
// *** Set up HTML Table Attributes ***
// **************************************
static const QString cellPaddingFmt (" cellpadding=\"%1\"");
static const QString cellSpacingFmt (" cellspacing=\"%2\"");
static const QString borderPixFmt (" border=\"%3\"");
const QString cellPadding (cellPaddingFmt .arg (4)); // PADDING
const QString cellSpacing (cellSpacingFmt .arg (0)); // CELL SPACING
const QString borderPix (borderPixFmt .arg (1)); // BORDER
static const QString tableElement ( QString ("")
.arg (cellPadding)
.arg (cellSpacing)
.arg (borderPix) );
// *************************
// *** Slot Data Table ***
// *************************
os << qPrintable (tableElement) << endl;
writeSlotDataTableColMap (1, os);
writeSlotDataTableHeader (1, os);
for (int rowInx = 0; rowInx < dataRowCnt; ++rowInx)
{
writeSlotDataTableRow (rowInx, 1, os);
if (truncateRows)
{
if (rowInx == 4)
{
// Draw divider row
writeSlotDataTableRow ((-1), 1, os);
// Skip ahead
rowInx = std::max (5, dataRowCnt-5);
}
}
}
os << "
\n"
<< "
"
<< endl;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// private
void RepGenSlotHtml::writeSlotDataTableHeader (int indentLevel, cwofstream& os)
{
if (_slot == NULL) return;
//---------------------->>
// ListSlots don't need a slot data table header
if (_slot->isA (Slot::ListSlotBit)) return;
//--------------------------------------->>
static const QString trFmtBeg ("INDENT\n");
static const QString tdFmtLft ("INDENT %1 | \n");
static const QString tdFmtRgt ("INDENT %1 | \n");
static const QString trFmtEnd ("INDENT
\n");
QString trElement (trFmtBeg.arg (HeaderBackgroundColor));
trElement += tdFmtLft.arg (nbspQstr);
const int dataColCnt = SlotGUIUtils::getNumCols (_slot);
for (int colInx = 0; colInx < dataColCnt; ++colInx)
{
const QString colLab =
SlotGUIUtils::getColLabel (_slot, colInx).toLocal8Bit().constData();
const ScaledUnitPtr scUnit =
SlotGUIUtils::getScaledUnitPtr (_slot, colInx);
const QString colUnits =
SlotGUIUtils::scaledUnitDisplayStr (scUnit);
bool alignRight (true); // tentative
QString colHeaderHtml (""); // tentative
if (!colLab.isEmpty())
{
alignRight = false;
colHeaderHtml = colLab;
}
if (!colUnits.isEmpty())
{
if (!colHeaderHtml.isEmpty())
colHeaderHtml += "
";
colHeaderHtml += QString ("[%2]") .arg (colUnits);
}
if (colHeaderHtml.isEmpty())
{
colHeaderHtml = nbspQstr;
}
trElement += (alignRight ? tdFmtRgt : tdFmtLft)
.arg (colHeaderHtml);
}
trElement += trFmtEnd;
const QString indentStr (indentLevel, QChar (' ')); // Indent String
trElement.replace (QString ("INDENT"), indentStr);
os << qPrintable (trElement) << endl;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// private
void RepGenSlotHtml::writeSlotDataTableColMap (int indentLevel, cwofstream& os)
{
if (_slot == NULL) return;
//---------------------->>
// Only TableSlots (incl. subclasses) support Column Maps (NumericDimension)
if (!_slot->isA (Slot::TableSlotBit)) return;
//----------------------------------------->>
QStringList colMapUsrValStrs;
QString colMapUnitsStr ("");
const bool colMapDataFound =
SlotGUIUtils::getColMapUsrValues (_slot, colMapUsrValStrs,
colMapUnitsStr);
if (!colMapDataFound) return;
//------------------------->>
if (!colMapUnitsStr.startsWith (QChar ('[')))
colMapUnitsStr = QString ("[%1]") .arg (colMapUnitsStr);
static const QString trFmtBeg ("INDENT\n");
static const QString tdFmtLft ("INDENT %1 | \n");
static const QString tdFmtRgt ("INDENT %1 | \n");
static const QString trFmtEnd ("INDENT
\n");
QString trElement (trFmtBeg.arg (ColMapBackgroundColor));
trElement += tdFmtLft.arg (nbspQstr); // blank row header column
const int dataColCnt = SlotGUIUtils::getNumCols (_slot);
for (int colInx = 0; colInx < dataColCnt; ++colInx)
{
const QString colMapStr = colMapUsrValStrs.value (colInx);
const QString valStr = colMapStr.isEmpty() ? nbspQstr : colMapStr;
const QString unitStr = colMapStr.isEmpty() ? nbspQstr : colMapUnitsStr;
const QString colMapHtml = QString ("%1
%2")
.arg (valStr)
.arg (unitStr);
trElement += tdFmtRgt.arg (colMapHtml);
}
trElement += trFmtEnd;
const QString indentStr (indentLevel, QChar (' ')); // Indent String
trElement.replace (QString ("INDENT"), indentStr);
os << qPrintable (trElement) << endl;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// private
void RepGenSlotHtml::writeSlotDataTableRow (int row,
int indentLevel, cwofstream& os)
{
static const QString ellipsis ("...");
//--------------------------------------------------------
// NOTE: if (row < 0), show a divider row (with ellipsis).
//--------------------------------------------------------
if (_slot == NULL) return;
//---------------------->>
const bool isListSlot (_slot->isA (Slot::ListSlotBit));
static const QString trFmtBeg ("INDENT\n");
static const QString tdFmtLft ("INDENT %1 | \n");
static const QString tdFmtRgt ("INDENT %1 | \n");
static const QString trFmtEnd ("INDENT
\n");
QString trElement (trFmtBeg);
// ***********************************
// *** Row Header (First Column) ***
// ***********************************
const bool supportsTextRowLabel (_slot->isA (Slot::TableSlotBit) ||
_slot->isA (Slot::SeriesSlotBit) );
QString rowLab (nbspQstr); // tentative
bool rowHeaderColAlignRight (true); // tentative
if (row < 0)
{
rowLab = ellipsis;
}
else // (row >= 0)
{
rowLab = QString::number (row); // tentative
if (supportsTextRowLabel)
{
const QString rowLabStr = SlotGUIUtils::getRowLabel (_slot, row);
if (!rowLabStr.isEmpty())
{
rowLab = rowLabStr;
rowHeaderColAlignRight = false;
}
}
}
trElement += (rowHeaderColAlignRight ? tdFmtRgt.arg (rowLab)
: tdFmtLft.arg (rowLab));
// ************************************************
// *** Special Column for ListSlots: Item Icon ***
// ************************************************
if (isListSlot)
{
const ListSlotBase* lslot = dynamic_cast (_slot);
if (lslot)
{
IconHandle lsIcon ((SimObj*) NULL, false);
const bool iconOk = lslot->getItemIcon (row, lsIcon);
if (iconOk)
{
const QString imgFileStr =
RepGen::imgFileStr (lsIcon, _modelReport);
const QSize imgSize = RepGen::imgSize (lsIcon);
const QString altText = lsIcon.iconDescStr();
const QString objIconHtml =
RepGen::html_icon (imgFileStr, imgSize, 0, altText, "");
trElement += tdFmtLft.arg (objIconHtml);
}
else
{
trElement += tdFmtLft.arg (nbspQstr);
}
}
}
// ***************************
// *** Slot Data Columns ***
// ***************************
const QString tdFmt (isListSlot ? tdFmtLft : tdFmtRgt);
const int dataColCnt = SlotGUIUtils::getNumCols (_slot);
for (int colInx = 0; colInx < dataColCnt; ++colInx)
{
if (row < 0)
{
trElement += tdFmt.arg (ellipsis);
}
else
{
const QString valStr =
SlotGUIUtils::getValueUsrStr (_slot, row, colInx,
false, //-- for edit
false); //-- alt units
trElement += tdFmt.arg (valStr);
}
}
trElement += trFmtEnd;
const QString indentStr (indentLevel, QChar (' ')); // Indent String
trElement.replace (QString ("INDENT"), indentStr);
os << qPrintable (trElement) << endl;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// *****************************
// *** HTML Slot Utilities ***
// *****************************
QString RepGenSlotHtml::slotTypHtml (bool verbose /*=false*/) const
{
const QString str = slotTypStr (verbose); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::slotImgFileHtml() const
{
if (_slot)
{
const IconHandle slotIcon (_slot);
const QString filename = RepGen::imgFileStr (slotIcon, _modelReport);
return (filename);
//-------------->>
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QSize RepGenSlotHtml::slotImgSize() const
{
QSize slotTypeIconSize (0,0); // tentative
if (_slot)
{
const IconHandle slotIcon (_slot);
slotTypeIconSize = RepGen::imgSize (slotIcon);
}
return (slotTypeIconSize);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::slotNameHtml() const
{
const QString str = slotNameStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::slotValHtml() const
{
const QString str = slotValStr(); // [RepGenSlot] (for scalars)
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::slotUnitsHtml (bool withBrackets) const
{
const QString str = slotUnitsStr (withBrackets); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::slotRowsHtml() const
{
const QString str = slotRowsStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::slotColsHtml() const
{
const QString str = slotColsStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::slotLabelsHtml() const
{
const QString str = slotLabelsStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::seriesStepHtml() const
{
const QString str = seriesStepStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::seriesStartHtml() const
{
const QString str = seriesStartStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::seriesEndHtml() const
{
const QString str = seriesEndStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::objTypHtml() const
{
const QString str = objTypStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::objImgFileHtml() const
{
const SimObj* simObj = (_slot ? _slot->getSimObj() : NULL);
if (simObj)
{
const IconHandle objIcon (simObj, false); // Not Large
const QString filename = RepGen::imgFileStr (objIcon, _modelReport);
return (filename);
//-------------->>
}
return (nbspQstr); //
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QSize RepGenSlotHtml::objImgSize() const
{
QSize objTypeIconSize (0,0); // tentative
SimObj* obj = (_slot ? _slot->getSimObj() : NULL);
if (obj)
{
const IconHandle objIcon (obj, false); // not large
objTypeIconSize = RepGen::imgSize (objIcon);
}
return (objTypeIconSize);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
QString RepGenSlotHtml::objNameHtml() const
{
const QString str = objNameStr(); // [RepGenSlot]
if (!str.isEmpty())
{
return (str);
}
return (nbspQstr); //
}
//--- (end RepGenSlotHtml.cpp) ---