void RTFGenParser::tag_end(const QString &tagName) { // Roll back until we find our tag. bool found = false; for(Tag* pTag = m_tags.peek(); pTag != NULL && !found; pTag = m_tags.peek()) { if (pTag->name == tagName) { found = true; } if (pTag->hasCharStyle()) { CharStyle style = *(pTag->pCharStyle); // We must pop here, so that getTopTagWithCharStyle will find a parent tag. m_tags.pop(); pTag = NULL; // to avoid confusion Tag* pParentTag = m_tags.getTopTagWithCharStyle(); if (pParentTag != NULL) { if (pParentTag->hasCharStyle()) { CharStyle* pParentStyle = pParentTag->pCharStyle; // Roll back the character style. This is regardless of whether // we found the closed tag; we just collapse all styles on our way. QString rtf = pParentStyle->getDiffRTF(style); if (!rtf.isEmpty()) { res += rtf.utf8(); m_bSpace = true; } } } } else // if this tag has no char style attached { m_tags.pop(); // just pop the tag out pTag = NULL; // to avoid confusion } if (found) { if (tagName.lower() == "p") { res += "\\par"; m_bSpace = true; } } } }
string RTFGenParser::parse(const QString &text) { res = ""; m_res_size = 0; m_codec = getContacts()->getCodec(m_contact); int charset = 0; for (const ENCODING *c = getContacts()->getEncodings(); c->language; c++){ if (!strcasecmp(c->codec, m_codec->name())){ charset = c->rtf_code; break; } } #ifdef WIN32 if ((charset == 0) && !strcasecmp(m_codec->name(), "system")){ char buff[256]; int res = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE, (char*)&buff, sizeof(buff)); if (res){ unsigned codepage = atol(buff); if (codepage){ for (const rtf_cp *c = rtf_cps; c->cp; c++){ if (c->cp == codepage) charset = c->charset; } } } } #endif unsigned ansicpg = 0; const char *send_encoding = 0; m_codec = NULL; if (charset){ for (const ENCODING *c = getContacts()->getEncodings(); c->language; c++){ if ((c->rtf_code == charset) && c->bMain){ send_encoding = c->codec; m_codec = getContacts()->getCodecByName(send_encoding); ansicpg = c->cp_code; break; } } } // Add defaults to the tables m_fontFaces.push_back("MS Sans Serif"); m_colors.push_back(m_foreColor); // Create a "fake" tag which'll serve as the default style CharStyle style; style.faceIdx = 0; style.colorIdx = 1; // colors are 1-based (0 = default) style.sizePt = 12; // default according to Microsoft Tag& tag = *(m_tags.pushNew()); tag.setCharStyle(style); // Assume we go immediately after a tag. m_bSpace = true; HTMLParser::parse(text); string s; s = "{\\rtf1\\ansi"; if (ansicpg){ s += "\\ansicpg"; s += number(ansicpg); } s += "\\deff0\r\n"; s += "{\\fonttbl"; unsigned n = 0; for (list<QString>::iterator it_face = m_fontFaces.begin(); it_face != m_fontFaces.end(); it_face++, n++){ s += "{\\f"; s += number(n); QString face = (*it_face); if (face.find("Times") >= 0){ s += "\\froman"; }else if (face.find("Courier") >= 0){ s += "\\fmodern"; }else{ s += "\\fswiss"; } if (charset){ s += "\\fcharset"; s += number(charset); } s += " "; int pos = face.find(QRegExp(" +[")); if (pos > 0) face = face.left(pos); s += static_cast<string>(face.toLatin1()); s += ";}"; } s += "}\r\n"; s += "{\\colortbl ;"; for (list<QColor>::iterator it_colors = m_colors.begin(); it_colors != m_colors.end(); ++it_colors){ QColor c = *it_colors; s += "\\red"; s += number(c.red()); s += "\\green"; s += number(c.green()); s += "\\blue"; s += number(c.blue()); s += ";"; } s += "}\r\n"; s += "\\viewkind4\\pard"; s += static_cast<string>(style.getDiffRTF(CharStyle()).toUtf8()); s += res; s += "\r\n}\r\n"; log(L_DEBUG, "Resulting RTF: %s", s.c_str()); return s; }