Exemplo n.º 1
0
int KTextDocumentLayout::hitTestIterated(QTextFrame::iterator begin, QTextFrame::iterator end, const QPointF &point, Qt::HitTestAccuracy accuracy) const
{
    int position = -1;
    QTextFrame::iterator it = begin;
    for (it = begin; it != end; ++it) {
        QTextBlock block = it.currentBlock();
        QTextTable *table = qobject_cast<QTextTable*>(it.currentFrame());
        QTextFrame *subFrame = it.currentFrame();

        if (table) {
            QTextTableCell cell = m_state->hitTestTable(table, point);
            if (cell.isValid()) {
                position = hitTestIterated(cell.begin(), cell.end(), point,
                                accuracy);
                if (position == -1)
                    position = cell.lastPosition();
                return position;
            }
            continue;
        } else if (subFrame) {
            position = hitTestIterated(subFrame->begin(), subFrame->end(), point, accuracy);
            if (position != -1)
                return position;
            continue;
        } else {
            if (!block.isValid())
                continue;
        }
        // kDebug(32500) <<"hitTest[" << point.x() <<"," << point.y() <<"]";
        QTextLayout *layout = block.layout();
        if (point.y() > layout->boundingRect().bottom()) {
            // just skip this block. position = block.position() + block.length() - 1;
            continue;
        }
        for (int i = 0; i < layout->lineCount(); i++) {
            QTextLine line = layout->lineAt(i);
            // kDebug(32500) <<" + line[" << line.textStart() <<"]:" << line.y() <<"-" << line.height();
            if (point.y() > line.y() + line.height()) {
                position = line.textStart() + line.textLength();
                continue;
            }
            if (accuracy == Qt::ExactHit && point.y() < line.y()) // between lines
                return -1;
            if (accuracy == Qt::ExactHit && // left or right of line
                    (point.x() < line.x() || point.x() > line.x() + line.width()))
                return -1;
            if (point.x() > line.width() && layout->textOption().textDirection() == Qt::RightToLeft) {
                // totally right of RTL text means the position is the start of the text.
                return block.position() + line.textStart();
            }
            return block.position() + line.xToCursor(point.x());
        }
    }
    return -1;
}
Exemplo n.º 2
0
void QTextOdfWriter::writeFrame(QXmlStreamWriter &writer, const QTextFrame *frame)
{
    Q_ASSERT(frame);
    const QTextTable *table = qobject_cast<const QTextTable*> (frame);

    if (table) { // Start a table.
        writer.writeStartElement(tableNS, QString::fromLatin1("table"));
        writer.writeEmptyElement(tableNS, QString::fromLatin1("table-column"));
        writer.writeAttribute(tableNS, QString::fromLatin1("number-columns-repeated"), QString::number(table->columns()));
    } else if (frame->document() && frame->document()->rootFrame() != frame) { // start a section
        writer.writeStartElement(textNS, QString::fromLatin1("section"));
    }

    QTextFrame::iterator iterator = frame->begin();
    QTextFrame *child = 0;

    int tableRow = -1;
    while (! iterator.atEnd()) {
        if (iterator.currentFrame() && child != iterator.currentFrame())
            writeFrame(writer, iterator.currentFrame());
        else { // no frame, its a block
            QTextBlock block = iterator.currentBlock();
            if (table) {
                QTextTableCell cell = table->cellAt(block.position());
                if (tableRow < cell.row()) {
                    if (tableRow >= 0)
                        writer.writeEndElement(); // close table row
                    tableRow = cell.row();
                    writer.writeStartElement(tableNS, QString::fromLatin1("table-row"));
                }
                writer.writeStartElement(tableNS, QString::fromLatin1("table-cell"));
                if (cell.columnSpan() > 1)
                    writer.writeAttribute(tableNS, QString::fromLatin1("number-columns-spanned"), QString::number(cell.columnSpan()));
                if (cell.rowSpan() > 1)
                    writer.writeAttribute(tableNS, QString::fromLatin1("number-rows-spanned"), QString::number(cell.rowSpan()));
                if (cell.format().isTableCellFormat()) {
                    writer.writeAttribute(tableNS, QString::fromLatin1("style-name"), QString::fromLatin1("T%1").arg(cell.tableCellFormatIndex()));
                }
            }
            writeBlock(writer, block);
            if (table)
                writer.writeEndElement(); // table-cell
        }
        child = iterator.currentFrame();
        ++iterator;
    }
    if (tableRow >= 0)
        writer.writeEndElement(); // close table-row

    if (table || (frame->document() && frame->document()->rootFrame() != frame))
        writer.writeEndElement();  // close table or section element
}
Exemplo n.º 3
0
void XmlWriter::processFrame(QDomElement &parent, QTextFrame *frame)
{
    QDomElement frameElement = document->createElement("frame");
    frameElement.setAttribute("begin", frame->firstPosition());
    frameElement.setAttribute("end", frame->lastPosition());
    parent.appendChild(frameElement);

//! [0]
    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it) {

        QTextFrame *childFrame = it.currentFrame();
        QTextBlock childBlock = it.currentBlock();

        if (childFrame) {
            QTextTable *childTable = qobject_cast<QTextTable*>(childFrame);

            if (childTable)
                processTable(frameElement, childTable);
            else
                processFrame(frameElement, childFrame);

        } else if (childBlock.isValid())
//! [0] //! [1]
            processBlock(frameElement, childBlock);
    }
//! [1]
}
Exemplo n.º 4
0
void TextDocumentModel::fillFrameIterator(const QTextFrame::iterator &it, QStandardItem *parent)
{
    if (QTextFrame *frame = it.currentFrame()) {
        const QRectF b = m_document->documentLayout()->frameBoundingRect(frame);
        QTextTable *table = qobject_cast<QTextTable *>(frame);
        auto item = new QStandardItem;
        if (table) {
            item->setText(tr("Table"));
            appendRow(parent, item, table->format(), b);
            fillTable(table, item);
        } else {
            item->setText(tr("Frame"));
            appendRow(parent, item, frame->frameFormat(), b);
            fillFrame(frame, item);
        }
    }
    const QTextBlock block = it.currentBlock();
    if (block.isValid()) {
        auto item = new QStandardItem;
        item->setText(tr("Block: %1").arg(block.text()));
        const QRectF b = m_document->documentLayout()->blockBoundingRect(block);
        appendRow(parent, item, block.blockFormat(), b);
        fillBlock(block, item);
    }
}
Exemplo n.º 5
0
// 遍历框架
void MainWindow::showTextFrame()
{
    QTextDocument *document = ui->textEdit->document();
    QTextFrame *frame = document->rootFrame();
    // 建立QTextFrame类的迭代器
    QTextFrame::iterator it;
    for (it = frame->begin(); !(it.atEnd()); ++it) {
         // 获取当前框架的指针
         QTextFrame *childFrame = it.currentFrame();
         // 获取当前文本块
         QTextBlock childBlock = it.currentBlock();
         if (childFrame)
             qDebug() << "frame";
         else if (childBlock.isValid())
             qDebug() << "block:" << childBlock.text();
    }
}
Exemplo n.º 6
0
QModelIndex TextDocumentStructureModel::parent(const QModelIndex &index) const
{
    kDebug(32500) << "-------------------------- index:"<<index<<m_textDocument;
    if (! m_textDocument || ! index.isValid()) {
        return QModelIndex();
    }

    Q_ASSERT(index.internalId() < uint(m_nodeDataTable.count()));

    const NodeData &nodeData = m_nodeDataTable.at(index.internalId());

    QTextFrame* parentFrame;
    if (nodeData.type == NodeData::Frame) {
        parentFrame = nodeData.frame->parentFrame();
    } else {
        QTextBlock block = m_textDocument->findBlockByNumber(nodeData.blockNumber);
        Q_ASSERT(block.isValid());
        // QTextBlock's API has no option to query the parentframe, so get it via a cursor
        QTextCursor cursor(block);
        parentFrame = cursor.currentFrame();
    }

    if (! parentFrame) {
        return QModelIndex();
    }

    QTextFrame* grandParentFrame = parentFrame->parentFrame();
    // parent is root frame?
    if (! grandParentFrame) {
        Q_ASSERT(parentFrame == m_textDocument->rootFrame());
        return createIndex(0, 0, static_cast<quintptr>(0));
    }

    // find position of parentFrame
    bool posFound = false;
    int row = 0;
    for (QTextFrame::iterator iterator = grandParentFrame->begin(); !iterator.atEnd(); ++iterator) {
        if (iterator.currentFrame() == parentFrame) {
            posFound = true;
            break;
        }
        ++row;
    }
    Q_ASSERT(posFound);Q_UNUSED(posFound);
    return createIndex(row, 0, frameIndex(parentFrame));
}
Exemplo n.º 7
0
void XmlWriter::processTableCell(QDomElement &parent, const QTextTableCell &cell)
{
    QDomElement element = document->createElement("cell");
    element.setAttribute("row", cell.row());
    element.setAttribute("column", cell.column());
    
    QTextFrame::iterator it;
    for (it = cell.begin(); !(it.atEnd()); ++it) {

        QTextFrame *childFrame = it.currentFrame();
        QTextBlock childBlock = it.currentBlock();

        if (childFrame)
            processFrame(element, childFrame);
        else if (childBlock.isValid())
            processBlock(element, childBlock);
    }
    parent.appendChild(element);
}
Exemplo n.º 8
0
QModelIndex TextDocumentStructureModel::index(int row, int column, const QModelIndex &parentIndex) const
{
    kDebug(32500) << "-------------------------- row:" << row << "column:"<<column << "index:"<<parentIndex<<m_textDocument;
    if (! m_textDocument) {
        return QModelIndex();
    }

    if (! parentIndex.isValid()) {
        return createIndex(row, column, static_cast<quintptr>(0));
    }

    Q_ASSERT(parentIndex.internalId() < uint(m_nodeDataTable.count()));

    const NodeData &nodeData = m_nodeDataTable.at(parentIndex.internalId());
    // can be only frame for now
    Q_ASSERT(nodeData.type == NodeData::Frame);

    QTextFrame* parentFrame = nodeData.frame;
    int index = -1;
    int count = 0;
    for (QTextFrame::iterator iterator = parentFrame->begin(); !iterator.atEnd(); ++iterator) {
        if (count == row) {
            QTextFrame *frame = iterator.currentFrame();
            if (frame) {
                index = frameIndex(frame);
                break;
            } else {
                QTextBlock block = iterator.currentBlock();
                if (block.isValid()) {
                    index = blockIndex(block);
                    break;
                }
            }
        }
        ++count;
    }

    Q_ASSERT(index != -1);
    return createIndex(row, column, index);
}
QString TextDocumentSerializer::processFrame(QTextFrame *frame)
{
    QString text;

    QTextFrame::iterator it = frame->begin();
    while(!it.atEnd()){
        QTextFrame *childFrame = it.currentFrame();
        QTextBlock childBlock = it.currentBlock();

        if(childFrame)
            text += processFrame(childFrame);
        else if(childBlock.isValid()){
            if(childBlock.textList())
                text = removeTrailingLineBreaks(text);
            text += processBlock(childBlock, it);
        }

        ++it;
    }

    text = removeTrailingLineBreaks(text);

    return text;
}
Exemplo n.º 10
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;
}