/*! Makes the given \a block part of the list. \sa remove(), removeItem() */ void QTextList::add(const QTextBlock &block) { QTextBlockFormat fmt = block.blockFormat(); fmt.setObjectIndex(objectIndex()); block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat); }
void NumberedTextView::textChanged( int pos, int removed, int added ) { Q_UNUSED( pos ); if ( removed == 0 && added == 0 ) return; QTextBlock block = highlight.block(); QTextBlockFormat fmt = block.blockFormat(); QColor bg = view->palette().base().color(); fmt.setBackground( bg ); highlight.setBlockFormat( fmt ); int lineCount = 1; for ( QTextBlock block = view->document()->begin(); block.isValid(); block = block.next(), ++lineCount ) { if ( lineCount == markedLine ) { fmt = block.blockFormat(); QColor bg = Qt::red; fmt.setBackground( bg.light(150) ); highlight = QTextCursor( block ); highlight.movePosition( QTextCursor::EndOfBlock, QTextCursor::KeepAnchor ); highlight.setBlockFormat( fmt ); break; } } }
int QTextCopyHelper::appendFragment(int pos, int endPos, int objectIndex) { QTextDocumentPrivate::FragmentIterator fragIt = src->find(pos); const QTextFragmentData * const frag = fragIt.value(); Q_ASSERT(objectIndex == -1 || (frag->size_array[0] == 1 && src->formatCollection()->format(frag->format).objectIndex() != -1)); int charFormatIndex; if (forceCharFormat) charFormatIndex = primaryCharFormatIndex; else charFormatIndex = convertFormatIndex(frag->format, objectIndex); const int inFragmentOffset = qMax(0, pos - fragIt.position()); int charsToCopy = qMin(int(frag->size_array[0] - inFragmentOffset), endPos - pos); QTextBlock nextBlock = src->blocksFind(pos + 1); int blockIdx = -2; if (nextBlock.position() == pos + 1) { blockIdx = convertFormatIndex(nextBlock.blockFormat()); } else if (pos == 0 && insertPos == 0) { dst->setBlockFormat(dst->blocksBegin(), dst->blocksBegin(), convertFormat(src->blocksBegin().blockFormat()).toBlockFormat()); dst->setCharFormat(-1, 1, convertFormat(src->blocksBegin().charFormat()).toCharFormat()); } QString txtToInsert(originalText.constData() + frag->stringPosition + inFragmentOffset, charsToCopy); if (txtToInsert.length() == 1 && (txtToInsert.at(0) == QChar::ParagraphSeparator || txtToInsert.at(0) == QTextBeginningOfFrame || txtToInsert.at(0) == QTextEndOfFrame ) ) { dst->insertBlock(txtToInsert.at(0), insertPos, blockIdx, charFormatIndex); ++insertPos; } else { if (nextBlock.textList()) { QTextBlock dstBlock = dst->blocksFind(insertPos); if (!dstBlock.textList()) { // insert a new text block with the block and char format from the // source block to make sure that the following text fragments // end up in a list as they should int listBlockFormatIndex = convertFormatIndex(nextBlock.blockFormat()); int listCharFormatIndex = convertFormatIndex(nextBlock.charFormat()); dst->insertBlock(insertPos, listBlockFormatIndex, listCharFormatIndex); ++insertPos; } } dst->insert(insertPos, txtToInsert, charFormatIndex); const int userState = nextBlock.userState(); if (userState != -1) dst->blocksFind(insertPos).setUserState(userState); insertPos += txtToInsert.length(); } return charsToCopy; }
void MainWindow::highlightListItems() { QTextCursor cursor = editor->textCursor(); QTextList *list = cursor.currentList(); if (!list) return; cursor.beginEditBlock(); //! [0] for (int index = 0; index < list->count(); ++index) { QTextBlock listItem = list->item(index); //! [0] QTextBlockFormat newBlockFormat = listItem.blockFormat(); newBlockFormat.setBackground(Qt::lightGray); QTextCursor itemCursor = cursor; itemCursor.setPosition(listItem.position()); //itemCursor.movePosition(QTextCursor::StartOfBlock); itemCursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); itemCursor.setBlockFormat(newBlockFormat); /* //! [1] processListItem(listItem); //! [1] */ //! [2] } //! [2] cursor.endEditBlock(); }
template<> void QConsoleWidget::_pf<void, UpdatePromptWidget>( QConsoleWidget * thisp ) { //TODO: UpdatePromptWidget { QFontMetricsF fontMetrics( thisp->thisp->textCharFormat.font()); { QTextDocument * doc = thisp->document(); QTextBlock textBlock = doc->findBlock(thisp->promptEndPos_); QTextCursor cursor_(textBlock); QTextBlockFormat bf_ = textBlock.blockFormat(); float fh = fontMetrics.height() +1.55f; thisp->thisp->setFixedHeight(fh); thisp->thisp->setFixedWidth(fh); bf_.setTextIndent( thisp->thisp->width() ); cursor_.setBlockFormat(bf_); thisp->setTextCursor(cursor_); } } _pf<void, UpdatePromptWidgetPositon>(thisp); thisp->raise(); }
void TextContentsModelImpl::documentLayoutFinished() { QTextBlock block = d->textDocument->firstBlock(); d->entries.clear(); while (block.isValid()) { QTextBlockFormat format = block.blockFormat(); if (format.hasProperty(KoParagraphStyle::OutlineLevel)) { ContentsEntry entry; entry.title = block.text(); entry.level = format.intProperty(KoParagraphStyle::OutlineLevel); auto rootArea = d->layout->rootAreaForPosition(block.position()); if (rootArea) { if (rootArea->page()) { entry.pageNumber = rootArea->page()->visiblePageNumber(); entry.page = static_cast<KWPage*>(rootArea->page()); } } d->entries.append(entry); } block = block.next(); } emit listContentsCompleted(); }
void NoteEditWidget::resizeEvent(QResizeEvent *) { int screenWidth = width(); int screenHeight = height(); if (screenWidth > screenHeight) { // we have a classical landscape monitor noteEditHeight = screenHeight - TextEditMargin; noteEditWidth = static_cast<int>(noteEditHeight * NoteEditWidthMultiplier); } else { // we have monitor standing in portrait noteEditWidth = screenWidth - TextEditMargin; noteEditHeight = static_cast<int>(noteEditWidth / NoteEditWidthMultiplier); } noteEditXPos = (screenWidth - noteEditWidth) / 2; noteEditYPos = (screenHeight - noteEditHeight) / 2; visualCover->setGeometry(0, 0, width(), height()); textEdit->setGeometry(noteEditXPos, noteEditYPos, noteEditWidth, noteEditHeight); textEdit->setFocus(); textEdit->setFont(getFontForTextEditWith(noteEditWidth)); for (QTextBlock block = textEdit->document()->begin(); block.isValid(); block = block.next()) { QTextCursor tc = QTextCursor(block); QTextBlockFormat fmt = block.blockFormat(); fmt.setLineHeight(LineHeightPercentage, QTextBlockFormat::ProportionalHeight); tc.setBlockFormat(fmt); } }
void KoTextWriter::Private::writeBlocks(QTextDocument *document, int from, int to, QHash<QTextList *, QString> &listStyles, QTextTable *currentTable, QTextList *currentList) { pairedInlineObjectsStackStack.push(currentPairedInlineObjectsStack); currentPairedInlineObjectsStack = new QStack<KoInlineObject*>(); QTextBlock block = document->findBlock(from); int sectionLevel = 0; while (block.isValid() && ((to == -1) || (block.position() <= to))) { QTextCursor cursor(block); int frameType = cursor.currentFrame()->format().intProperty(KoText::SubFrameType); if (frameType == KoText::AuxillaryFrameType) { break; // we've reached the "end" (end/footnotes saved by themselves) // note how NoteFrameType passes through here so the notes can // call writeBlocks to save their contents. } QTextBlockFormat format = block.blockFormat(); if (format.hasProperty(KoParagraphStyle::SectionStartings)) { QVariant v = format.property(KoParagraphStyle::SectionStartings); QList<QVariant> sectionStarts = v.value<QList<QVariant> >(); foreach (const QVariant &sv, sectionStarts) { KoSection* section = (KoSection*)(sv.value<void*>()); if (section) { ++sectionLevel; section->saveOdf(context); } } }
/*! Removes the given \a block from the list. \sa add(), removeItem() */ void QTextList::remove(const QTextBlock &block) { QTextBlockFormat fmt = block.blockFormat(); fmt.setIndent(fmt.indent() + format().indent()); fmt.setObjectIndex(-1); block.docHandle()->setBlockFormat(block, block, fmt, QTextDocumentPrivate::SetFormat); }
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); } }
void TextTools::indentLessClicked() { QTextList* list = cursor()->currentList(); if (list == 0) { QTextBlockFormat format = cursor()->blockFormat(); int indent = format.indent(); if (indent) { indent--; format.setIndent(indent); cursor()->insertBlock(format); updateText(); } return; } QTextCharFormat format = cursor()->blockCharFormat(); QTextListFormat listFormat = list->format(); QTextBlock block = cursor()->block(); if (block.next().isValid()) block = block.next(); else { block = QTextBlock(); } cursor()->insertBlock(block.blockFormat()); cursor()->setCharFormat(block.charFormat()); updateText(); }
void OdtWriter::writeAutomaticStyles(const QTextDocument* document) { m_xml.writeStartElement(QString::fromLatin1("office:automatic-styles")); QVector<QTextFormat> formats = document->allFormats(); // Find all used styles QVector<int> text_styles; QVector<int> paragraph_styles; int index = 0; for (QTextBlock block = document->begin(); block.isValid(); block = block.next()) { index = block.blockFormatIndex(); if (!paragraph_styles.contains(index)) { int heading = block.blockFormat().property(QTextFormat::UserProperty).toInt(); if (!heading) { paragraph_styles.append(index); } else { m_styles.insert(index, QString("Heading-%1").arg(heading)); } } for (QTextBlock::iterator iter = block.begin(); !(iter.atEnd()); ++iter) { index = iter.fragment().charFormatIndex(); if (!text_styles.contains(index) && formats.at(index).propertyCount()) { text_styles.append(index); } } } // Write text styles int text_style = 1; for (int i = 0; i < text_styles.size(); ++i) { int index = text_styles.at(i); const QTextFormat& format = formats.at(index); QString name = QString::fromLatin1("T") + QString::number(text_style); if (writeTextStyle(format.toCharFormat(), name)) { m_styles.insert(index, name); ++text_style; } } // Write paragraph styles int paragraph_style = 1; for (int i = 0; i < paragraph_styles.size(); ++i) { int index = paragraph_styles.at(i); const QTextFormat& format = formats.at(index); QString name = QString::fromLatin1("P") + QString::number(paragraph_style); if (writeParagraphStyle(format.toBlockFormat(), name)) { m_styles.insert(index, name); ++paragraph_style; } else { m_styles.insert(index, "Normal"); } } m_xml.writeEndElement(); }
void ChangeFollower::processUpdates(const QList<int> &changedStyles) { KoStyleManager *sm = m_styleManager.data(); if (!sm) { // since the stylemanager would be the one calling this method, I doubt this // will ever happen. But better safe than sorry.. deleteLater(); return; } // optimization strategy; store the formatid of the formats we checked into // a qset for 'hits' and 'ignores' and avoid the copying of the format // (fragment.charFormat() / block.blockFormat()) when the formatId is // already checked previosly QTextCursor cursor(m_document); QTextBlock block = cursor.block(); while (block.isValid()) { QTextBlockFormat bf = block.blockFormat(); int id = bf.intProperty(KoParagraphStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { cursor.setPosition(block.position()); KoParagraphStyle *style = sm->paragraphStyle(id); Q_ASSERT(style); style->applyStyle(bf); cursor.setBlockFormat(bf); } QTextCharFormat cf = block.charFormat(); id = cf.intProperty(KoCharacterStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { KoCharacterStyle *style = sm->characterStyle(id); Q_ASSERT(style); style->applyStyle(block); } QTextBlock::iterator iter = block.begin(); while (! iter.atEnd()) { QTextFragment fragment = iter.fragment(); cf = fragment.charFormat(); id = cf.intProperty(KoCharacterStyle::StyleId); if (id > 0 && changedStyles.contains(id)) { // create selection cursor.setPosition(fragment.position()); cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor); KoCharacterStyle *style = sm->characterStyle(id); Q_ASSERT(style); style->applyStyle(cf); cursor.mergeCharFormat(cf); } iter++; } block = block.next(); } }
void QLineNumberTextEdit::textChanged( int pos, int removed, int added ) { return; Q_UNUSED( pos ); #if 0 if ( removed == 0 && added == 0 ) return; if(doHighlighting) { QTextBlock block = highlight.block(); QTextBlockFormat fmt = block.blockFormat(); QColor bg = view->palette().base().color(); fmt.setBackground( bg ); highlight.setBlockFormat( fmt ); int lineCount = 1; for ( QTextBlock block = view->document()->begin(); block.isValid(); block = block.next(), ++lineCount ) { // if ( lineCount == infoLine ) { // fmt = block.blockFormat(); // QColor bg = view->palette().highlight().color().light(150); // fmt.setBackground( bg ); // highlight = QTextCursor( block ); // highlight.movePosition( QTextCursor::EndOfBlock, QTextCursor::KeepAnchor ); // highlight.setBlockFormat( fmt ); // break; // } else if ( lineCount == warningLine ) { // fmt = block.blockFormat(); // QColor bg = view->palette().highlight().color().light(100); // fmt.setBackground( bg ); // highlight = QTextCursor( block ); // highlight.movePosition( QTextCursor::EndOfBlock, QTextCursor::KeepAnchor ); // highlight.setBlockFormat( fmt ); // break; // } else if ( lineCount == errorLine ) { // fmt = block.blockFormat(); // QColor bg = view->palette().highlight().color().light(100); // fmt.setBackground( bg ); // highlight = QTextCursor( block ); // highlight.movePosition( QTextCursor::EndOfBlock, QTextCursor::KeepAnchor ); // highlight.setBlockFormat( fmt ); // break; // } } } #endif }
int KoList::level(const QTextBlock &block) { if (!block.textList()) return 0; int l = block.blockFormat().intProperty(KParagraphStyle::ListLevel); if (!l) { // not a numbered-paragraph QTextListFormat format = block.textList()->format(); l = format.intProperty(KListStyle::Level); } return l; }
void visit(QTextBlock &block) const { QTextBlockFormat format = block.blockFormat(); // TODO make the 10 configurable. format.setLeftMargin(qMax(qreal(0.0), format.leftMargin() - 10)); if (block.textList()) { const QTextListFormat listFormat = block.textList()->format(); if (format.leftMargin() < listFormat.doubleProperty(KoListStyle::Margin)) { format.setLeftMargin(listFormat.doubleProperty(KoListStyle::Margin)); } } QTextCursor cursor(block); cursor.setBlockFormat(format); }
void KDReports::TextDocumentData::updatePercentSizes( const QSizeF& size ) { QTextCursor c( m_document ); c.beginEditBlock(); // TODO only if we inserted resizable images do { c.movePosition( QTextCursor::NextCharacter ); QTextCharFormat format = c.charFormat(); if ( format.hasProperty( ResizableImageProperty ) ) { Q_ASSERT( format.isImageFormat() ); QTextImageFormat imageFormat = format.toImageFormat(); updatePercentSize( imageFormat, size ); //qDebug() << "updatePercentSizes: setting image to " << imageFormat.width() << "," << imageFormat.height(); c.movePosition( QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor ); c.setCharFormat( imageFormat ); c.movePosition( QTextCursor::NextCharacter ); } } while ( !c.atEnd() ); if (m_usesTabPositions) { QTextFrameFormat rootFrameFormat = m_document->rootFrame()->frameFormat(); const int rootFrameMargins = rootFrameFormat.leftMargin() + rootFrameFormat.rightMargin(); QTextBlock block = m_document->firstBlock(); do { QTextBlockFormat blockFormat = block.blockFormat(); QList<QTextOption::Tab> tabs = blockFormat.tabPositions(); //qDebug() << "Looking at block" << block.blockNumber() << "tabs:" << tabs.count(); if (!tabs.isEmpty()) { for (int i = 0; i < tabs.count(); ++i) { QTextOption::Tab& tab = tabs[i]; if ( tab.delimiter == QLatin1Char('P') /* means Page -- see rightAlignedTab*/) { if ( tab.type == QTextOption::RightTab ) { //qDebug() << "Adjusted RightTab from" << tab.position << "to" << size.width(); tab.position = size.width() - rootFrameMargins; } else if ( tab.type == QTextOption::CenterTab ) { tab.position = ( size.width() - rootFrameMargins ) / 2; } } } blockFormat.setTabPositions( tabs ); //qDebug() << "Adjusted tabs:" << tabs; c.setPosition( block.position() ); c.setBlockFormat( blockFormat ); } block = block.next(); } while ( block.isValid() ); } c.endEditBlock(); }
void TestKoTextEditor::checkSectionModelLevel(TestDocument *doc) { // Assuming here that Formatting level is OK // Below I will rebuild sections structure from scratch // and compare it then with a KoSectionModel QVector<SectionHandle *> allSections, rootSections; QStack<SectionHandle *> sectionStack; QTextBlock curBlock = doc->m_document->firstBlock(); // This kind of cycle should visit all blocks // including ones in tables and frames. while (curBlock.isValid()) { QList<KoSection *> secStartings = KoSectionUtils::sectionStartings(curBlock.blockFormat()); QList<KoSectionEnd *> secEndings = KoSectionUtils::sectionEndings(curBlock.blockFormat()); foreach(KoSection *sec, secStartings) { SectionHandle *handle = new SectionHandle(sec); if (sectionStack.empty()) { rootSections.push_back(handle); handle->parent = 0; } else { sectionStack.top()->children.push_back(handle); handle->parent = sectionStack.top()->sec; } allSections.push_back(handle); sectionStack.push(handle); } foreach(KoSectionEnd *secEnd, secEndings) { sectionStack.pop(); } curBlock = curBlock.next(); }
TableOfContentsConfigure::TableOfContentsConfigure(KoTextEditor *editor, QTextBlock block, QWidget *parent) : QDialog(parent), m_textEditor(editor), m_tocStyleConfigure(0), m_tocInfo(0), m_block(block), m_document(0), m_tocEntryStyleModel(0), m_tocEntryConfigureDelegate(0) { init(); KoTableOfContentsGeneratorInfo *info = block.blockFormat().property(KoParagraphStyle::TableOfContentsData).value<KoTableOfContentsGeneratorInfo*>(); m_tocInfo = info->clone(); setDisplay(); }
void visit(QTextBlock &block) const { QTextBlockFormat format = block.blockFormat(); // TODO make the 10 configurable. if (!block.textList()) { format.setLeftMargin(format.leftMargin() + 10); } else { const QTextListFormat listFormat = block.textList()->format(); if (format.leftMargin() == 0) { format.setLeftMargin(listFormat.doubleProperty(KoListStyle::Margin) + 10); } else { format.setLeftMargin(format.leftMargin() + 10); } } QTextCursor cursor(block); cursor.setBlockFormat(format); }
qreal KDReports::TextDocReportLayout::layoutAsOnePage(qreal docWidth) { m_textDocument.layoutWithTextWidth(docWidth); qreal docHeight = m_textDocument.contentDocument().size().height(); #if QT_VERSION <= 0x040300 // Qt-4.2 bug, fixed in Qt-4.3: QTextDocumentLayout::dynamicPageCount() // returns docheight/pageheight + 1. So if the doc is just as high as the page, I get 2 pages. docHeight += 1; #endif // We need to get rid of all page breaks... // Unittest: PageLayout::testEndlessPrinterWithPageBreaks() QTextCursor c(&m_textDocument.contentDocument()); c.beginEditBlock(); QTextBlock block = m_textDocument.contentDocument().firstBlock(); do { //qDebug() << "addBlock: Looking at block" << block.blockNumber(); QTextBlockFormat format = block.blockFormat(); if ( format.pageBreakPolicy() != QTextBlockFormat::PageBreak_Auto ) format.setPageBreakPolicy( QTextBlockFormat::PageBreak_Auto ); c.setPosition( block.position() ); c.setBlockFormat( format ); block = block.next(); } while ( block.isValid() ); c.endEditBlock(); setPageContentSize(QSizeF(docWidth, docHeight)); qDebug() << "m_textDocument.layoutDocument().setPageSize" << docWidth << "x" << docHeight << numberOfPages() << "pages"; qreal newDocHeight = m_textDocument.contentDocument().size().height(); if (newDocHeight > docHeight) { // QTextDocument is playing tricks on us; it was able to layout as docWidth x docHeight // but once we set that as the page size, we end up with more height... // Unittest: PageLayout::testEndlessPrinterBug() qDebug() << "newDocHeight=" << newDocHeight << "expected" << docHeight; setPageContentSize(QSizeF(docWidth, newDocHeight)); newDocHeight = m_textDocument.contentDocument().size().height(); qDebug() << "final newDocHeight=" << newDocHeight << numberOfPages() << "pages"; } Q_ASSERT(numberOfPages() == 1); return newDocHeight; }
/*! \fn QString QTextList::itemText(const QTextBlock &block) const Returns the text of the list item that corresponds to the given \a block. */ QString QTextList::itemText(const QTextBlock &blockIt) const { Q_D(const QTextList); int item = d->blocks.indexOf(blockIt) + 1; if (item <= 0) return QString(); QTextBlock block = d->blocks.at(item-1); QTextBlockFormat blockFormat = block.blockFormat(); QString result; const int style = format().style(); switch (style) { case QTextListFormat::ListDecimal: result = QString::number(item); break; // from the old richtext case QTextListFormat::ListLowerAlpha: case QTextListFormat::ListUpperAlpha: { const char baseChar = style == QTextListFormat::ListUpperAlpha ? 'A' : 'a'; int c = item; while (c > 0) { c--; result.prepend(QChar(baseChar + (c % 26))); c /= 26; } } break; default: Q_ASSERT(false); } if (blockFormat.layoutDirection() == Qt::RightToLeft) return result.prepend(QLatin1Char('.')); return result + QLatin1Char('.'); }
void TextEditWidget::sl_ListButton_Toggled(bool toggle) { QTextCursor cursor = this->textField->textCursor(); if (toggle) { if (cursor.currentList()) { WARNING("Wrong button state"); return; } QTextListFormat format; format.setStyle(QTextListFormat::ListDisc); cursor.createList(format); } else { QTextList *textList = cursor.currentList(); if (!cursor.currentList()) { WARNING("Wrong button state"); return; } QTextBlock block = cursor.block(); textList->remove(block); QTextBlockFormat format = block.blockFormat(); format.setIndent(0); cursor.setBlockFormat(format); } }
void MLScriptEditor::lineNumberAreaPaintEvent( QPaintEvent *event,const QColor& col) { QPainter painter(narea); painter.fillRect(event->rect(),col); QTextBlock block = firstVisibleBlock(); int indent = block.blockFormat().indent(); int blockNumber = block.blockNumber(); int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); int bottom = top + (int) blockBoundingRect(block).height(); while (block.isValid() && top <= event->rect().bottom()) { if (block.isVisible() && bottom >= event->rect().top()) { QString number = QString::number(blockNumber + 1); painter.setPen(Qt::black); painter.drawText(0, top, narea->width(), fontMetrics().height(),Qt::AlignRight, number); } block = block.next(); top = bottom; bottom = top + (int) blockBoundingRect(block).height(); ++blockNumber; } }
QString KoTextWriter::saveParagraphStyle(const QTextBlock &block) { KoParagraphStyle *defaultParagraphStyle = d->styleManager->defaultParagraphStyle(); QTextBlockFormat blockFormat = block.blockFormat(); QTextCharFormat charFormat = QTextCursor(block).blockCharFormat(); KoParagraphStyle *originalParagraphStyle = d->styleManager->paragraphStyle(blockFormat.intProperty(KoParagraphStyle::StyleId)); if (!originalParagraphStyle) originalParagraphStyle = defaultParagraphStyle; QString generatedName; QString displayName = originalParagraphStyle->name(); QString internalName = QString(QUrl::toPercentEncoding(displayName, "", " ")).replace('%', '_'); // we'll convert the blockFormat to a KoParagraphStyle to check for local changes. KoParagraphStyle paragStyle(blockFormat, charFormat); if (paragStyle == (*originalParagraphStyle)) { // This is the real, unmodified character style. // TODO zachmann: this could use the name of the saved style without saving it again // therefore we would need to store that information in the saving context if (originalParagraphStyle != defaultParagraphStyle) { KoGenStyle style(KoGenStyle::StyleUser, "paragraph"); originalParagraphStyle->saveOdf(style, d->context.mainStyles()); generatedName = d->context.mainStyles().lookup(style, internalName, KoGenStyles::DontForceNumbering); } } else { // There are manual changes... We'll have to store them then KoGenStyle style(KoGenStyle::StyleAuto, "paragraph", internalName); if (d->context.isSet(KoShapeSavingContext::AutoStyleInStyleXml)) style.setAutoStyleInStylesDotXml(true); if (originalParagraphStyle) paragStyle.removeDuplicates(*originalParagraphStyle); paragStyle.saveOdf(style, d->context.mainStyles()); generatedName = d->context.mainStyles().lookup(style, "P"); } return generatedName; }
/*! \fn QString QTextList::itemText(const QTextBlock &block) const Returns the text of the list item that corresponds to the given \a block. */ QString QTextList::itemText(const QTextBlock &blockIt) const { Q_D(const QTextList); int item = d->blocks.indexOf(blockIt) + 1; if (item <= 0) return QString(); QTextBlock block = d->blocks.at(item-1); QTextBlockFormat blockFormat = block.blockFormat(); QString result; const int style = format().style(); QString numberPrefix; QString numberSuffix = QLatin1String("."); if (format().hasProperty(QTextFormat::ListNumberPrefix)) numberPrefix = format().numberPrefix(); if (format().hasProperty(QTextFormat::ListNumberSuffix)) numberSuffix = format().numberSuffix(); switch (style) { case QTextListFormat::ListDecimal: result = QString::number(item); break; // from the old richtext case QTextListFormat::ListLowerAlpha: case QTextListFormat::ListUpperAlpha: { const char baseChar = style == QTextListFormat::ListUpperAlpha ? 'A' : 'a'; int c = item; while (c > 0) { c--; result.prepend(QChar(baseChar + (c % 26))); c /= 26; } } break; case QTextListFormat::ListLowerRoman: case QTextListFormat::ListUpperRoman: { if (item < 5000) { QByteArray romanNumeral; // works for up to 4999 items static const char romanSymbolsLower[] = "iiivixxxlxcccdcmmmm"; static const char romanSymbolsUpper[] = "IIIVIXXXLXCCCDCMMMM"; QByteArray romanSymbols; // wrap to have "mid" if (style == QTextListFormat::ListLowerRoman) romanSymbols = QByteArray::fromRawData(romanSymbolsLower, sizeof(romanSymbolsLower)); else romanSymbols = QByteArray::fromRawData(romanSymbolsUpper, sizeof(romanSymbolsUpper)); int c[] = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 }; int n = item; for (int i = 12; i >= 0; n %= c[i], i--) { int q = n / c[i]; if (q > 0) { int startDigit = i + (i+3)/4; int numDigits; if (i % 4) { // c[i] == 4|5|9|40|50|90|400|500|900 if ((i-2) % 4) { // c[i] == 4|9|40|90|400|900 => with subtraction (IV, IX, XL, XC, ...) numDigits = 2; } else { // c[i] == 5|50|500 (V, L, D) numDigits = 1; } } else { // c[i] == 1|10|100|1000 (I, II, III, X, XX, ...) numDigits = q; } romanNumeral.append(romanSymbols.mid(startDigit, numDigits)); } } result = QString::fromLatin1(romanNumeral); } else { result = QLatin1String("?"); } } break; default: Q_ASSERT(false); } if (blockIt.textDirection() == Qt::RightToLeft) return numberSuffix + result + numberPrefix; else return numberPrefix + result + numberSuffix; }
void KoTextWriter::write(QTextDocument *document, int from, int to) { d->styleManager = KoTextDocument(document).styleManager(); d->layout = dynamic_cast<KoTextDocumentLayout*>(document->documentLayout()); d->changeTracker = KoTextDocument(document).changeTracker(); // Q_ASSERT(d->changeTracker); Q_ASSERT(d->layout); Q_ASSERT(d->layout->inlineTextObjectManager()); QTextBlock block = document->findBlock(from); KoTextDocument textDocument(document); QHash<QTextList *, QString> listStyles = saveListStyles(block, to); QList<QTextList*> textLists; // Store the current lists being stored. KoList *currentList = 0; while (block.isValid() && ((to == -1) || (block.position() <= to))) { QTextBlockFormat blockFormat = block.blockFormat(); QTextList *textList = block.textList(); int headingLevel = 0, numberedParagraphLevel = 0; if (textList) { headingLevel = blockFormat.intProperty(KoParagraphStyle::OutlineLevel); numberedParagraphLevel = blockFormat.intProperty(KoParagraphStyle::ListLevel); } if (textList && !headingLevel && !numberedParagraphLevel) { if (!textLists.contains(textList)) { KoList *list = textDocument.list(block); if (currentList != list) { while (!textLists.isEmpty()) { textLists.removeLast(); d->writer->endElement(); // </text:list> if (!textLists.isEmpty()) { d->writer->endElement(); // </text:list-element> } } currentList = list; } else if (!textLists.isEmpty()) // sublists should be written within a list-item d->writer->startElement("text:list-item", false); d->writer->startElement("text:list", false); d->writer->addAttribute("text:style-name", listStyles[textList]); if (textList->format().hasProperty(KoListStyle::ContinueNumbering)) d->writer->addAttribute("text:continue-numbering", textList->format().boolProperty(KoListStyle::ContinueNumbering) ? "true" : "false"); textLists.append(textList); } else if (textList != textLists.last()) { while ((!textLists.isEmpty()) && (textList != textLists.last())) { textLists.removeLast(); d->writer->endElement(); // </text:list> d->writer->endElement(); // </text:list-element> } } const bool listHeader = blockFormat.boolProperty(KoParagraphStyle::IsListHeader) || blockFormat.boolProperty(KoParagraphStyle::UnnumberedListItem); d->writer->startElement(listHeader ? "text:list-header" : "text:list-item", false); if (KoListStyle::isNumberingStyle(textList->format().style())) { if (KoTextBlockData *blockData = dynamic_cast<KoTextBlockData *>(block.userData())) { d->writer->startElement("text:number", false); d->writer->addTextSpan(blockData->counterText()); d->writer->endElement(); } } } else { // Close any remaining list... while (!textLists.isEmpty()) { textLists.removeLast(); d->writer->endElement(); // </text:list> if (!textLists.isEmpty()) { d->writer->endElement(); // </text:list-element> } } if (textList && numberedParagraphLevel) { d->writer->startElement("text:numbered-paragraph", false); d->writer->addAttribute("text:level", numberedParagraphLevel); d->writer->addAttribute("text:style-name", listStyles.value(textList)); } } saveParagraph(block, from, to); if (!textLists.isEmpty() || numberedParagraphLevel) { // we are generating a text:list-item. Look forward and generate unnumbered list items. while (true) { QTextBlock nextBlock = block.next(); if (!nextBlock.isValid() || !((to == -1) || (nextBlock.position() < to))) break; if (!nextBlock.textList() || !nextBlock.blockFormat().boolProperty(KoParagraphStyle::UnnumberedListItem)) break; block = nextBlock; saveParagraph(block, from, to); } } // We must check if we need to close a previously-opened text:list node. if ((block.textList() && !headingLevel) || numberedParagraphLevel) d->writer->endElement(); block = block.next(); } // while // Close any remaining lists while (!textLists.isEmpty()) { textLists.removeLast(); d->writer->endElement(); // </text:list> if (!textLists.isEmpty()) { d->writer->endElement(); // </text:list-element> } } }
void QTextCopyHelper::copy() { if (cursor.hasComplexSelection()) { QTextTable *table = cursor.currentTable(); int row_start, col_start, num_rows, num_cols; cursor.selectedTableCells(&row_start, &num_rows, &col_start, &num_cols); QTextTableFormat tableFormat = table->format(); tableFormat.setColumns(num_cols); tableFormat.clearColumnWidthConstraints(); const int objectIndex = dst->formatCollection()->createObjectIndex(tableFormat); Q_ASSERT(row_start != -1); for (int r = row_start; r < row_start + num_rows; ++r) { for (int c = col_start; c < col_start + num_cols; ++c) { QTextTableCell cell = table->cellAt(r, c); const int rspan = cell.rowSpan(); const int cspan = cell.columnSpan(); if (rspan != 1) { int cr = cell.row(); if (cr != r) continue; } if (cspan != 1) { int cc = cell.column(); if (cc != c) continue; } // add the QTextBeginningOfFrame QTextCharFormat cellFormat = cell.format(); if (r + rspan >= row_start + num_rows) { cellFormat.setTableCellRowSpan(row_start + num_rows - r); } if (c + cspan >= col_start + num_cols) { cellFormat.setTableCellColumnSpan(col_start + num_cols - c); } const int charFormatIndex = convertFormatIndex(cellFormat, objectIndex); int blockIdx = -2; const int cellPos = cell.firstPosition(); QTextBlock block = src->blocksFind(cellPos); if (block.position() == cellPos) { blockIdx = convertFormatIndex(block.blockFormat()); } dst->insertBlock(QTextBeginningOfFrame, insertPos, blockIdx, charFormatIndex); ++insertPos; // nothing to add for empty cells if (cell.lastPosition() > cellPos) { // add the contents appendFragments(cellPos, cell.lastPosition()); } } } // add end of table int end = table->lastPosition(); appendFragment(end, end+1, objectIndex); } else { appendFragments(cursor.selectionStart(), cursor.selectionEnd()); } }
bool IndexGeneratorManager::generate() { if (m_state == Resting || m_state == FirstRunLayouting || m_state == SecondRunLayouting) { return false; } if (m_state == FirstRun || m_state == SecondRun) { return true; } if (m_document->characterCount() < 2) { return false; } if (m_state == FirstRunNeeded) { m_state = FirstRun; } if (m_state == SecondRunNeeded) { m_state = SecondRun; } QTextBlock block = m_document->firstBlock(); bool success = true; while (block.isValid()) { QTextBlockFormat format = block.blockFormat(); if (format.hasProperty(KoParagraphStyle::TableOfContentsData)) { QVariant data = format.property(KoParagraphStyle::TableOfContentsData); KoTableOfContentsGeneratorInfo *tocInfo = data.value<KoTableOfContentsGeneratorInfo *>(); data = format.property(KoParagraphStyle::GeneratedDocument); QTextDocument *tocDocument = data.value<QTextDocument *>(); ToCGenerator *generator = m_generators[tocInfo]; if (!generator) { generator = new ToCGenerator(tocDocument, tocInfo); m_generators[tocInfo] = generator; } generator->setBlock(block); success &= generator->generate(); } block = block.next(); } if (m_state == FirstRun) { m_state = FirstRunLayouting; } if (m_state == SecondRun) { if (success) { m_state = SecondRunLayouting; } else { m_state = FirstRunLayouting; } } return false; }
void visit(QTextBlock &block) const { QTextBlockFormat format = block.blockFormat(); format.setAlignment(alignment); QTextCursor cursor(block); cursor.setBlockFormat(format); }