Ejemplo n.º 1
0
void TextDocumentModel::fillBlock(const QTextBlock &block, QStandardItem *parent)
{
    for (auto it = block.begin(); it != block.end(); ++it) {
        QStandardItem *item = new QStandardItem(tr("Fragment: %1").arg(it.fragment().text()));
        const QRectF b = m_document->documentLayout()->blockBoundingRect(block);
        appendRow(parent, item, it.fragment().charFormat(), b);
        if (!block.layout())
            continue;
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
        foreach (const auto &range, block.layout()->formats()) {
            const auto start = std::max(range.start, it.fragment().position() - block.position());
            const auto end = std::min(range.start + range.length,
                                      it.fragment().position() + it.fragment().length()
                                      - block.position());
            if (start >= end)
                continue;
            auto child
                = new QStandardItem(tr("Layout Range: %1").arg(it.fragment().text().mid(start,
                                                                                        end
                                                                                        -start)));
            appendRow(item, child, range.format, QRectF());
        }
#endif
    }
}
Ejemplo n.º 2
0
    virtual void visitBlock(QTextBlock &block, const QTextCursor &caret)
    {
        m_formats.clear();
        m_cursors.clear();

        for (QTextBlock::iterator it = block.begin(); it != block.end(); ++it) {
            QTextCursor fragmentSelection(caret);
            fragmentSelection.setPosition(it.fragment().position());
            fragmentSelection.setPosition(it.fragment().position() + it.fragment().length(), QTextCursor::KeepAnchor);

            if (fragmentSelection.anchor() >= fragmentSelection.position()) {
                continue;
            }

            visitFragmentSelection(fragmentSelection);
        }

        QTextCursor cursor(caret);
        cursor.mergeBlockFormat(m_deltaBlockFormat);
        cursor.mergeBlockCharFormat(m_deltaCharFormat);

        QList<QTextCharFormat>::Iterator it = m_formats.begin();
        foreach(QTextCursor cursor, m_cursors) {
            cursor.setCharFormat(*it);
            ++it;
        }
Ejemplo n.º 3
0
void TextDocumentModel::fillBlock(const QTextBlock &block, QStandardItem *parent)
{
  for (QTextBlock::iterator it = block.begin(); it != block.end(); ++it) {
    QStandardItem *item = new QStandardItem(tr("Fragment: %1").arg(it.fragment().text()));
    const QRectF b = m_document->documentLayout()->blockBoundingRect(block);
    appendRow(parent, item, it.fragment().charFormat(), b);
  }
}
Ejemplo n.º 4
0
QString Text::extractSanitizedText(int from, int to) const
{
    if (!doc)
        return "";

    QString txt;

    QTextBlock begin = doc->findBlock(from);
    QTextBlock end = doc->findBlock(to);
    for (QTextBlock block = begin; block != end.next() && block.isValid(); block = block.next()) {
        for (QTextBlock::Iterator itr = block.begin(); itr != block.end(); ++itr) {
            int pos =
                itr.fragment()
                    .position(); // fragment position -> position of the first character in the fragment

            if (itr.fragment().charFormat().isImageFormat()) {
                QTextImageFormat imgFmt = itr.fragment().charFormat().toImageFormat();
                QString key = imgFmt.name(); // img key (eg. key::D for :D)
                QString rune = key.mid(4);

                if (pos >= from && pos < to) {
                    txt += rune;
                    ++pos;
                }
            } else {
                for (QChar c : itr.fragment().text()) {
                    if (pos >= from && pos < to)
                        txt += c;

                    ++pos;
                }
            }
        }

        txt += '\n';
    }

    txt.chop(1);

    return txt;
}
Ejemplo n.º 5
0
    virtual void visitBlock(QTextBlock &block, const QTextCursor &caret)
    {
        for (QTextBlock::iterator it = block.begin(); it != block.end(); ++it) {
            QTextCursor fragmentSelection(caret);
            fragmentSelection.setPosition(it.fragment().position());
            fragmentSelection.setPosition(it.fragment().position() + it.fragment().length(), QTextCursor::KeepAnchor);

            if (fragmentSelection.anchor() >= fragmentSelection.position()) {
                continue;
            }

            visitFragmentSelection(fragmentSelection);
        }

        QList<QTextCharFormat>::Iterator it = m_formats.begin();
        Q_FOREACH (QTextCursor cursor, m_cursors) {
            QTextFormat prevFormat(cursor.charFormat());
            cursor.setCharFormat(*it);
            editor()->registerTrackedChange(cursor, KoGenChange::FormatChange, kundo2_i18n("Formatting"), *it, prevFormat, false);
            ++it;
        }
Ejemplo n.º 6
0
void ContactListEdit::GetCollectedContacts(IMailProcessor::TRecipientPublicKeys* storage) const
  {
  assert(storage != nullptr);
  storage->reserve(10);

  QTextBlock block = document()->begin();
  while(block.isValid())
    {
    for(QTextBlock::iterator i = block.begin(); i != block.end(); ++i)
      {
      QTextCharFormat format = i.fragment().charFormat();
      if(format.isImageFormat())
        {
        QTextImageFormat imgF = format.toImageFormat();
        IMailProcessor::TRecipientPublicKey pk;
        decodePublicKey(imgF, &pk);
        assert(pk.valid());
        storage->push_back(pk);
        }
      }

    block = block.next();
    }
  }
Ejemplo n.º 7
0
bool RTF::Writer::write(QIODevice* device, QTextDocument* text)
{
	if (m_codec == 0) {
		return false;
	}

	device->write(m_header);

	for (QTextBlock block = text->begin(); block.isValid(); block = block.next()) {
		QByteArray par("{\\pard\\plain");
		QTextBlockFormat block_format = block.blockFormat();
		bool rtl = block_format.layoutDirection() == Qt::RightToLeft;
		if (rtl) {
			par += "\\rtlpar";
		}
		Qt::Alignment align = block_format.alignment();
		if (rtl && (align & Qt::AlignLeft)) {
			par += "\\ql";
		} else if (align & Qt::AlignRight) {
			par += "\\qr";
		} else if (align & Qt::AlignCenter) {
			par += "\\qc";
		} else if (align & Qt::AlignJustify) {
			par += "\\qj";
		}
		if (block_format.indent() > 0) {
			par += "\\li" + QByteArray::number(block_format.indent() * 15);
		}
		device->write(par);

		if (block.begin() != block.end()) {
			device->write(" ");
			for (QTextBlock::iterator iter = block.begin(); iter != block.end(); ++iter) {
				QTextFragment fragment = iter.fragment();
				QTextCharFormat char_format = fragment.charFormat();
				QByteArray style;
				if (char_format.fontWeight() == QFont::Bold) {
					style += "\\b";
				}
				if (char_format.fontItalic()) {
					style += "\\i";
				}
				if (char_format.fontUnderline()) {
					style += "\\ul";
				}
				if (char_format.fontStrikeOut()) {
					style += "\\strike";
				}
				if (char_format.verticalAlignment() == QTextCharFormat::AlignSuperScript) {
					style += "\\super";
				} else if (char_format.verticalAlignment() == QTextCharFormat::AlignSubScript) {
					style += "\\sub";
				}

				if (!style.isEmpty()) {
					device->write("{" + style + " " + fromUnicode(fragment.text()) + "}");
				} else {
					device->write(fromUnicode(fragment.text()));
				}
			}
		}

		device->write("\\par}\n");
	}

	device->write("\n}");
	return true;
}
Ejemplo n.º 8
0
void TextContent::updateTextConstraints()
{
    // 1. actual content stretch
    double prevXScale = 1.0;
    double prevYScale = 1.0;
   /* if (m_textRect.width() > 0 && m_textRect.height() > 0) {
        QRect cRect = contentRect();
        prevXScale = (qreal)cRect.width() / (qreal)m_textRect.width();
        prevYScale = (qreal)cRect.height() / (qreal)m_textRect.height();
    }*/

    // 2. LAYOUT TEXT. find out Block rects and Document rect
    int minCharSide = 0;
    m_blockRects.clear();
    m_textRect = QRect(0, 0, 0, 0);
    for (QTextBlock tb = m_text->begin(); tb.isValid(); tb = tb.next()) {
        if (!tb.isVisible())
            continue;

        // 2.1.A. calc the Block size uniting Fragments bounding rects
        QRect blockRect(0, 0, 0, 0);
        for (QTextBlock::iterator tbIt = tb.begin(); !(tbIt.atEnd()); ++tbIt) {
            QTextFragment frag = tbIt.fragment();
            if (!frag.isValid())
                continue;

            QString text = frag.text();
            if (text.trimmed().isEmpty())
                continue;

            QFontMetrics metrics(frag.charFormat().font());
            if (!minCharSide || metrics.height() > minCharSide)
                minCharSide = metrics.height();

            // TODO: implement superscript / subscript (it's in charFormat's alignment)
            // it must be implemented in paint too

            QRect textRect = metrics.boundingRect(text);
            if (textRect.left() > 9999)
                continue;
            if (textRect.top() < blockRect.top())
                blockRect.setTop(textRect.top());
            if (textRect.bottom() > blockRect.bottom())
                blockRect.setBottom(textRect.bottom());

            int textWidth = metrics.width(text);
            blockRect.setWidth(blockRect.width() + textWidth);
        }
        // 2.1.B. calc the Block size of blank lines
        if (tb.begin() == tb.end()) {
            QFontMetrics metrics(tb.charFormat().font());
            int textHeight = metrics.height();
            blockRect.setWidth(1);
            blockRect.setHeight(textHeight);
        }

        // 2.2. add the Block's margins
        QTextBlockFormat tbFormat = tb.blockFormat();
        blockRect.adjust(-tbFormat.leftMargin(), -tbFormat.topMargin(), tbFormat.rightMargin(), tbFormat.bottomMargin());

        // 2.3. store the original block rect
        m_blockRects.append(blockRect);

        // 2.4. enlarge the Document rect (uniting the Block rect)
        blockRect.translate(0, m_textRect.bottom() - blockRect.top() + 1);
        if (blockRect.left() < m_textRect.left())
            m_textRect.setLeft(blockRect.left());
        if (blockRect.right() > m_textRect.right())
            m_textRect.setRight(blockRect.right());
        if (blockRect.top() < m_textRect.top())
            m_textRect.setTop(blockRect.top());
        if (blockRect.bottom() > m_textRect.bottom())
            m_textRect.setBottom(blockRect.bottom());
    }
    m_textRect.adjust(-m_textMargin, -m_textMargin, m_textMargin, m_textMargin);

    // 3. use shape-based rendering
    if (hasShape()) {
#if 1
        // more precise, but too close to the path
        m_shapeRect = m_shapePath.boundingRect().toRect();
#else
        // faster, but less precise (as it uses the controls points to determine
        // the path rect, instead of the path itself)
        m_shapeRect = m_shapePath.controlPointRect().toRect();
#endif
        minCharSide = qBound(10, minCharSide, 500);
        m_shapeRect.adjust(-minCharSide, -minCharSide, minCharSide, minCharSide);

        // FIXME: layout, save layouting and calc the exact size!
        //int w = m_shapeRect.width();
        //int h = m_shapeRect.height();
        //resizeContents(QRect(-w / 2, -h / 2, w, h));
        resizeContents(m_shapeRect);

  //      moveBy(m_shapeRect.left(), m_shapeRect.top());
//        m_shapePath.translate(-m_shapeRect.left(), -m_shapeRect.top());
        //setPos(m_shapeRect.center());
        return;
    }

    // 4. resize content keeping stretch
    int w = (int)(prevXScale * (qreal)m_textRect.width());
    int h = (int)(prevYScale * (qreal)m_textRect.height());
    resizeContents(QRect(-w / 2, -h / 2, w, h));
}
Ejemplo n.º 9
0
QString Format::frameToString( QTextFrame *frame )
{
  QString out;

  QTextFrame::iterator it;
  for( it = frame->begin(); it != frame->end(); ++it ) {
    QTextBlock block = it.currentBlock();
    if ( block.isValid() ) {
      out += "<block";

      QTextCursor c( block );

      QDateTime dt = TextFormats::lastModified( c );
      if ( dt.isValid() ) {
        out += " lastmodified=\"" + dt.toString( Qt::ISODate ) + "\"";
      }

      if ( TextFormats::isTitle( c ) ) {
        out += " titlestyle=\"title\"";
      } else if ( TextFormats::isSubTitle( c ) ) {
        out += " titlestyle=\"subtitle\"";
      }

      QTextBlockFormat blockFormat = block.blockFormat();
      if ( blockFormat.isValid() ) {
        QTextList *list = block.textList();
        if ( list ) {
          QTextListFormat f = list->format();
          out += " liststyle=\"";
          switch( f.style() ) {
            default:
            case QTextListFormat::ListDisc:
              out += "disc";
              break;
            case QTextListFormat::ListDecimal:
              out += "decimal";
              break;
          }
          out += "\"";

          out += " listindent=\"" + QString::number( f.indent() ) + "\"";
        } else {
          if ( blockFormat.indent() != 0 ) {
            out += " blockindent=\"" + QString::number( blockFormat.indent() ) +
              "\"";
          }
        }
      }

      out += ">\n";
      
      QTextBlock::iterator it2;
      for( it2 = block.begin(); it2 != block.end(); ++it2 ) {
        QTextFragment fragment = it2.fragment();
        if ( !fragment.isValid() ) continue;

        QString text = fragment.text();

        QString outText;
        for( int i = 0; i < text.size(); ++i ) {
          if ( text.at( i ) == 0xfffc ) {
            outText += "<todo status=\"";

            QTextImageFormat imageFormat = fragment.charFormat().toImageFormat();
            if ( imageFormat.isValid() ) {
              if ( imageFormat.name().contains( "done" ) ) outText += "done";
              else outText += "todo";
            } else {
              dbg() << "NO IMAGE FORMAT" << endl;
            }
            
            outText += "\"/>";
          } else {
            outText += escape( QString( text.at( i ) ) );
          }
        }

        out += "  <fragment";

        QTextCharFormat format = fragment.charFormat();
        if ( !format.anchorHref().isEmpty() ) {
          out += " link=\"" + escape( format.anchorHref() ) + "\"";
        }
        if ( format.fontWeight() == QFont::Bold ) {
          out += " bold=\"true\"";
        }
        if ( format.fontItalic() ) {
          out += " italic=\"true\"";
        }
        if ( format.hasProperty( QTextFormat::FontPointSize ) &&
             format.fontPointSize() != 10 ) {
          out += " fontsize=\"" + QString::number( format.fontPointSize() ) +
            "\"";
        }

        if ( outText.trimmed().isEmpty() ) outText.replace( " ", "[FIXME:space]" );

        out += ">" + outText + "</fragment>\n";
      }
      
      out += "</block>";

      out += "\n";
    }
    QTextFrame *f = it.currentFrame();
    if ( f ) {
      QTextFrameFormat format = f->frameFormat();
      out += "<frame";
      if ( format.hasProperty( TextFormats::FrameType ) ) {
        out += " type=";
        if ( format.property( TextFormats::FrameType ) == TextFormats::CodeFrame ) {
          out += "\"code\"";
        } else {
          out += "\"undefined\"";
        }
      }
      out += ">\n";
      out += frameToString( f );
      out += "</frame>\n";
    }
  }

  return out;
}
Ejemplo n.º 10
0
QString validHtml(const QString &html, bool allowReplacement, QTextCursor *tc)
	{
	QDesktopWidget dw;
	ValidDocument oValidDocument(allowReplacement);

	QRectF qr = dw.availableGeometry();
	oValidDocument.setTextWidth(qr.width() / 2);
	oValidDocument.setDefaultStyleSheet(qApp->styleSheet());

	oValidDocument.setHtml(html);
	bool fIsValid = oValidDocument.isValid();

	QStringList qslAllowed = allowedSchemes();
	for (QTextBlock qtb = oValidDocument.begin(); qtb != oValidDocument.end(); qtb = qtb.next())
		{
		for (QTextBlock::iterator qtbi = qtb.begin(); qtbi != qtb.end(); ++qtbi)
			{
			const QTextFragment &qtf = qtbi.fragment();
			QTextCharFormat qcf = qtf.charFormat();
			if (! qcf.anchorHref().isEmpty())
				{
				QUrl url(qcf.anchorHref());
				if (! url.isValid() || ! qslAllowed.contains(url.scheme()))
					{
					QTextCharFormat qcfn = QTextCharFormat();
					QTextCursor qtc(&oValidDocument);
					qtc.setPosition(qtf.position(), QTextCursor::MoveAnchor);
					qtc.setPosition(qtf.position()+qtf.length(), QTextCursor::KeepAnchor);
					qtc.setCharFormat(qcfn);
					qtbi = qtb.begin();
					}
				}
			if (qcf.isImageFormat())
				{
				QTextImageFormat qtif = qcf.toImageFormat();
				QUrl url(qtif.name());
				if (! qtif.name().isEmpty() && ! url.isValid())
					fIsValid = false;
				}
			}
		}

	oValidDocument.adjustSize();
	QSizeF s = oValidDocument.size();

	if (!fIsValid || (s.width() > qr.width()) || (s.height() > qr.height())) {
		oValidDocument.setPlainText(html);
		oValidDocument.adjustSize();
		s = oValidDocument.size();

		if ((s.width() > qr.width()) || (s.height() > qr.height())) {
			QString errorMessage = "[[ Text object too large to display ]]";
			if (tc) {
				tc->insertText(errorMessage);
				return QString();
			} else {
				return errorMessage;
			}
		}
	}

	if (tc) {
		QTextCursor tcNew(&oValidDocument);
		tcNew.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
		tc->insertFragment(tcNew.selection());
		return QString();
	} else {
		return oValidDocument.toHtml();
	}
}