Beispiel #1
0
bool KIcoPlugin::readInfo( KFileMetaInfo& info, uint what)
{


    QFile file(info.path());

    if (!file.open(IO_ReadOnly))
    {
        kdDebug(7034) << "Couldn't open " << QFile::encodeName(info.path()) << endl;
        return false;
    }

    QDataStream dstream(&file);

    // ICO files are little-endian
    dstream.setByteOrder(QDataStream::LittleEndian);


    // read the beginning of the file and make sure it looks ok
    uint16_t ico_reserved;
    uint16_t ico_type;
    uint16_t ico_count;

    dstream >> ico_reserved;
    dstream >> ico_type;
    dstream >> ico_count;

    if ((ico_reserved != 0) || (ico_type != 1) || (ico_count < 1))
        return false;


    // now loop through each of the icon entries
    uint8_t icoe_width;
    uint8_t icoe_height;
    uint8_t icoe_colorcount;
    uint8_t icoe_reserved;
    uint16_t icoe_planes;
    uint16_t icoe_bitcount;
    uint32_t icoe_bytesinres;
    uint32_t icoe_imageoffset;

    // read the data on the 1st icon
    dstream >> icoe_width;
    dstream >> icoe_height;
    dstream >> icoe_colorcount;
    dstream >> icoe_reserved;
    dstream >> icoe_planes;
    dstream >> icoe_bitcount;
    dstream >> icoe_bytesinres;
    dstream >> icoe_imageoffset;


    // output the useful bits
    KFileMetaInfoGroup group = appendGroup(info, "Technical");
    appendItem(group, "Number", ico_count);

    if (ico_count == 1) {
        appendItem(group, "Dimensions", QSize(icoe_width, icoe_height));

        if (icoe_colorcount > 0)
            appendItem(group, "Colors", icoe_colorcount);
        else if (icoe_bitcount > 0)
            appendItem(group, "Colors", 2 ^ icoe_bitcount);

    } else {

        appendItem(group, "DimensionsM", QSize(icoe_width, icoe_height));

        if (icoe_colorcount > 0)
            appendItem(group, "ColorsM", icoe_colorcount);
        else if (icoe_bitcount > 0)
            appendItem(group, "ColorsM", 2 ^ icoe_bitcount);

    }

    return true;
}
Beispiel #2
0
bool KOfficePlugin::readInfo( KFileMetaInfo& info, uint /*what*/)
{
    if ( info.path().isEmpty() ) // remote file
        return false;

    KFileMetaInfoGroup group = appendGroup(info, DocumentInfo);
    QDomDocument doc = getMetaDocument(info.path());
    if (doc.isNull())
	    return false;
    QDomElement base = getBaseNode(doc).toElement();
    if (base.isNull())
	    return false;
    for (int i = 0; Information[i]; i+=2)
	    appendItem(group, Information[i],
		       stringFromNode(base, Information[i]));
    // Special case for keyword
    QDomNodeList keywordList = base.elementsByTagName( metakeyword );
    QString allKeywords;
    for (uint i = 0; i < keywordList.length(); i++){
      QDomNode node = keywordList.item(i);
      if (node.isElement()){
	if (i>0)
		allKeywords += ", ";
	allKeywords += node.toElement().text();
      }
    }
    appendItem(group, metakeyword,
	       allKeywords);

    KFileMetaInfoGroup group1 = appendGroup(info, DocAdvanced);
    for (int i = 0; Advanced[i]; i+=2){
	    QString txt = stringFromNode(base, Advanced[i]);
	    if (!txt.isEmpty()){
		    // A silly way to do it...
		    switch (i){
			    case 2:
			    case 4:
			    case 6:
			    	getDateTime(group1, Advanced[i], txt);
				break;
			    case 14:
				getEditingTime(group1, Advanced[i], txt);
				break;
			    default:
				appendItem(group1, Advanced[i], txt);}
		   }
	    }

    QDomNode dstat = base.namedItem(metadocstat);

    KFileMetaInfoGroup group2 = appendGroup(info, DocStatistics);
    if (!dstat.isNull() && dstat.isElement()){
	    QDomElement dinfo = dstat.toElement();
    	    for (int i = 0; Statistics[i]; i+=2)
		    addAttributeInfo(dinfo, group2, Statistics[i] );
    }


    QDomNodeList userList = base.elementsByTagName( metauserdef );

    KFileMetaInfoGroup groupuser = appendGroup(info, UserDefined);

    for (uint i = 0; i < userList.length(); i++){
      QDomNode node = userList.item(i);
      if (node.isElement()){
	appendItem(groupuser,
		   node.toElement().attribute(metaname,
					      QString("User %1").arg(i)),
		   node.toElement().text());
      }
    }
    return true;
}
bool KRpmPlugin::readInfo( KFileMetaInfo& info, uint what)
{
    QFile file(info.path());
    int pass;
    KFileMetaInfoGroup general, all;

    if (!file.open(QIODevice::ReadOnly))
    {
        kDebug(7034) << "Couldn't open " << QFile::encodeName(info.path());
        return false;
    }

    QDataStream dstream(&file);
    dstream.setByteOrder(QDataStream::BigEndian);
    general = appendGroup(info, "General");
    if (what == KFileMetaInfo::Everything) all = appendGroup(info, "All tags");

    file.seek(96); // Seek past old lead

    for (pass = 0; pass < 2; ++pass) { // RPMs have two headers
	uint32_t storepos, entries, size, reserved;
	unsigned char version;
	char magic[3];

	dstream.readRawBytes(magic, 3);
	dstream >> version >> reserved >> entries >> size;
	if (memcmp(magic, RPM_HEADER_MAGIC, 3)) return false;
	if (version != 1) return false; // Only v1 headers supported

	storepos = file.pos() + entries * 16;
	if (pass == 0) { // Don't need the first batch of tags - pgp etc
		file.seek(storepos + size);
		file.seek(file.pos() + (8 - (file.pos() % 8)) % 8); // Skip padding
		continue;
	}

	if (entries < 500) while (entries--) { // Just in case something goes wrong, limit to 500
		uint32_t tag, type, offset, count;
		QString tagname;
		dstream >> tag >> type >> offset >> count;
		offset += storepos;

		switch (tag) {
			case RPMTAG_NAME: tagname = "Name"; break;
			case RPMTAG_VERSION: tagname = "Version"; break;
			case RPMTAG_SUMMARY: tagname = "Summary"; break;
			case RPMTAG_GROUP: tagname = "Group"; break;
			case RPMTAG_SIZE: tagname = "Size"; break;
			case RPMTAG_RELEASE: tagname = "Release"; break;
			case RPMTAG_VENDOR: tagname = "Vendor"; break;
			case RPMTAG_PACKAGER: tagname = "Packager"; break;
			case RPMTAG_DESCRIPTION: tagname = "Comment"; break;
		}

		if ( !tagname.isEmpty() || all.isValid() ) {
			// kDebug(7034) << "Tag number: " << tag << " Type: " << type;
			int oldPos = file.pos();
			file.seek(offset); // Set file position to correct place in store
			switch (type) {
				case RPM_INT32_TYPE:	uint32_t int32tag;
							dstream >> int32tag;
							if ( !tagname.isEmpty() ) appendItem(general, tagname, int(int32tag));
							if ( all.isValid() ) appendItem(all, QString("%1").arg( tag ), QString("%1").arg( int32tag ));
							break;
				case RPM_INT16_TYPE:	uint16_t int16tag;
							dstream >> int16tag;
							if ( !tagname.isEmpty() ) appendItem(general, tagname, int(int16tag));
							if ( all.isValid() ) appendItem(all, QString("%1").arg( tag ), QString("%1").arg( int16tag ));
							break;
				case RPM_I18NSTRING_TYPE: // Fallthru
				case RPM_STRING_TYPE:   QString strtag; char in;
							while ( ( in = file.getch() ) != '\0' ) strtag += in;
							if ( !tagname.isEmpty() ) appendItem(general, tagname, strtag);
							if( all.isValid() ) appendItem(all, QString("%1").arg( tag ), strtag);
							break;
			}
			file.seek(oldPos); // Restore old position
		}
	}
	appendItem(general, "Archive Offset", (storepos + size) );
    }
bool KFlacPlugin::readInfo( KFileMetaInfo& info, uint what )
{
    if ( info.path().isEmpty() ) // remote file
        return false;

    bool readComment = false;
    bool readTech = false;
    if (what & (KFileMetaInfo::Fastest |
                KFileMetaInfo::DontCare |
                KFileMetaInfo::ContentInfo)) readComment = true;

    if (what & (KFileMetaInfo::Fastest |
                KFileMetaInfo::DontCare |
                KFileMetaInfo::TechnicalInfo)) readTech = true;

    TagLib::File *file = 0;

    if (info.mimeType() == "audio/x-flac")
        file = new TagLib::FLAC::File(QFile::encodeName(info.path()).data(), readTech);
#ifdef TAGLIB_1_2
    else
        file = new TagLib::Ogg::FLAC::File(QFile::encodeName(info.path()).data(), readTech);
#endif

    if (!file || !file->isValid())
    {
        kdDebug(7034) << "Couldn't open " << file->name() << endl;
        delete file;
        return false;
    }

    if(readComment && file->tag())
    {
        KFileMetaInfoGroup commentgroup = appendGroup(info, "Comment");

        QString date  = file->tag()->year() > 0 ? QString::number(file->tag()->year()) : QString::null;
        QString track = file->tag()->track() > 0 ? QString::number(file->tag()->track()) : QString::null;

        appendItem(commentgroup, "Title",       TStringToQString(file->tag()->title()).stripWhiteSpace());
        appendItem(commentgroup, "Artist",      TStringToQString(file->tag()->artist()).stripWhiteSpace());
        appendItem(commentgroup, "Album",       TStringToQString(file->tag()->album()).stripWhiteSpace());
        appendItem(commentgroup, "Date",        date);
        appendItem(commentgroup, "Comment",     TStringToQString(file->tag()->comment()).stripWhiteSpace());
        appendItem(commentgroup, "Tracknumber", track);
        appendItem(commentgroup, "Genre",       TStringToQString(file->tag()->genre()).stripWhiteSpace());
    }

    if (readTech && file->audioProperties())
    {
        KFileMetaInfoGroup techgroup = appendGroup(info, "Technical");
        TagLib::FLAC::Properties *properties =
                   (TagLib::FLAC::Properties*)(file->audioProperties());

        appendItem(techgroup, "Bitrate",      properties->bitrate());
        appendItem(techgroup, "Sample Rate",  properties->sampleRate());
        appendItem(techgroup, "Sample Width", properties->sampleWidth());
        appendItem(techgroup, "Channels",     properties->channels());
        appendItem(techgroup, "Length",       properties->length());
    }

    delete file;
    return true;

}
Beispiel #5
0
QString KFileItem::getToolTipText(int maxcount)
{
  // we can return QString::null if no tool tip should be shown
  QString tip;
  KFileMetaInfo info = metaInfo();

  // the font tags are a workaround for the fact that the tool tip gets
  // screwed if the color scheme uses white as default text color
  const char* start = "<tr><td><nobr><font color=\"black\">";
  const char* mid   = "</font></nobr></td><td><nobr><font color=\"black\">";
  const char* end   = "</font></nobr></td></tr>";

  tip = "<table cellspacing=0 cellpadding=0>";

  tip += start + i18n("Name:") + mid + text() + end;
  tip += start + i18n("Type:") + mid;

  QString type = QStyleSheet::escape(mimeComment());
  if ( m_bLink ) {
   tip += i18n("Link to %1 (%2)").arg(linkDest(), type) + end;
  } else
    tip += type + end;

  if ( !S_ISDIR ( m_fileMode ) ) {
    bool hasSize;
    KIO::filesize_t sizeValue = size(hasSize);
    if(hasSize)
      tip += start + i18n("Size:") + mid +
             KIO::convertSizeWithBytes(sizeValue) + end;
  }
  QString timeStr = timeString( KIO::UDS_MODIFICATION_TIME);
  if(!timeStr.isEmpty())
    tip += start + i18n("Modified:") + mid +
           timeStr + end;
#ifndef Q_WS_WIN //TODO: show win32-specific permissions
  QString userStr = user();
  QString groupStr = group();
  if(!userStr.isEmpty() || !groupStr.isEmpty())
    tip += start + i18n("Owner:") + mid + userStr + " - " + groupStr + end +
           start + i18n("Permissions:") + mid +
           parsePermissions(m_permissions) + end;
#endif

  if (info.isValid() && !info.isEmpty() )
  {
    tip += "<tr><td colspan=2><center><s>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</s></center></td></tr>";
    QStringList keys = info.preferredKeys();

    // now the rest
    QStringList::Iterator it = keys.begin();
    for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
    {
      KFileMetaInfoItem item = info.item( *it );
      if ( item.isValid() )
      {
        QString s = item.string();
        if ( ( item.attributes() & KFileMimeTypeInfo::SqueezeText )
             && s.length() > 50) {
            s.truncate(47);
            s.append("...");
        }
        if ( !s.isEmpty() )
        {
          count++;
          tip += start +
                   QStyleSheet::escape( item.translatedKey() ) + ":" +
                 mid +
                   QStyleSheet::escape( s ) +
                 end;
        }

      }
    }
  }
  tip += "</table>";

  //kdDebug() << "making this the tool tip rich text:\n";
  //kdDebug() << tip << endl;

  return tip;
}
bool KAuPlugin::readInfo( KFileMetaInfo& info, uint what)
{
    // the file signature, wants to be tidier...
    const char fsig[] = { 0x2e, 0x73, 0x6e, 0x64 };

    // a dword buffer for input
    char inbuf[4];

    // some vars for the file properties
    uint32_t datasize;
    uint32_t encoding;
    uint32_t samplerate;
    uint32_t channels;
    uint16_t bytespersample;

    if ( info.path().isEmpty() ) // remote file
        return false;

    QFile file(info.path());

    if (!file.open(IO_ReadOnly))
    {
        kdDebug(7034) << "Couldn't open " << QFile::encodeName(info.path()) << endl;
        return false;
    }

    QDataStream dstream(&file);

    // AU files are big-endian
    dstream.setByteOrder(QDataStream::BigEndian);


    // Read and verify the signature
    dstream.readRawBytes(inbuf, 4);
    if (memcmp(fsig, inbuf, 4))
        return false;

    // skip unwanted bits
    file.at(8);

    // grab the bits we want
    dstream >> datasize;
    dstream >> encoding;
    dstream >> samplerate;
    dstream >> channels;

    // add the info
    KFileMetaInfoGroup group = appendGroup(info, "Technical");
    appendItem(group, "Sample Rate", (uint) samplerate);
    appendItem(group, "Channels", (uint) channels);

    // work out the encoding
    switch (encoding) {
    case 1 :
        appendItem(group, "Encoding", i18n("8-bit ISDN u-law"));
        bytespersample = 1;
        break;
    case 2 :
        appendItem(group, "Encoding", i18n("8-bit linear PCM [REF-PCM]"));
        bytespersample = 1;
        break;
    case 3 :
        appendItem(group, "Encoding", i18n("16-bit linear PCM"));
        bytespersample = 2;
        break;
    case 4 :
        appendItem(group, "Encoding", i18n("24-bit linear PCM"));
        bytespersample = 3;
        break;
    case 5 :
        appendItem(group, "Encoding", i18n("32-bit linear PCM"));
        bytespersample = 4;
        break;
    case 6 :
        appendItem(group, "Encoding", i18n("32-bit IEEE floating point"));
        bytespersample = 4;
        break;
    case 7 :
        appendItem(group, "Encoding", i18n("64-bit IEEE floating point"));
        bytespersample = 8;
        break;
    case 23 :
        appendItem(group, "Encoding", i18n("8-bit ISDN u-law compressed"));
        bytespersample = 1;
        break;
    default :
        appendItem(group, "Encoding", i18n("Unknown"));
        bytespersample = 0;
    }

    // work out length from bytespersample + channels + size
    if ((channels > 0) && (datasize > 0) && (datasize != 0xFFFFFFFF) && (bytespersample > 0) && (samplerate > 0)) {
        uint32_t length = datasize / channels / bytespersample / samplerate;
        appendItem(group, "Length", (uint) length);
    } else {
        appendItem(group, "Length", "???");
    }

    return true;
}
Beispiel #7
0
bool KigPlugin::readInfo( KFileMetaInfo& metainfo, uint /*what*/ )
{
  KFileMetaInfoGroup metagroup = appendGroup( metainfo, "KigInfo");

  QString sfile =  metainfo.path();
  bool iscompressed = false;
  QFile f( sfile );
  if ( !sfile.endsWith( ".kig", false ) )
  {
    iscompressed = true;

    QString tempdir = KGlobal::dirs()->saveLocation( "tmp" );
    if ( tempdir.isEmpty() )
      return false;

    QString tempname = sfile.section( '/', -1 );
    if ( sfile.endsWith( ".kigz", false ) )
    {
      tempname.remove( QRegExp( "\\.[Kk][Ii][Gg][Zz]$" ) );
    }
    else
      return false;
    // reading compressed file
    KTar* ark = new KTar( sfile, "application/x-gzip" );
    ark->open( IO_ReadOnly );
    const KArchiveDirectory* dir = ark->directory();
    QStringList entries = dir->entries();
    QStringList kigfiles = entries.grep( QRegExp( "\\.kig$" ) );
    if ( kigfiles.count() != 1 )
      return false;
    const KArchiveEntry* kigz = dir->entry( kigfiles[0] );
    if ( !kigz->isFile() )
      return false;
    dynamic_cast<const KArchiveFile*>( kigz )->copyTo( tempdir );

    f.setName( tempdir + kigz->name() );
  }

  if ( !f.open( IO_ReadOnly ) )
    return false;

  QDomDocument doc( "KigDocument" );
  if ( !doc.setContent( &f ) )
    return false;

  f.close();

  // removing temp file
  if ( iscompressed )
    f.remove();

  QDomElement main = doc.documentElement();

  // reading the version...
  QString version = main.attribute( "Version" );
  if ( version.isEmpty() ) version = main.attribute( "version" );
  if ( version.isEmpty() ) version = i18n( "Translators: Not Available", "n/a" );
  appendItem( metagroup, "Version", version );

  // reading the compatibility version...
  QString compatversion = main.attribute( "CompatibilityVersion" );
  if ( compatversion.isEmpty() )
    compatversion = i18n( "%1 represents Kig version",
                          "%1 (as the version)" ).arg( version );
  appendItem( metagroup, "CompatVersion", compatversion );

  // reading the Coordinate System...
  QCString coordsystem;
  for ( QDomNode n = main.firstChild(); ! n.isNull(); n = n.nextSibling() )
  {
    QDomElement e = n.toElement();
    if ( e.isNull() ) continue;
    if ( e.tagName() == "CoordinateSystem" )
      coordsystem = e.text().latin1();
  }
  appendItem( metagroup, "CoordSystem", coordsystem );

  // has Kig document the grid?
  bool btmp = true;
  QString stmp = main.attribute( "grid" );
  if ( !( stmp.isEmpty() || ( stmp != "0" ) ) )
    btmp = ( stmp != "0" );
  QString stmp2 = btmp ? i18n( "Yes" ) : i18n( "No" );
  appendItem( metagroup, "Grid", stmp2 );

  // has Kig document the axes?
  btmp = true;
  stmp = main.attribute( "axes" );
  if ( !( stmp.isEmpty() || ( stmp != "0" ) ) )
    btmp = ( stmp != "0" );
  stmp2 = btmp ? i18n( "Yes" ) : i18n( "No" );
  appendItem( metagroup, "Axes", stmp2 );

  stmp2 = iscompressed ? i18n( "Yes" ) : i18n( "No" );
  appendItem( metagroup, "Compressed", stmp2 );

  return true;
}
bool KXpsPlugin::readInfo( KFileMetaInfo& info, uint /* what */)
{
    KFileMetaInfoGroup generalGroup = appendGroup(info, "General");

    KZip *xpsArchive = new KZip( info.path() );
    if ( xpsArchive->open( IO_ReadOnly ) == true ) {
        // kdDebug(7115) << "Successful open of " << xpsArchive->fileName() << endl;
    } else {
        kDebug(7115) << "Could not open XPS archive: " << xpsArchive->fileName();
	delete xpsArchive;
	return false;
    }

    const KZipFileEntry* relFile = static_cast<const KZipFileEntry *>(xpsArchive->directory()->entry("_rels/.rels"));

    if ( !relFile ) {
        delete xpsArchive;	
        // this might occur if we can't read the zip directory, or it doesn't have the relationships entry
        return false;
    }


    if ( relFile->name().isEmpty() ) {
	delete xpsArchive;
        // this might occur if we can't read the zip directory, or it doesn't have the relationships entry
        return false;
    }

    QIODevice* relDevice = relFile->createDevice();

    QDomDocument relDom;
    QString errMsg;
    int errLine, errCol;
    if ( relDom.setContent( relDevice, true, &errMsg, &errLine, &errCol ) == false ) {
        // parse error
        kDebug(7115) << "Could not parse relationship document: " << errMsg << " : "
		     << errLine << " : " << errCol << endl;
        delete relDevice;
	delete xpsArchive;
	return false;
    }

    QDomElement docElem = relDom.documentElement();
    
    QString thumbFileName;
    QString fixedRepresentationFileName;
    QString metadataFileName;

    QDomNode n = docElem.firstChild();
    while( !n.isNull() ) {
        QDomElement e = n.toElement();
	if( !e.isNull() ) {
	    if ("http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail" == e.attribute("Type") ) {
	        thumbFileName = e.attribute("Target");
	    } else if ("http://schemas.microsoft.com/xps/2005/06/fixedrepresentation" == e.attribute("Type") ) {
	        fixedRepresentationFileName = e.attribute("Target");
	    } else if ("http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" == e.attribute("Type") ) {
	        metadataFileName = e.attribute("Target");
	    }
	}
	n = n.nextSibling();
    }

    delete relDevice;

    if ( fixedRepresentationFileName.isEmpty() ) {
	delete xpsArchive;
        // FixedRepresentation is a required part of the XPS document
        return false;
    }

    const KZipFileEntry* fixedRepFile = static_cast<const KZipFileEntry *>(xpsArchive->directory()->entry( fixedRepresentationFileName ));

    QIODevice* fixedRepDevice = fixedRepFile->createDevice();

    QDomDocument fixedRepDom;
    if ( fixedRepDom.setContent( fixedRepDevice, true, &errMsg, &errLine, &errCol ) == false ) {
        // parse error
        kDebug(7115) << "Could not parse Fixed Representation document: " << errMsg << " : "
		     << errLine << " : " << errCol << endl;
        delete fixedRepDevice;
	delete xpsArchive;
	return false;
    }

    docElem = fixedRepDom.documentElement();

    QString firstDocumentFileName;
    int numDocuments = 0; // the number of Documents in this FixedDocumentSequence

    n = docElem.firstChild();
    while( !n.isNull() ) {
        QDomElement e = n.toElement();
	if( !e.isNull() ) {
	    if (e.tagName() == "DocumentReference") {
	        if (firstDocumentFileName.isEmpty()) {
		    // we don't already have a filename, so take this one
		    firstDocumentFileName = e.attribute("Source");
		}
		numDocuments++;
	    }
	}
	n = n.nextSibling();
    }

    delete fixedRepDevice;

#if 0
    // This stuff is used for detailed parsing - not really required

    // no document? bail out here.
    if ( firstDocumentFileName.isEmpty() ) {
        return false;
    }

    KZipFileEntry* firstDocumentFile = static_cast<const KZipFileEntry *>(xpsArchive->directory()->entry( firstDocumentFileName ));

    QIODevice* firstDocumentDevice = firstDocumentFile->device();    

    QDomDocument firstDocumentDom;
    if ( firstDocumentDom.setContent( firstDocumentDevice, true, &errMsg, &errLine, &errCol ) == false ) {
        // parse error
        kDebug(7115) << "Could not parse first document: " << errMsg << " : "
		     << errLine << " : " << errCol << endl;
	return false;
    }

    n = firstDocumentDom.documentElement().firstChild();

    while( !n.isNull() ) {
        QDomElement e = n.toElement();
	if( !e.isNull() ) {
	  kDebug(7155) << "DOcument: " << e.tagName() << " : " << e.text();
	}
	n = n.nextSibling();
    }
#endif

    if ( ! metadataFileName.isEmpty() ) {
        const KZipFileEntry* corepropsFile = static_cast<const KZipFileEntry *>(xpsArchive->directory()->entry(metadataFileName));
	kDebug(7115) << "metadata file name: " << metadataFileName;

	QDomDocument metadataDocumentDom;

	QIODevice *corepropsDevice = corepropsFile->createDevice();

	if ( metadataDocumentDom.setContent( corepropsDevice, true, &errMsg, &errLine, &errCol ) == false ) {
	    // parse error
	    kDebug(7115) << "Could not parse core properties (metadata) document: " << errMsg << " : "
			 << errLine << " : " << errCol << endl;
            delete corepropsDevice;
	    delete xpsArchive;
	    return false;
	}

	n = metadataDocumentDom.documentElement().firstChild(); // the <coreProperties> level
	while( !n.isNull() ) {
	    QDomElement e = n.toElement();
	    if( !e.isNull() ) {
		if (e.tagName() == "title") {
		    appendItem(generalGroup, "Title", e.text() );
		} else if (e.tagName() == "subject") {
		    appendItem(generalGroup, "Subject", e.text() );
		} else if (e.tagName() == "description") {
		    appendItem(generalGroup, "Description", e.text() );
		} else if (e.tagName() == "creator") {
		    appendItem(generalGroup, "Author", e.text() );
		} else if (e.tagName() == "created") {
		    appendItem(generalGroup, "CreationDate", QDateTime::fromString( e.text(), "yyyy-MM-ddThh:mm:ssZ" ) );
		} else if (e.tagName() == "modified") {
		    appendItem(generalGroup, "ModificationDate", QDateTime::fromString( e.text(), "yyyy-MM-ddThh:mm:ssZ" ) );
		} else if (e.tagName() == "keywords") {
		    appendItem(generalGroup, "Keywords", e.text() );
		} else {
		    kDebug(7155) << "unhandled metadata tag: " << e.tagName() << " : " << e.text();
		}
	    }
	    n = n.nextSibling();
	}

	delete corepropsDevice;
    }

    if ( ! thumbFileName.isEmpty() ) {
        const KZipFileEntry* thumbFile = static_cast<const KZipFileEntry *>(xpsArchive->directory()->entry(thumbFileName));

	QImage img;
	img.loadFromData(thumbFile->data());

	appendItem( generalGroup, "Thumbnail", img);
	appendItem( generalGroup, "ThumbnailDimensions", QSize( img.width(), img.height() ) );
    }

    appendItem(generalGroup, "Documents", numDocuments);

    delete xpsArchive;

    return true;
}
bool KRgbPlugin::readInfo(KFileMetaInfo& info, uint /*what*/)
{
	QFile file(info.path());

	if (!file.open(QIODevice::ReadOnly)) {
		kDebug(7034) << "Couldn't open " << QFile::encodeName(info.path());
		return false;
	}

	QDataStream dstream(&file);

	quint16 magic;
	quint8  storage;
	quint8  bpc;
	quint16 dimension;
	quint16 xsize;
	quint16 ysize;
	quint16 zsize;
	quint32 pixmin;
	quint32 pixmax;
	quint32 dummy;
	char     imagename[80];
	quint32 colormap;

	dstream >> magic;
	dstream >> storage;
	dstream >> bpc;
	dstream >> dimension;
	dstream >> xsize;
	dstream >> ysize;
	dstream >> zsize;
	dstream >> pixmin;
	dstream >> pixmax;
	dstream >> dummy;
	dstream.readRawBytes(imagename, 80);
	imagename[79] = '\0';
	dstream >> colormap;
	quint8 u8;
	for (uint i = 0; i < 404; i++)
		dstream >> u8;

	if (magic != 474)
		return false;

	KFileMetaInfoGroup group;

	group = appendGroup(info, "Technical");

	if (dimension == 1)
		ysize = 1;
	appendItem(group, "Dimensions", QSize(xsize, ysize));
	appendItem(group, "BitDepth", zsize * 8 * bpc);

	if (zsize == 1)
		appendItem(group, "ColorMode", i18n("Grayscale"));
	else if (zsize == 2)
		appendItem(group, "ColorMode", i18n("Grayscale/Alpha"));
	else if (zsize == 3)
		appendItem(group, "ColorMode", i18n("RGB"));
	else if (zsize == 4)
		appendItem(group, "ColorMode", i18n("RGB/Alpha"));

	if (!storage)
		appendItem(group, "Compression", i18nc("Compression", "Uncompressed"));
	else if (storage == 1) {
		long compressed = file.size() - 512;
		long verbatim = xsize * ysize * zsize;
		appendItem(group, "Compression", i18nc("Compression", "Runlength Encoded")
				+ QString(", %1%").arg(compressed * 100.0 / verbatim, 0, 'f', 1));

		long k;
		quint32 offs;
		QMap<quint32, uint> map;
		QMap<quint32, uint>::Iterator it;
		QMap<quint32, uint>::Iterator end = map.end();
		for (k = 0; k < (ysize * zsize); k++) {
			dstream >> offs;
			if ((it = map.find(offs)) != end)
				map.insert(offs, *it + 1);
			else
				map[offs] = 0;
		}
		for (k = 0, it = map.begin(); it != end; ++it)
			k += *it;

		if (k)
			appendItem(group, "SharedRows", QString("%1%").arg(k * 100.0
					/ (ysize * zsize), 0, 'f', 1));
		else
			appendItem(group, "SharedRows", i18nc("SharedRows", "None"));
	} else