kioslave/imap4
mimeheader.cpp
00001 /*************************************************************************** 00002 mimeheader.cc - description 00003 ------------------- 00004 begin : Fri Oct 20 2000 00005 copyright : (C) 2000 by Sven Carstens 00006 email : s.carstens@gmx.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "mimeheader.h" 00019 #include "mimehdrline.h" 00020 #include "mailheader.h" 00021 00022 #include <QRegExp> 00023 00024 // #include <iostream.h> 00025 #include <kglobal.h> 00026 #include <kcomponentdata.h> 00027 #include <kiconloader.h> 00028 #include <kmimetype.h> 00029 #include <kcodecs.h> 00030 #include <kdebug.h> 00031 00032 #include <kimap/rfccodecs.h> 00033 using namespace KIMAP; 00034 00035 mimeHeader::mimeHeader () 00036 : typeList (), dispositionList (), 00037 _contentType("application/octet-stream"), 00038 _contentDisposition(), _contentDescription() 00039 { 00040 // Case insensitive hashes are killing us. Also are they too small? 00041 nestedMessage = NULL; 00042 contentLength = 0; 00043 } 00044 00045 mimeHeader::~mimeHeader () 00046 { 00047 } 00048 00049 /* 00050 QPtrList<mimeHeader> mimeHeader::getAllParts() 00051 { 00052 QPtrList<mimeHeader> retVal; 00053 00054 // caller is responsible for clearing 00055 retVal.setAutoDelete( false ); 00056 nestedParts.setAutoDelete( false ); 00057 00058 // shallow copy 00059 retVal = nestedParts; 00060 00061 // can't have duplicate pointers 00062 nestedParts.clear(); 00063 00064 // restore initial state 00065 nestedParts.setAutoDelete( true ); 00066 00067 return retVal; 00068 } */ 00069 00070 void 00071 mimeHeader::addHdrLine (mimeHdrLine * aHdrLine) 00072 { 00073 mimeHdrLine *addLine = new mimeHdrLine (aHdrLine); 00074 if (addLine) 00075 { 00076 originalHdrLines.append (addLine); 00077 if (qstrnicmp (addLine->getLabel (), "Content-", 8)) 00078 { 00079 additionalHdrLines.append (addLine); 00080 } 00081 else 00082 { 00083 int skip; 00084 const char *aCStr = addLine->getValue ().data (); 00085 QHash < QString, QString > *aList = 0; 00086 00087 skip = mimeHdrLine::parseSeparator (';', aCStr); 00088 if (skip > 0) 00089 { 00090 int cut = 0; 00091 if (skip >= 2) 00092 { 00093 if (aCStr[skip - 1] == '\r') 00094 cut++; 00095 if (aCStr[skip - 1] == '\n') 00096 cut++; 00097 if (aCStr[skip - 2] == '\r') 00098 cut++; 00099 if (aCStr[skip - 1] == ';') 00100 cut++; 00101 } 00102 QByteArray mimeValue(aCStr, skip - cut); 00103 00104 00105 if (!qstricmp (addLine->getLabel (), "Content-Disposition")) 00106 { 00107 aList = &dispositionList; 00108 setDisposition( mimeValue ); 00109 } 00110 else if (!qstricmp (addLine->getLabel (), "Content-Type")) 00111 { 00112 aList = &typeList; 00113 setType( mimeValue ); 00114 } 00115 else if (!qstricmp (addLine->getLabel (), "Content-Transfer-Encoding")) 00116 { 00117 setEncoding( mimeValue ); 00118 } 00119 else if (!qstricmp (addLine->getLabel (), "Content-ID")) 00120 { 00121 setID( mimeValue ); 00122 } 00123 else if (!qstricmp (addLine->getLabel (), "Content-Description")) 00124 { 00125 setDescription( mimeValue ); 00126 } 00127 else if (!qstricmp (addLine->getLabel (), "Content-MD5")) 00128 { 00129 setMD5( mimeValue ); 00130 } 00131 else if (!qstricmp (addLine->getLabel (), "Content-Length")) 00132 { 00133 contentLength = mimeValue.toUInt (); 00134 } 00135 else 00136 { 00137 additionalHdrLines.append (addLine); 00138 } 00139 // cout << addLine->getLabel().data() << ": '" << mimeValue.data() << "'" << endl; 00140 00141 aCStr += skip; 00142 while ((skip = mimeHdrLine::parseSeparator (';', aCStr))) 00143 { 00144 if (skip > 0) 00145 { 00146 if (aList) 00147 addParameter (QByteArray (aCStr, skip).simplified(), *aList); 00148 mimeValue = QByteArray (addLine->getValue ().data (), skip); 00149 aCStr += skip; 00150 } 00151 else 00152 break; 00153 } 00154 } 00155 } 00156 } 00157 } 00158 00159 void 00160 mimeHeader::addParameter (const QByteArray& aParameter, QHash < QString, QString > &aList) 00161 { 00162 QString aValue; 00163 QByteArray aLabel; 00164 int pos = aParameter.indexOf ('='); 00165 // cout << aParameter.left(pos).data(); 00166 aValue = QString::fromLatin1 (aParameter.right (aParameter.length () - pos - 1)); 00167 aLabel = aParameter.left (pos); 00168 if (aValue[0] == '"') 00169 aValue = aValue.mid (1, aValue.length () - 2); 00170 00171 aList.insert (aLabel.toLower(), aValue); 00172 // cout << "=" << aValue->data() << endl; 00173 } 00174 00175 QString 00176 mimeHeader::getDispositionParm (const QByteArray& aStr) 00177 { 00178 return getParameter (aStr, dispositionList); 00179 } 00180 00181 QString 00182 mimeHeader::getTypeParm (const QByteArray& aStr) 00183 { 00184 return getParameter (aStr, typeList); 00185 } 00186 00187 void 00188 mimeHeader::setDispositionParm (const QByteArray& aLabel, const QString& aValue) 00189 { 00190 setParameter (aLabel, aValue, dispositionList); 00191 return; 00192 } 00193 00194 void 00195 mimeHeader::setTypeParm (const QByteArray& aLabel, const QString& aValue) 00196 { 00197 setParameter (aLabel, aValue, typeList); 00198 } 00199 00200 QHashIterator < QString, QString > mimeHeader::getDispositionIterator () 00201 { 00202 return QHashIterator < QString, QString > (dispositionList); 00203 } 00204 00205 QHashIterator < QString, QString > mimeHeader::getTypeIterator () 00206 { 00207 return QHashIterator < QString, QString > (typeList); 00208 } 00209 00210 QListIterator < mimeHdrLine *> mimeHeader::getOriginalIterator () 00211 { 00212 return QListIterator < mimeHdrLine *> (originalHdrLines); 00213 } 00214 00215 QListIterator < mimeHdrLine *> mimeHeader::getAdditionalIterator () 00216 { 00217 return QListIterator < mimeHdrLine *> (additionalHdrLines); 00218 } 00219 00220 void 00221 mimeHeader::outputHeader (mimeIO & useIO) 00222 { 00223 if (!getDisposition ().isEmpty ()) 00224 { 00225 useIO.outputMimeLine (QByteArray ("Content-Disposition: ") 00226 + getDisposition () 00227 + outputParameter (dispositionList)); 00228 } 00229 00230 if (!getType ().isEmpty ()) 00231 { 00232 useIO.outputMimeLine (QByteArray ("Content-Type: ") 00233 + getType () + outputParameter (typeList)); 00234 } 00235 if (!getDescription ().isEmpty ()) 00236 useIO.outputMimeLine (QByteArray ("Content-Description: ") + 00237 getDescription ()); 00238 if (!getID ().isEmpty ()) 00239 useIO.outputMimeLine (QByteArray ("Content-ID: ") + getID ()); 00240 if (!getMD5 ().isEmpty ()) 00241 useIO.outputMimeLine (QByteArray ("Content-MD5: ") + getMD5 ()); 00242 if (!getEncoding ().isEmpty ()) 00243 useIO.outputMimeLine (QByteArray ("Content-Transfer-Encoding: ") + 00244 getEncoding ()); 00245 00246 QListIterator < mimeHdrLine *> ait = getAdditionalIterator (); 00247 mimeHdrLine *hdrline; 00248 while (ait.hasNext ()) 00249 { 00250 hdrline = ait.next(); 00251 useIO.outputMimeLine (hdrline->getLabel () + ": " + 00252 hdrline->getValue ()); 00253 } 00254 useIO.outputMimeLine (QByteArray ("")); 00255 } 00256 00257 QString 00258 mimeHeader::getParameter (const QByteArray& aStr, QHash < QString, QString > &aDict) 00259 { 00260 QString retVal, found; 00261 //see if it is a normal parameter 00262 found = aDict.value ( aStr ); 00263 if ( found.isEmpty() ) 00264 { 00265 //might be a continuated or encoded parameter 00266 found = aDict.value ( aStr + '*' ); 00267 if ( found.isEmpty() ) 00268 { 00269 //continuated parameter 00270 QString decoded, encoded; 00271 int part = 0; 00272 00273 do 00274 { 00275 QByteArray search; 00276 search.setNum (part); 00277 search = aStr + '*' + search; 00278 found = aDict.value (search); 00279 if ( found.isEmpty() ) 00280 { 00281 found = aDict.value (search + '*'); 00282 if ( !found.isEmpty() ) 00283 encoded += KIMAP::encodeRFC2231String (found); 00284 } 00285 else 00286 { 00287 encoded += found; 00288 } 00289 part++; 00290 } 00291 while ( !found.isEmpty() ); 00292 if (encoded.contains ('\'')) 00293 { 00294 retVal = KIMAP::decodeRFC2231String (encoded.toLocal8Bit ()); 00295 } 00296 else 00297 { 00298 retVal = 00299 KIMAP::decodeRFC2231String (QByteArray ("''") + encoded.toLocal8Bit ()); 00300 } 00301 } 00302 else 00303 { 00304 //simple encoded parameter 00305 retVal = KIMAP::decodeRFC2231String (found.toLocal8Bit ()); 00306 } 00307 } 00308 else 00309 { 00310 retVal = found; 00311 } 00312 00313 return retVal; 00314 } 00315 00316 void 00317 mimeHeader::setParameter (const QByteArray& aLabel, const QString& aValue, 00318 QHash < QString, QString > &aDict) 00319 { 00320 bool encoded = true; 00321 uint vlen, llen; 00322 QString val = aValue; 00323 00324 //see if it needs to get encoded 00325 if (encoded && !aLabel.contains('*')) 00326 { 00327 val = KIMAP::encodeRFC2231String (aValue); 00328 } 00329 //kDebug(7116) <<"mimeHeader::setParameter() - val = '" << val <<"'"; 00330 //see if it needs to be truncated 00331 vlen = val.length(); 00332 llen = aLabel.length(); 00333 if (vlen + llen + 4 > 80 && llen < 80 - 8 - 2 ) 00334 { 00335 const int limit = 80 - 8 - 2 - (int)llen; 00336 // the -2 is there to allow extending the length of a part of val 00337 // by 1 or 2 in order to prevent an encoded character from being 00338 // split in half 00339 int i = 0; 00340 QString shortValue; 00341 QByteArray shortLabel; 00342 00343 while (!val.isEmpty ()) 00344 { 00345 int partLen; // the length of the next part of the value 00346 if ( limit >= int(vlen) ) { 00347 // the rest of the value fits completely into one continued header 00348 partLen = vlen; 00349 } 00350 else { 00351 partLen = limit; 00352 // make sure that we don't split an encoded char in half 00353 if ( val[partLen-1] == '%' ) { 00354 partLen += 2; 00355 } 00356 else if ( partLen > 1 && val[partLen-2] == '%' ) { 00357 partLen += 1; 00358 } 00359 // make sure partLen does not exceed vlen (could happen in case of 00360 // an incomplete encoded char) 00361 if ( partLen > int(vlen) ) { 00362 partLen = vlen; 00363 } 00364 } 00365 shortValue = val.left( partLen ); 00366 shortLabel.setNum (i); 00367 shortLabel = aLabel + '*' + shortLabel; 00368 val = val.right( vlen - partLen ); 00369 vlen = vlen - partLen; 00370 if (encoded) 00371 { 00372 if (i == 0) 00373 { 00374 shortValue = "''" + shortValue; 00375 } 00376 shortLabel += '*'; 00377 } 00378 //kDebug(7116) <<"mimeHeader::setParameter() - shortLabel = '" << shortLabel <<"'"; 00379 //kDebug(7116) <<"mimeHeader::setParameter() - shortValue = '" << shortValue <<"'"; 00380 //kDebug(7116) <<"mimeHeader::setParameter() - val = '" << val <<"'"; 00381 aDict.insert (shortLabel.toLower(), shortValue); 00382 i++; 00383 } 00384 } 00385 else 00386 { 00387 aDict.insert (aLabel.toLower(), val); 00388 } 00389 } 00390 00391 QByteArray mimeHeader::outputParameter (QHash < QString, QString > &aDict) 00392 { 00393 QByteArray retVal; 00394 QHashIterator < QString, QString > it (aDict); 00395 while (it.hasNext ()) 00396 { 00397 it.next(); 00398 retVal += (";\n\t" + it.key() + '=').toLatin1 (); 00399 if (it.value().indexOf (' ') > 0 || it.value().indexOf (';') > 0) 00400 { 00401 retVal += '"' + it.value().toUtf8 () + '"'; 00402 } 00403 else 00404 { 00405 retVal += it.value().toUtf8 (); 00406 } 00407 } 00408 retVal += '\n'; 00409 00410 return retVal; 00411 } 00412 00413 void 00414 mimeHeader::outputPart (mimeIO & useIO) 00415 { 00416 QListIterator < mimeHeader *> nestedPartsIterator = getNestedIterator (); 00417 QByteArray boundary; 00418 if (!getTypeParm ("boundary").isEmpty ()) 00419 boundary = getTypeParm ("boundary").toLatin1 (); 00420 00421 outputHeader (useIO); 00422 if (!getPreBody ().isEmpty ()) 00423 useIO.outputMimeLine (getPreBody ()); 00424 if (getNestedMessage ()) 00425 getNestedMessage ()->outputPart (useIO); 00426 00427 mimeHeader *mimeline; 00428 while (nestedPartsIterator.hasNext()) 00429 { 00430 mimeline = nestedPartsIterator.next(); 00431 if (!boundary.isEmpty ()) 00432 useIO.outputMimeLine ("--" + boundary); 00433 mimeline->outputPart (useIO); 00434 } 00435 if (!boundary.isEmpty ()) 00436 useIO.outputMimeLine ("--" + boundary + "--"); 00437 if (!getPostBody ().isEmpty ()) 00438 useIO.outputMimeLine (getPostBody ()); 00439 } 00440 00441 #if 0 00442 int 00443 mimeHeader::parsePart (mimeIO & useIO, const QString& boundary) 00444 { 00445 int retVal = 0; 00446 bool mbox = false; 00447 QByteArray preNested, postNested; 00448 mbox = parseHeader (useIO); 00449 00450 kDebug(7116) <<"mimeHeader::parsePart - parsing part '" << getType () <<"'"; 00451 if (!qstrnicmp (getType (), "Multipart", 9)) 00452 { 00453 retVal = parseBody (useIO, preNested, getTypeParm ("boundary")); //this is a message in mime format stuff 00454 setPreBody (preNested); 00455 int localRetVal; 00456 do 00457 { 00458 mimeHeader *aHeader = new mimeHeader; 00459 00460 // set default type for multipart/digest 00461 if (!qstrnicmp (getType (), "Multipart/Digest", 16)) 00462 aHeader->setType ("Message/RFC822"); 00463 00464 localRetVal = aHeader->parsePart (useIO, getTypeParm ("boundary")); 00465 addNestedPart (aHeader); 00466 } 00467 while (localRetVal); //get nested stuff 00468 } 00469 if (!qstrnicmp (getType (), "Message/RFC822", 14)) 00470 { 00471 mailHeader *msgHeader = new mailHeader; 00472 retVal = msgHeader->parsePart (useIO, boundary); 00473 setNestedMessage (msgHeader); 00474 } 00475 else 00476 { 00477 retVal = parseBody (useIO, postNested, boundary, mbox); //just a simple part remaining 00478 setPostBody (postNested); 00479 } 00480 return retVal; 00481 } 00482 00483 int 00484 mimeHeader::parseBody (mimeIO & useIO, QByteArray & messageBody, 00485 const QString& boundary, bool mbox) 00486 { 00487 QByteArray inputStr; 00488 QByteArray buffer; 00489 QString partBoundary; 00490 QString partEnd; 00491 int retVal = 0; //default is last part 00492 00493 if (!boundary.isEmpty ()) 00494 { 00495 partBoundary = QString ("--") + boundary; 00496 partEnd = QString ("--") + boundary + "--"; 00497 } 00498 00499 while (useIO.inputLine (inputStr)) 00500 { 00501 //check for the end of all parts 00502 if (!partEnd.isEmpty () 00503 && !qstrnicmp (inputStr, partEnd.toLatin1 (), partEnd.length () - 1)) 00504 { 00505 retVal = 0; //end of these parts 00506 break; 00507 } 00508 else if (!partBoundary.isEmpty () 00509 && !qstrnicmp (inputStr, partBoundary.toLatin1 (), 00510 partBoundary.length () - 1)) 00511 { 00512 retVal = 1; //continue with next part 00513 break; 00514 } 00515 else if (mbox && inputStr.startsWith ("From ") ) 00516 { 00517 retVal = 0; // end of mbox 00518 break; 00519 } 00520 buffer += inputStr; 00521 if (buffer.length () > 16384) 00522 { 00523 messageBody += buffer; 00524 buffer = ""; 00525 } 00526 } 00527 00528 messageBody += buffer; 00529 return retVal; 00530 } 00531 #endif 00532 00533 bool mimeHeader::parseHeader (mimeIO & useIO) 00534 { 00535 bool mbox = false; 00536 bool first = true; 00537 mimeHdrLine my_line; 00538 QByteArray inputStr; 00539 00540 kDebug(7116) <<"mimeHeader::parseHeader - starting parsing"; 00541 while (useIO.inputLine (inputStr)) 00542 { 00543 int appended; 00544 if (!inputStr.startsWith("From ") || !first) //krazy:exclude=strings 00545 { 00546 first = false; 00547 appended = my_line.appendStr (inputStr); 00548 if (!appended) 00549 { 00550 addHdrLine (&my_line); 00551 appended = my_line.setStr (inputStr); 00552 } 00553 if (appended <= 0) 00554 break; 00555 } 00556 else 00557 { 00558 mbox = true; 00559 first = false; 00560 } 00561 inputStr = QByteArray(); 00562 } 00563 00564 kDebug(7116) <<"mimeHeader::parseHeader - finished parsing"; 00565 return mbox; 00566 } 00567 00568 mimeHeader * 00569 mimeHeader::bodyPart (const QString & _str) 00570 { 00571 // see if it is nested a little deeper 00572 int pt = _str.indexOf('.'); 00573 if (pt != -1) 00574 { 00575 QString tempStr = _str; 00576 mimeHeader *tempPart; 00577 00578 tempStr = _str.right (_str.length () - pt - 1); 00579 if (nestedMessage) 00580 { 00581 kDebug(7116) <<"mimeHeader::bodyPart - recursing message"; 00582 tempPart = nestedMessage->nestedParts.at (_str.left(pt).toULong() - 1); 00583 } 00584 else 00585 { 00586 kDebug(7116) <<"mimeHeader::bodyPart - recursing mixed"; 00587 tempPart = nestedParts.at (_str.left(pt).toULong() - 1); 00588 } 00589 if (tempPart) 00590 tempPart = tempPart->bodyPart (tempStr); 00591 return tempPart; 00592 } 00593 00594 kDebug(7116) <<"mimeHeader::bodyPart - returning part" << _str; 00595 // or pick just the plain part 00596 if (nestedMessage) 00597 { 00598 kDebug(7116) <<"mimeHeader::bodyPart - message"; 00599 return nestedMessage->nestedParts.at (_str.toULong () - 1); 00600 } 00601 kDebug(7116) <<"mimeHeader::bodyPart - mixed"; 00602 return nestedParts.at (_str.toULong () - 1); 00603 } 00604 00605 void mimeHeader::serialize(QDataStream& stream) 00606 { 00607 int nestedcount = nestedParts.count(); 00608 if (nestedParts.isEmpty() && nestedMessage) 00609 nestedcount = 1; 00610 stream << nestedcount; 00611 stream << _contentType; 00612 stream << QString (getTypeParm ("name")); 00613 stream << _contentDescription; 00614 stream << _contentDisposition; 00615 stream << _contentEncoding; 00616 stream << contentLength; 00617 stream << partSpecifier; 00618 // serialize nested message 00619 if (nestedMessage) 00620 nestedMessage->serialize(stream); 00621 00622 // serialize nested parts 00623 if (!nestedParts.isEmpty()) 00624 { 00625 QListIterator < mimeHeader *> it(nestedParts); 00626 mimeHeader* part; 00627 while ( it.hasNext() ) { 00628 part = it.next(); 00629 part->serialize( stream ); 00630 } 00631 } 00632 } 00633 00634 #ifdef KMAIL_COMPATIBLE 00635 // compatibility subroutines 00636 QString 00637 mimeHeader::bodyDecoded () 00638 { 00639 kDebug(7116) <<"mimeHeader::bodyDecoded"; 00640 QByteArray temp = bodyDecodedBinary (); 00641 return QString::fromLatin1 (temp.data (), temp.count ()); 00642 } 00643 00644 QByteArray 00645 mimeHeader::bodyDecodedBinary () 00646 { 00647 QByteArray retVal; 00648 00649 if (contentEncoding.startsWith (QLatin1String("quoted-printable"), Qt::CaseInsensitive) ) 00650 retVal = KCodecs::quotedPrintableDecode(postMultipartBody); 00651 else if (contentEncoding.startsWith (QLatin1String("base64"), Qt::CaseInsensitive) ) 00652 KCodecs::base64Decode(postMultipartBody, retVal); 00653 else retVal = postMultipartBody; 00654 00655 kDebug(7116) << "mimeHeader::bodyDecodedBinary - size is" << retVal.size (); 00656 return retVal; 00657 } 00658 00659 void 00660 mimeHeader::setBodyEncodedBinary (const QByteArray & _arr) 00661 { 00662 setBodyEncoded (_arr); 00663 } 00664 00665 void 00666 mimeHeader::setBodyEncoded (const QByteArray & _arr) 00667 { 00668 QByteArray setVal; 00669 00670 kDebug(7116) <<"mimeHeader::setBodyEncoded - in size" << _arr.size (); 00671 if (contentEncoding.startsWith (QLatin1String("quoted-printable"), Qt::CaseInsensitive) ) 00672 setVal = KCodecs::quotedPrintableEncode(_arr); 00673 else if (contentEncoding.startsWith (QLatin1String("base64"), Qt::CaseInsensitive) ) 00674 KCodecs::base64Encode(_arr, setVal); 00675 else 00676 setVal.duplicate (_arr); 00677 kDebug(7116) <<"mimeHeader::setBodyEncoded - out size" << setVal.size (); 00678 00679 postMultipartBody.duplicate (setVal); 00680 kDebug(7116) <<"mimeHeader::setBodyEncoded - out size" << postMultipartBody.size (); 00681 } 00682 00683 QString 00684 mimeHeader::iconName () 00685 { 00686 QString fileName = 00687 KMimeType::mimeType (contentType.toLower ())->icon (QString(), false); 00688 QString iconFileName = 00689 KGlobal::mainComponent().iconLoader ()->iconPath (fileName, KIconLoader::Desktop); 00690 // if (iconFileName.isEmpty()) 00691 // iconFileName = KGlobal::mainComponent().iconLoader()->iconPath( "unknown", KIconLoader::Desktop ); 00692 return iconFileName; 00693 } 00694 00695 void 00696 mimeHeader::setNestedMessage (mailHeader * inPart, bool destroy) 00697 { 00698 // if(nestedMessage && destroy) delete nestedMessage; 00699 nestedMessage = inPart; 00700 } 00701 00702 QString 00703 mimeHeader::headerAsString () 00704 { 00705 mimeIOQString myIO; 00706 00707 outputHeader (myIO); 00708 return myIO.getString (); 00709 } 00710 00711 QString 00712 mimeHeader::magicSetType (bool aAutoDecode) 00713 { 00714 QByteArray body; 00715 00716 if (aAutoDecode) 00717 body = bodyDecodedBinary (); 00718 else 00719 body = postMultipartBody; 00720 00721 KMimeType::Ptr mime = KMimeType::findByContent (body); 00722 QString mimetype = mime->name(); 00723 contentType = mimetype; 00724 return mimetype; 00725 } 00726 #endif
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:48:36 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Apr 30 2012 21:48:36 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.