/** * Get some summary statistics on the specified field in a human-readable * format. The exact content of the summary depends on the data type of the * field. The summary is with respect to the current filter, not the entire * database (unless an all-inclusive filter is selected, of course). * * @param colIndex The position index of the field to get statistics for * @return A list of individual "Name: value" statistics formatted as rows * of an HTML table */ QStringList View::getStatistics(int colIndex) { QStringList lines; if (rowCnt == 0) { lines.append(QString("<tr><td>%1</td></tr>") .arg(tr("No data to summarize"))); return lines; } int type = dataTypes[colIndex]; QLocale locale = QLocale::system(); QString pattern("<tr><td align=\"right\"><font color=\"#0000ff\">%1</font>: </td><td>%2</td></tr>"); if (type == INTEGER || type == SEQUENCE) { c4_IntProp prop(ids[colIndex]); int value = prop (dbview[0]); int total = value; int min = value; int max = value; for (int i = 1; i < rowCnt; i++) { int value = prop (dbview[i]); total += value; min = qMin(min, value); max = qMax(max, value); } float mean = total / (float)rowCnt; lines.append(pattern.arg(tr("Total")).arg(locale.toString(total))); lines.append(pattern.arg(tr("Average")).arg(locale.toString(mean))); lines.append(pattern.arg(tr("Minimum")).arg(locale.toString(min))); lines.append(pattern.arg(tr("Maximum")).arg(locale.toString(max))); } else if (type == FLOAT || type == CALC) { c4_FloatProp prop(ids[colIndex]); c4_StringProp stringProp(scIds[colIndex]); double value = prop (dbview[0]); double total = value; double min = value; double max = value; QString minString = QString::fromUtf8(stringProp (dbview[0])); QString maxString = minString; for (int i = 1; i < rowCnt; i++) { double value = prop (dbview[i]); total += value; if (value < min) { min = value; minString = QString::fromUtf8(stringProp (dbview[i])); } if (value > max) { max = value; maxString = QString::fromUtf8(stringProp (dbview[i])); } } double mean = total / rowCnt; lines.append(pattern.arg(tr("Total")) .arg(locale.toString(total, 'f', 2))); lines.append(pattern.arg(tr("Average")) .arg(locale.toString(mean, 'f', 2))); lines.append(pattern.arg(tr("Minimum")) .arg(Formatting::toLocalDouble(minString))); lines.append(pattern.arg(tr("Maximum")) .arg(Formatting::toLocalDouble(maxString))); } else if (type == BOOLEAN) { c4_IntProp prop(ids[colIndex]); int checked = 0; for (int i = 0; i < rowCnt; i++) { int value = prop (dbview[i]); if (value == 1) { checked++; } } lines.append(pattern.arg(tr("Checked")) .arg(locale.toString(checked))); lines.append(pattern.arg(tr("Unchecked")) .arg(locale.toString(rowCnt - checked))); } else if (type == DATE) { c4_IntProp prop(ids[colIndex]); int value = prop (dbview[0]); int min = value; int max = value; for (int i = 1; i < rowCnt; i++) { int value = prop (dbview[i]); if (value != 17520914) { min = (min == 17520914) ? value : qMin(min, value); max = qMax(max, value); } } lines.append(pattern.arg(tr("Earliest")) .arg(Formatting::dateToString(min))); lines.append(pattern.arg(tr("Latest")) .arg(Formatting::dateToString(max))); } else if (type == TIME) { c4_IntProp prop(ids[colIndex]); int value = prop (dbview[0]); int min = value; int max = value; for (int i = 1; i < rowCnt; i++) { int value = prop (dbview[i]); if (value != -1) { min = (min == -1) ? value : qMin(min, value); max = qMax(max, value); } } lines.append(pattern.arg(tr("Earliest")) .arg(Formatting::timeToString(min))); lines.append(pattern.arg(tr("Latest")) .arg(Formatting::timeToString(max))); } else if (type == STRING || type == NOTE) { c4_StringProp prop(ids[colIndex]); QString value = QString::fromUtf8(prop (dbview[0])); int length = value.length(); int total = length; int min = length; int max = length; for (int i = 1; i < rowCnt; i++) { QString svalue = QString::fromUtf8(prop (dbview[i])); length = svalue.length(); total += length; min = qMin(min, length); max = qMax(max, length); } int mean = total / rowCnt; lines.append(pattern.arg(tr("Total length")) .arg(tr("%Ln character(s)", "", total))); lines.append(pattern.arg(tr("Average length")) .arg(tr("%Ln character(s)", "", mean))); lines.append(pattern.arg(tr("Minimum length")) .arg(tr("%Ln character(s)", "", min))); lines.append(pattern.arg(tr("Maximum length")) .arg(tr("%Ln character(s)", "", max))); } else if (type == IMAGE) { c4_StringProp stringProp(scIds[colIndex]); int missing = 0; for (int i = 0; i < rowCnt; i++) { QString value(stringProp (dbview[i])); if (value.isEmpty()) { missing++; } } lines.append(pattern.arg(tr("Image available")) .arg(locale.toString(rowCnt - missing))); lines.append(pattern.arg(tr("No image")) .arg(locale.toString(missing))); } else if (type >= FIRST_ENUM) { c4_StringProp prop(ids[colIndex]); QStringList options = db->listEnumOptions(type); int optionCount = options.count(); int *tallies = new int[optionCount]; int i; for (i = 0; i < optionCount; i++) { tallies[i] = 0; } for (i = 0; i < rowCnt; i++) { int index = options.indexOf(QString::fromUtf8(prop (dbview[i]))); tallies[index] = tallies[index] + 1; } for (i = 0; i < optionCount; i++) { lines.append(pattern.arg(options[i]) .arg(locale.toString(tallies[i]))); } delete[] tallies; } return lines; }
//TODO: out at maximum one warning per unsupported type void readInputProperties( Abc::ICompoundProperty prop, std::vector<AbcProp>& props ) { if(!prop){ return; } for(size_t i=0; i<prop.getNumProperties(); i++){ AbcA::PropertyHeader pheader = prop.getPropertyHeader(i); AbcA::PropertyType propType = pheader.getPropertyType(); //ESS_LOG_WARNING("Property, propName: "<<pheader.getName()<<", pod: "<<getPodStr(pheader.getDataType().getPod()) \ // <<", extent: "<<(int)pheader.getDataType().getExtent()<<", interpretation: "<<pheader.getMetaData().get("interpretation")); int invalidStrIndex = containsInvalidString(pheader.getName()); if( invalidStrIndex > 0 ){ ESS_LOG_WARNING("Skipping property "<<pheader.getName()<<" because it contains an invalid character: "<<invalidStrTable[invalidStrIndex]); continue; } if( propType == AbcA::kCompoundProperty ){ //printInputProperties(Abc::ICompoundProperty(prop, pheader.getName())); //ESS_LOG_WARNING("Unsupported compound property: "<<pheader.getName()); } else if( propType == AbcA::kScalarProperty ){ //ESS_LOG_WARNING("Scaler property: "<<pheader.getName()); // std::string displayVal; bool bConstant = true; int sortId = 0; int size = 0; if(Abc::IBoolProperty::matches(pheader)){ //I need to know the name and type only if animated; an appropriate controller will handle reading the data. //If not animated, the value will set directly on the light and/or display modifier Abc::IBoolProperty boolProp(prop, pheader.getName()); /*if(boolProp.isConstant()){*/ AbcU::bool_t bVal = false; boolProp.get(bVal); if(bVal == true) displayVal = "true"; else displayVal = "false"; //} //else{ // //} } else if(readPropExt1<Abc::IInt32Property, int>(prop, pheader, displayVal, bConstant)); else if(readPropExt1<Abc::IFloatProperty, float>(prop, pheader, displayVal, bConstant)); else if(readPropExt3<Abc::IC3fProperty, Abc::C3f>(prop, pheader, displayVal, bConstant)); else if(readPropExt3<Abc::IV3fProperty, Abc::V3f>(prop, pheader, displayVal, bConstant)); else if(readPropExt3<Abc::IN3fProperty, Abc::N3f>(prop, pheader, displayVal, bConstant)); else if(Abc::IStringProperty::matches(pheader)){ Abc::IStringProperty stringProp(prop, pheader.getName()); stringProp.get(displayVal); sortId = 1000000000; } else{ // Abc::PropertyHeader propHeader = props.getPropertyHeader(i); // AbcA::PropertyType propType = propHeader.getPropertyType(); ESS_LOG_WARNING("Unsupported property, propName: "<<pheader.getName()<<", pod: "<<getPodStr(pheader.getDataType().getPod()) \ <<", extent: "<<(int)pheader.getDataType().getExtent()<<", interpretation: "<<pheader.getMetaData().get("interpretation")); } props.push_back(AbcProp(pheader.getName(), displayVal, pheader, bConstant, sortId)); } else if( propType == AbcA::kArrayProperty ){ //ESS_LOG_WARNING("Unsupported array property: "<<pheader.getName()); //it the moment is unlikely we will support array properties in 3DS Max. They won't work so well with our display modifier system. //ESS_LOG_WARNING("Unsupported array property, propName: "<<pheader.getName()<<", pod: "<<getPodStr(pheader.getDataType().getPod()) \ //<<", extent: "<<(int)pheader.getDataType().getExtent()<<", interpretation: "<<pheader.getMetaData().get("interpretation")); } else{ ESS_LOG_WARNING("Unsupported input property: "<<pheader.getName()); } } }