예제 #1
0
MetaInfoMap getMetaInfo(const QString& path)
{
    KFileMetaInfo fmi(path);
    QStringList list = fmi.supportedKeys();
    QStringList::ConstIterator it = list.constBegin();
    MetaInfoMap map;

    for (; it != list.constEnd(); ++it) {
        KFileMetaInfoItem item = fmi.item(*it);
        map[*it] = item.value().toString();
    }

    return map;
}
예제 #2
0
// static helper:
// creates strings like
// "group:       translatedKey:               value"
TQString FileProps::createKeyValue( const KFileMetaInfoGroup& g,
                                   const TQString& key )
{
    static const int MAX_SPACE = 25;
    KFileMetaInfoItem item = g.item( key );

    TQString result("%1");
    result = result.arg( (item.isValid() ? item.translatedKey() : key) + ":",
                         -MAX_SPACE );
    result.append( beatifyValue( item.string() ) );

    TQString group("%1");
    group = group.arg( g.translatedName() + ":", -MAX_SPACE );
    result.prepend( group );

    return result;
}
예제 #3
0
void
MetaBundle::init( const KFileMetaInfo& info )
{
    if( info.isValid() && !info.isEmpty() )
    {
        m_artist     = info.item( "Artist" ).string();
        m_album      = info.item( "Album" ).string();
        m_year       = info.item( "Year" ).string();
        m_comment    = info.item( "Comment" ).string();
        m_genre      = info.item( "Genre" ).string();
        m_track      = info.item( "Track" ).string();
        m_bitrate    = info.item( "Bitrate" ).value().toInt();
        m_length     = info.item( "Length" ).value().toInt();
        m_sampleRate = info.item( "Sample Rate" ).value().toInt();

        // For title, check if it is valid. If not, use prettyTitle.
        // @see bug:83650
        const KFileMetaInfoItem item = info.item( "Title" );
        m_title = item.isValid() ? item.string() : prettyTitle( m_url.fileName() );

        // because whoever designed KMetaInfoItem is a donkey
        #define makeSane( x ) if( x == "---" ) x = null;
        QString null;
        makeSane( m_artist );
        makeSane( m_album );
        makeSane( m_year );
        makeSane( m_comment );
        makeSane( m_genre  );
        makeSane( m_track );
        makeSane( m_title );
        #undef makeSane

        m_isValidMedia = true;
    }
    else {
        m_bitrate = m_length = m_sampleRate = Undetermined;
        m_isValidMedia = false;
    }
}
예제 #4
0
void KFileMetaInfoWidget::init(KFileMetaInfoItem item, Mode mode)
{
    kdDebug(7033) << "*** item " << m_item.key() << " is a " << value().typeName() << endl;

    if(m_item.isEditable() && !(mode & ReadOnly))
        m_widget = makeWidget();
    else
        switch(m_value.type())
        {
            case QVariant::Image:
                m_widget = new QLabel(this, "info image");
                static_cast< QLabel * >(m_widget)->setPixmap(QPixmap(m_value.toImage()));
                break;
            case QVariant::Pixmap:
                m_widget = new QLabel(this, "info pixmap");
                static_cast< QLabel * >(m_widget)->setPixmap(m_value.toPixmap());
                break;
            default:
                m_widget = new QLabel(item.string(true), this, "info label");
        }

    (new QHBoxLayout(this))->addWidget(m_widget);
}
예제 #5
0
파일: kfileitem.cpp 프로젝트: vasi/kdelibs
QString KFileItem::getToolTipText(int maxcount) const
{
    // we can return QString() 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 QString colorName = QApplication::palette().color(QPalette::ToolTipText).name();
    const QString start = "<tr><td align=\"right\"><nobr><font color=\"" + colorName + "\"><b>";
    const QString mid = "&nbsp;</b></font></nobr></td><td><nobr><font color=\"" + colorName + "\">";
    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 = Qt::escape(mimeComment());
    if ( d->m_bLink ) {
        tip += i18n("Link to %1 (%2)", linkDest(), type) + end;
    } else
        tip += type + end;

    if ( !S_ISDIR ( d->m_fileMode ) )
        tip += start + i18n("Size:") + mid +
               QString("%1").arg(KIO::convertSize(size())) +
               end;

    tip += start + i18n("Modified:") + mid +
           timeString( KFileItem::ModificationTime ) + end
#ifndef Q_WS_WIN //TODO: show win32-specific permissions
           +start + i18n("Owner:") + mid + user() + " - " + group() + end +
           start + i18n("Permissions:") + mid +
           permissionsString() + end
#endif
           ;

    if (info.isValid())
    {
        const QStringList keys = info.preferredKeys();

        // now the rest
        QStringList::ConstIterator it = keys.begin();
        for (int count = 0; count<maxcount && it!=keys.end() ; ++it)
        {
            if ( count == 0 )
            {
                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>";
            }

            KFileMetaInfoItem item = info.item( *it );
            if ( item.isValid() )
            {
                QString s = item.value().toString();
                if ( !s.isEmpty() )
                {
                    count++;
                    tip += start +
                           Qt::escape( item.name() ) + ':' +
                           mid +
                           Qt::escape( s ) +
                           end;
                }

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

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

    return tip;
}
예제 #6
0
void KOCRBase::introduceImage( KookaImage* img)
{
    if( ! (img && img->isFileBound()) ) return;
    KFileMetaInfo info = img->fileMetaInfo();
    QStringList groups;
    if ( info.isValid() )
         groups = info.preferredGroups();

    delete m_metaBox;
    m_metaBox = new QVBox( m_imgHBox );

    /* Start to create a preview job for the thumb */
    KURL::List li(img->url());
    KIO::Job *m_job = KIO::filePreview(li, m_previewSize.width(),
                                       m_previewSize.height());

    if( m_job )
    {
        connect( m_job, SIGNAL( result( KIO::Job * )),
                 this, SLOT( slPreviewResult( KIO::Job * )));
        connect( m_job, SIGNAL( gotPreview( const KFileItem*, const QPixmap& )),
                 SLOT( slGotPreview( const KFileItem*, const QPixmap& ) ));
         /* KIO::Jo result is called in any way: Success, Failed, Error,
          * thus connecting the failed is not really necessary.
          */
    }

    for ( QStringList::Iterator it = groups.begin(); it != groups.end(); ++it )
    {
        QString theGroup(*it);

        kdDebug(29000) << "handling the group " << theGroup << endl;

        QStringList keys = info.group(theGroup).supportedKeys();

        if( keys.count() > 0 )
        {
            // info.groupInfo( theGroup )->translatedName()
            // FIXME: howto get the translated group name?
            QLabel *lGroup = new QLabel( theGroup, m_metaBox );
            lGroup->setBackgroundColor( QColor(gray));
            lGroup->setMargin( KDialog::spacingHint());

            QGrid *nGrid = new QGrid( 2,  m_metaBox );
            nGrid->setSpacing( KDialog::spacingHint());
            for ( QStringList::Iterator keyIt = keys.begin(); keyIt != keys.end(); ++keyIt )
            {
                KFileMetaInfoItem item = info.item(*keyIt);
                QString itKey = item.translatedKey();
                if( itKey.isEmpty() )
                    itKey = item.key();
                if( ! itKey.isEmpty() )
                {
                    (void) new QLabel( item.translatedKey() + ": ", nGrid );
                    (void) new QLabel( item.string(), nGrid );
                    kdDebug(29000) << "hasKey " << *keyIt << endl;
                }
            }
        }
    }
    QWidget *spaceEater = new QWidget( m_metaBox );
    spaceEater->setSizePolicy( QSizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored ));
    m_metaBox->show();
}
예제 #7
0
KFileMetaInfoWidget::KFileMetaInfoWidget(KFileMetaInfoItem item, Mode mode, QValidator *val, QWidget *parent, const char *name)
    : QWidget(parent, name), m_value(item.value()), m_item(item), m_validator(val)
{
    init(item, mode);
}
예제 #8
0
/* Check if file meets the find's requirements*/
void KQuery::processQuery( KFileItem* file)
{
  QRegExp *filename_match;

    if ( file->name() == "." || file->name() == ".." )
      return;

    bool matched=false;

    for ( filename_match = m_regexps.first(); !matched && filename_match; filename_match = m_regexps.next() )
    {
      matched |=  filename_match->isEmpty()  ||
                  (filename_match->exactMatch( file->url().fileName( true ) ) );
    }
    if (!matched)
      return;

    switch( m_sizemode )
    {
        case 1: // "at least"
            if ( file->size() < m_sizeboundary1 ) return;
            break;
        case 2: // "at most"
            if ( file->size() > m_sizeboundary1 ) return;
            break;
        case 3: // "equal"
            if ( file->size() != m_sizeboundary1 ) return;
            break;
        case 4: // "between"
            if ( (file->size() < m_sizeboundary1) || (file->size() > m_sizeboundary2) ) return;
            break;
        case 0: // "none" -> fall to default
        default:
            break;
    }

    // make sure it's in the correct date range
    // what about 0 times?
    if ( m_timeFrom && m_timeFrom > file->time(KIO::UDS_MODIFICATION_TIME) )
      return;
    if ( m_timeTo && m_timeTo < file->time(KIO::UDS_MODIFICATION_TIME) )
      return;

    // username / group match
    if ( (!m_username.isEmpty()) && (m_username != file->user()) )
       return;
    if ( (!m_groupname.isEmpty()) && (m_groupname != file->group()) )
       return;

    // file type
    switch (m_filetype)
    {
      case 0:
        break;
      case 1: // plain file
        if ( !S_ISREG( file->mode() ) )
          return;
        break;
      case 2:
        if ( !file->isDir() )
          return;
        break;
      case 3:
        if ( !file->isLink() )
          return;
        break;
      case 4:
        if ( !S_ISCHR ( file->mode() ) && !S_ISBLK ( file->mode() ) &&
              !S_ISFIFO( file->mode() ) && !S_ISSOCK( file->mode() ) )
              return;
        break;
      case 5: // binary
        if ( (file->permissions() & 0111) != 0111 || file->isDir() )
          return;
        break;
      case 6: // suid
        if ( (file->permissions() & 04000) != 04000 ) // fixme
          return;
        break;
      default:
        if (!m_mimetype.isEmpty() && !m_mimetype.contains(file->mimetype()))
          return;
    }

    // match datas in metainfo...
    if ((!m_metainfo.isEmpty())  && (!m_metainfokey.isEmpty()))
    {
       bool foundmeta=false;
       QString filename = file->url().path();

       if(filename.startsWith("/dev/"))
          return;

       KFileMetaInfo metadatas(filename);
       KFileMetaInfoItem metaitem;
       QStringList metakeys;
       QString strmetakeycontent;

       if(metadatas.isEmpty())
          return;

       metakeys=metadatas.supportedKeys();
       for ( QStringList::Iterator it = metakeys.begin(); it != metakeys.end(); ++it )
       {
          if (!metaKeyRx->exactMatch(*it))
             continue;
          metaitem=metadatas.item(*it);
          strmetakeycontent=metaitem.string();
          if(strmetakeycontent.find(m_metainfo)!=-1)
          {
             foundmeta=true;
             break;
          }
       }
       if (!foundmeta)
          return;
    }

    // match contents...
    QString matchingLine;
    if (!m_context.isEmpty())
    {

       if( !m_search_binary && ignore_mimetypes.findIndex(file->mimetype()) != -1 ) {
         kdDebug() << "ignoring, mime type is in exclusion list: " << file->url() << endl;
         return;
       }

       bool found = false;
       bool isZippedOfficeDocument=false;
       int matchingLineNumber=0;

       // FIXME: doesn't work with non local files

       QString filename;
       QTextStream* stream=0;
       QFile qf;
       QRegExp xmlTags;
       QByteArray zippedXmlFileContent;

       // KWord's and OpenOffice.org's files are zipped...
       if( ooo_mimetypes.findIndex(file->mimetype()) != -1 ||
           koffice_mimetypes.findIndex(file->mimetype()) != -1 )
       {
         KZip zipfile(file->url().path());
         KZipFileEntry *zipfileEntry;

         if(zipfile.open(IO_ReadOnly))
         {
           const KArchiveDirectory *zipfileContent = zipfile.directory();

           if( koffice_mimetypes.findIndex(file->mimetype()) != -1 )
             zipfileEntry = (KZipFileEntry*)zipfileContent->entry("maindoc.xml");
           else
             zipfileEntry = (KZipFileEntry*)zipfileContent->entry("content.xml"); //for OpenOffice.org

           if(!zipfileEntry) {
             kdWarning() << "Expected XML file not found in ZIP archive " << file->url() << endl;
             return;
           }

           zippedXmlFileContent = zipfileEntry->data();
           xmlTags.setPattern("<.*>");
           xmlTags.setMinimal(true);
           stream = new QTextStream(zippedXmlFileContent, IO_ReadOnly);
           stream->setEncoding(QTextStream::UnicodeUTF8);
           isZippedOfficeDocument = true;
         } else {
           kdWarning() << "Cannot open supposed ZIP file " << file->url() << endl;
         }
       } else if( !m_search_binary && !file->mimetype().startsWith("text/") &&
           file->url().isLocalFile() ) {
         KMimeType::Format f = KMimeType::findFormatByFileContent(file->url().path());
         if ( !f.text ) {
           kdDebug() << "ignoring, not a text file: " << file->url() << endl;
           return;
         }
       }

       if(!isZippedOfficeDocument) //any other file or non-compressed KWord
       {
         filename = file->url().path();
         if(filename.startsWith("/dev/"))
            return;
         qf.setName(filename);
         qf.open(IO_ReadOnly);
         stream=new QTextStream(&qf);
         stream->setEncoding(QTextStream::Locale);
       }

       while ( ! stream->atEnd() )
       {
          QString str = stream->readLine();
          matchingLineNumber++;

          if (str.isNull()) break;
          if(isZippedOfficeDocument)
            str.replace(xmlTags, "");

          if (m_regexpForContent)
          {
             if (m_regexp.search(str)>=0)
             {
                matchingLine=QString::number(matchingLineNumber)+": "+str;
                found = true;
                break;
             }
          }
          else
          {
             if (str.find(m_context, 0, m_casesensitive) != -1)
             {
                matchingLine=QString::number(matchingLineNumber)+": "+str;
                found = true;
                break;
             }
          }
          kapp->processEvents();
       }
       delete stream;

       if (!found)
          return;
    }
    emit addFile(file,matchingLine);
}
예제 #9
0
void ThumbnailProtocol::get(const KURL &url)
{
    m_mimeType = metaData("mimeType");
    kdDebug(7115) << "Wanting MIME Type:" << m_mimeType << endl;
#ifdef THUMBNAIL_HACK
    // ### HACK
    bool direct=false;
    if (m_mimeType.isEmpty())
    {
        kdDebug(7115) << "PATH: " << url.path() << endl;
        TQFileInfo info(url.path());
        if (info.isDir())
        {
            // We cannot process a directory
            error(TDEIO::ERR_IS_DIRECTORY,url.path());
            return;
        }
        else if (!info.exists())
        {
            // The file does not exist
            error(TDEIO::ERR_DOES_NOT_EXIST,url.path());
            return;
        }
        else if (!info.isReadable())
        {
            // The file is not readable!
            error(TDEIO::ERR_COULD_NOT_READ,url.path());
            return;
        }
        m_mimeType = KMimeType::findByURL(url)->name();
        kdDebug(7115) << "Guessing MIME Type:" << m_mimeType << endl;
        direct=true; // thumbnail: was probably called from Konqueror
    }
#endif

    if (m_mimeType.isEmpty())
    {
        error(TDEIO::ERR_INTERNAL, i18n("No MIME Type specified."));
        return;
    }

    m_width = metaData("width").toInt();
    m_height = metaData("height").toInt();
    int iconSize = metaData("iconSize").toInt();

    if (m_width < 0 || m_height < 0)
    {
        error(TDEIO::ERR_INTERNAL, i18n("No or invalid size specified."));
        return;
    }
#ifdef THUMBNAIL_HACK
    else if (!m_width || !m_height)
    {
        kdDebug(7115) << "Guessing height, width, icon size!" << endl;
        m_width=128;
        m_height=128;
        iconSize=128;
    }
#endif

    if (!iconSize)
        iconSize = TDEGlobal::iconLoader()->currentSize(TDEIcon::Desktop);
    if (iconSize != m_iconSize)
        m_iconDict.clear();
    m_iconSize = iconSize;

    m_iconAlpha = metaData("iconAlpha").toInt();
    if (m_iconAlpha)
        m_iconAlpha = (m_iconAlpha << 24) | 0xffffff;

    TQImage img;

    TDEConfigGroup group( TDEGlobal::config(), "PreviewSettings" );

    
    // ### KFMI
    bool kfmiThumb = false;
    if (group.readBoolEntry( "UseFileThumbnails", true )) {
        KService::Ptr service =
            KServiceTypeProfile::preferredService( m_mimeType, "KFilePlugin");

        if ( service && service->isValid() && /*url.isLocalFile() && */
            service->property("SupportsThumbnail").toBool())
        {
            KFileMetaInfo info(url.path(), m_mimeType, KFileMetaInfo::Thumbnail);
            if (info.isValid())
            {
                KFileMetaInfoItem item = info.item(KFileMimeTypeInfo::Thumbnail);
                if (item.isValid() && item.value().type() == TQVariant::Image)
                {
                    img = item.value().toImage();
                    kdDebug(7115) << "using KFMI for the thumbnail\n";
                    kfmiThumb = true;
                }
            }
        }
    }
    ThumbCreator::Flags flags = ThumbCreator::None;

    if (!kfmiThumb)
    {
        kdDebug(7115) << "using thumb creator for the thumbnail\n";
        TQString plugin = metaData("plugin");
#ifdef THUMBNAIL_HACK
        if (plugin.isEmpty())
        {
            TDETrader::OfferList plugins = TDETrader::self()->query("ThumbCreator");
            TQMap<TQString, KService::Ptr> mimeMap;
    
            for (TDETrader::OfferList::ConstIterator it = plugins.begin(); it != plugins.end(); ++it)
            {
                TQStringList mimeTypes = (*it)->property("MimeTypes").toStringList();
                for (TQStringList::ConstIterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt)
                {
                    if  ((*mt)==m_mimeType)
                    {
                        plugin=(*it)->library();
                        break;
                    }
                }
                if (!plugin.isEmpty())
                    break;
            }
        }
        kdDebug(7115) << "Guess plugin: " << plugin << endl;
#endif
        if (plugin.isEmpty())
        {
            error(TDEIO::ERR_INTERNAL, i18n("No plugin specified."));
            return;
        }
        
        ThumbCreator *creator = m_creators[plugin];
        if (!creator)
        {
            // Don't use KLibFactory here, this is not a TQObject and
            // neither is ThumbCreator
            KLibrary *library = KLibLoader::self()->library(TQFile::encodeName(plugin));
            if (library)
            {
                newCreator create = (newCreator)library->symbol("new_creator");
                if (create)
                    creator = create();
            }
            if (!creator)
            {
                error(TDEIO::ERR_INTERNAL, i18n("Cannot load ThumbCreator %1").arg(plugin));
                return;
            }
            m_creators.insert(plugin, creator);
        }

        if (!creator->create(url.path(), m_width, m_height, img))
        {
            error(TDEIO::ERR_INTERNAL, i18n("Cannot create thumbnail for %1").arg(url.path()));
            return;
        }
        flags = creator->flags();
    }

    if (img.width() > m_width || img.height() > m_height)
    {
        double imgRatio = (double)img.height() / (double)img.width();
        if (imgRatio > (double)m_height / (double)m_width)
            img = img.smoothScale( int(TQMAX((double)m_height / imgRatio, 1)), m_height);
        else
            img = img.smoothScale(m_width, int(TQMAX((double)m_width * imgRatio, 1)));
    }

// ### FIXME
#ifndef USE_KINSTANCE
    if (flags & ThumbCreator::DrawFrame)
    {
        TQPixmap pix;
        pix.convertFromImage(img);
        int x2 = pix.width() - 1;
        int y2 = pix.height() - 1;
        // paint a black rectangle around the "page"
        TQPainter p;
        p.begin( &pix );
        p.setPen( TQColor( 48, 48, 48 ));
        p.drawLine( x2, 0, x2, y2 );
        p.drawLine( 0, y2, x2, y2 );
        p.setPen( TQColor( 215, 215, 215 ));
        p.drawLine( 0, 0, x2, 0 );
        p.drawLine( 0, 0, 0, y2 );
        p.end();

        const TQBitmap *mask = pix.mask();
        if ( mask ) // need to update it so we can see the frame
        {
            TQBitmap bitmap( *mask );
            TQPainter painter;
            painter.begin( &bitmap );
            painter.drawLine( x2, 0, x2, y2 );
            painter.drawLine( 0, y2, x2, y2 );
            painter.drawLine( 0, 0, x2, 0 );
            painter.drawLine( 0, 0, 0, y2 );
            painter.end();

            pix.setMask( bitmap );
        }

        img = pix.convertToImage();
    }
#endif

    if ((flags & ThumbCreator::BlendIcon) && TDEGlobal::iconLoader()->alphaBlending(TDEIcon::Desktop))
    {
        // blending the mimetype icon in
        TQImage icon = getIcon();

        int x = img.width() - icon.width() - 4;
        x = TQMAX( x, 0 );
        int y = img.height() - icon.height() - 6;
        y = TQMAX( y, 0 );
        KImageEffect::blendOnLower( x, y, icon, img );
    }

    if (img.isNull())
    {
        error(TDEIO::ERR_INTERNAL, i18n("Failed to create a thumbnail."));
        return;
    }

    const TQString shmid = metaData("shmid");
    if (shmid.isEmpty())
    {
#ifdef THUMBNAIL_HACK
        if (direct)
        {
            // If thumbnail was called directly from Konqueror, then the image needs to be raw
            //kdDebug(7115) << "RAW IMAGE TO STREAM" << endl;
            TQBuffer buf;
            if (!buf.open(IO_WriteOnly))
            {
                error(TDEIO::ERR_INTERNAL, i18n("Could not write image."));
                return;
            }
            img.save(&buf,"PNG");
            buf.close();
            data(buf.buffer());
        }
        else
#endif
        {
            TQByteArray imgData;
            TQDataStream stream( imgData, IO_WriteOnly );
            //kdDebug(7115) << "IMAGE TO STREAM" << endl;
            stream << img;
            data(imgData);
        }
    }
    else
    {
        TQByteArray imgData;
        TQDataStream stream( imgData, IO_WriteOnly );
        //kdDebug(7115) << "IMAGE TO SHMID" << endl;
        void *shmaddr = shmat(shmid.toInt(), 0, 0);
        if (shmaddr == (void *)-1)
        {
            error(TDEIO::ERR_INTERNAL, i18n("Failed to attach to shared memory segment %1").arg(shmid));
            return;
        }
        if (img.width() * img.height() > m_width * m_height)
        {
            error(TDEIO::ERR_INTERNAL, i18n("Image is too big for the shared memory segment"));
            shmdt((char*)shmaddr);
            return;
        }
        if( img.depth() != 32 )           // TDEIO::PreviewJob and this code below completely
            img = img.convertDepth( 32 ); // ignores colortable :-/, so make sure there is none
        stream << img.width() << img.height() << img.depth()
               << img.hasAlphaBuffer();
        memcpy(shmaddr, img.bits(), img.numBytes());
        shmdt((char*)shmaddr);
        data(imgData);
    }
    finished();
}
예제 #10
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;
}