void KPrPlaceholderTextStrategy::paint( QPainter & painter, const KoViewConverter &converter, const QRectF & rect, KoShapePaintingContext &paintcontext) { if ( m_textShape ) { painter.save(); m_textShape->setSize( rect.size() ); // this code is needed to make sure the text of the textshape is layouted before it is painted KoTextShapeData * shapeData = qobject_cast<KoTextShapeData*>( m_textShape->userData() ); QTextDocument * document = shapeData->document(); KoTextDocumentLayout * lay = qobject_cast<KoTextDocumentLayout*>( document->documentLayout() ); if ( lay ) { lay->layout(); } m_textShape->paint( painter, converter, paintcontext); KoShape::applyConversion( painter, converter ); QPen pen(Qt::gray, 0); //pen.setStyle( Qt::DashLine ); // endless loop painter.setPen( pen ); painter.drawRect( rect ); painter.restore(); } else { KPrPlaceholderStrategy::paint( painter, converter, rect, paintcontext); } }
ShrinkToFitShapeContainer::ShrinkToFitShapeContainer(KoShape *childShape, KoDocumentResourceManager *documentResources) : KoShapeContainer(*(new ShrinkToFitShapeContainerPrivate(this, childShape))) { Q_UNUSED(documentResources); Q_D(ShrinkToFitShapeContainer); setPosition(childShape->position()); setSize(childShape->size()); setZIndex(childShape->zIndex()); setRunThrough(childShape->runThrough()); rotate(childShape->rotation()); //setTransformation(childShape->transformation()); if (childShape->parent()) { childShape->parent()->addShape(this); childShape->setParent(0); } childShape->setPosition(QPointF(0.0,0.0)); // since its relative to my position, this won't move it childShape->setSelectable(false); // our ShrinkToFitShapeContainer will handle that from now on d->model = new ShrinkToFitShapeContainerModel(this, d); addShape(childShape); QSet<KoShape*> delegates; delegates << childShape; setToolDelegates(delegates); KoTextShapeData* data = dynamic_cast<KoTextShapeData*>(childShape->userData()); Q_ASSERT(data); KoTextDocumentLayout *lay = qobject_cast<KoTextDocumentLayout*>(data->document()->documentLayout()); Q_ASSERT(lay); QObject::connect(lay, SIGNAL(finishedLayout()), static_cast<ShrinkToFitShapeContainerModel*>(d->model), SLOT(finishedLayout())); }
void KWCopyShape::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintcontext) { Q_ASSERT(m_original); //paint all child shapes KoShapeContainer* container = dynamic_cast<KoShapeContainer*>(m_original); if (container) { QList<KoShape*> sortedObjects = container->shapes(); sortedObjects.append(m_original); qSort(sortedObjects.begin(), sortedObjects.end(), KoShape::compareShapeZIndex); // Do the following to revert the absolute transformation of the // container that is re-applied in shape->absoluteTransformation() // later on. The transformation matrix of the container has already // been applied once before this function is called. QTransform baseMatrix = container->absoluteTransformation(&converter).inverted() * painter.transform(); KWPage copypage = m_pageManager->page(this); Q_ASSERT(copypage.isValid()); foreach(KoShape *shape, sortedObjects) { painter.save(); if (shape != m_original) { painter.setTransform(shape->absoluteTransformation(&converter) * baseMatrix); } KoTextShapeData *data = qobject_cast<KoTextShapeData*>(shape->userData()); if (data == 0) { shape->paint(painter, converter, paintcontext); } else { // Since the rootArea is shared between the copyShape and the originalShape we need to // temporary switch the used KoTextPage to be sure the proper page-numbers are displayed. KWPage originalpage = m_pageManager->page(shape); Q_ASSERT(originalpage.isValid()); KoTextLayoutRootArea *area = data->rootArea(); bool wasBlockChanges = false; if (area) { // We need to block documentChanged() signals emitted cause for example page-variables // may change there content to result in us marking root-areas dirty for relayout else // we could end in an infinite relayout ping-pong. wasBlockChanges = area->documentLayout()->changesBlocked(); area->documentLayout()->setBlockChanges(true); area->setPage(new KWPage(copypage)); } shape->paint(painter, converter, paintcontext); if (area) { area->setPage(new KWPage(originalpage)); area->documentLayout()->setBlockChanges(wasBlockChanges); } } painter.restore(); if (shape->stroke()) { painter.save(); painter.setTransform(shape->absoluteTransformation(&converter) * baseMatrix); shape->stroke()->paint(shape, painter, converter); painter.restore(); } } } else {
void ShrinkToFitShapeContainer::tryWrapShape(KoShape *shape, const KoXmlElement &element, KoShapeLoadingContext &context) { KoTextShapeData* data = dynamic_cast<KoTextShapeData*>(shape->userData()); if (!data || data->resizeMethod() != KoTextShapeData::ShrinkToFitResize) return; KoShapeContainer *oldParent = shape->parent(); ShrinkToFitShapeContainer *tos = wrapShape(shape, context.documentResourceManager()); if (!tos->loadOdf(element, context)) { shape->setParent(oldParent); delete tos; } }
void KoTextShapeContainerModel::childChanged(KoShape *child, KoShape::ChangeType type) { if (type == KoShape::RotationChanged || type == KoShape::ScaleChanged || type == KoShape::ShearChanged || type == KoShape::SizeChanged) { KoTextShapeData *data = dynamic_cast<KoTextShapeData*>(child->parent()->userData()); Q_ASSERT(data); data->foul(); KoTextDocumentLayout *lay = dynamic_cast<KoTextDocumentLayout*>(data->document()->documentLayout()); if (lay) lay->interruptLayout(); data->fireResizeEvent(); } }
void KPrPlaceholderTextStrategy::saveOdf( KoShapeSavingContext & context ) { if (m_textShape) { KoTextShapeData *shapeData = qobject_cast<KoTextShapeData*>(m_textShape->userData()); if (shapeData) { KoStyleManager *styleManager = KoTextDocument(shapeData->document()).styleManager(); if (styleManager) { QTextDocument *document = shapeData->document(); QTextBlock block = document->begin(); QString styleName = KoTextWriter::saveParagraphStyle(block, styleManager, context); context.xmlWriter().addAttribute("draw:text-style-name", styleName); } } } KPrPlaceholderStrategy::saveOdf( context ); }
KoShape *KPrPlaceholderTextStrategy::createShape(KoDocumentResourceManager *documentResources) { KoShape * shape = KPrPlaceholderStrategy::createShape(documentResources); if ( m_textShape ) { KoTextShapeData * data = qobject_cast<KoTextShapeData*>( m_textShape->userData() ); KoTextShapeData * newData = qobject_cast<KoTextShapeData*>( shape->userData() ); if ( data && newData ) { QTextCursor cursor( data->document() ); QTextCursor newCursor( newData->document() ); KoTextDocument textDocument( newData->document() ); QTextBlockFormat blockFormat( cursor.blockFormat() ); newCursor.setBlockFormat( blockFormat ); QTextCharFormat chatFormat( cursor.blockCharFormat() ); newCursor.setBlockCharFormat( chatFormat ); } } return shape; }
bool KPrPlaceholderTextStrategy::loadOdf( const KoXmlElement & element, KoShapeLoadingContext & context ) { if (KoTextSharedLoadingData *textSharedData = dynamic_cast<KoTextSharedLoadingData *>(context.sharedData(KOTEXT_SHARED_LOADING_ID))) { KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("TextShapeID"); Q_ASSERT(factory); delete m_textShape; m_textShape = factory->createDefaultShape(context.documentResourceManager()); KoTextShapeData *shapeData = qobject_cast<KoTextShapeData*>(m_textShape->userData()); shapeData->document()->setUndoRedoEnabled(false); QTextDocument *document = shapeData->document(); QTextCursor cursor(document); QTextBlock block = cursor.block(); const QString styleName = element.attributeNS(KoXmlNS::presentation, "style-name"); if (!styleName.isEmpty()) { const KoXmlElement *style = context.odfLoadingContext().stylesReader().findStyle(styleName, "presentation", context.odfLoadingContext().useStylesAutoStyles()); if (style) { KoParagraphStyle paragraphStyle; paragraphStyle.loadOdf(style, context); paragraphStyle.applyStyle(block, false); // TODO t.zachmann is the false correct? } } const QString textStyleName = element.attributeNS(KoXmlNS::draw, "text-style-name"); if (!textStyleName.isEmpty()) { KoParagraphStyle *style = textSharedData->paragraphStyle(textStyleName, context.odfLoadingContext().useStylesAutoStyles()); if (style) { style->applyStyle(block, false); // TODO t.zachmann is the false correct? } } cursor.insertText(text()); shapeData->setDirty(); shapeData->document()->setUndoRedoEnabled(true); } return true; }
void ShrinkToFitShapeContainerModel::containerChanged(KoShapeContainer *container, KoShape::ChangeType type) { Q_ASSERT(container == q); Q_UNUSED(container); if (type == KoShape::SizeChanged) { KoTextShapeData* data = dynamic_cast<KoTextShapeData*>(d->childShape->userData()); Q_ASSERT(data); KoTextLayoutRootArea *rootArea = data->rootArea(); Q_ASSERT(rootArea); QSizeF shapeSize = q->size(); QSizeF documentSize = rootArea->boundingRect().size(); if (m_maybeUpdate &&shapeSize == m_shapeSize && documentSize == m_documentSize) { m_dirty = 0; return; // nothing to update } m_shapeSize = shapeSize; m_documentSize = documentSize; if ( documentSize.width() > 0.0 && documentSize.height() > 0.0 ) { if (m_dirty || !m_maybeUpdate) { qreal scaleX = qMin<qreal>(1.0, shapeSize.width() / documentSize.width()); qreal scaleY = qMin<qreal>(1.0, shapeSize.height() / documentSize.height()); m_scale = (scaleX+scaleY)/2.0 * 0.95; if (m_maybeUpdate && m_dirty) --m_dirty; } } else { m_scale = 1.0; m_dirty = 1; } QSizeF newSize(shapeSize.width() / m_scale, shapeSize.height() / m_scale); d->childShape->setSize(newSize); QTransform m; m.scale(m_scale, m_scale); d->childShape->setTransformation(m); } }
void KoTextShapeContainerModel::proposeMove(KoShape *child, QPointF &move) { Relation *relation = d->children.value(child); if (relation == 0 || relation->anchor == 0) return; QPointF newPosition = child->position() + move; QRectF parentShapeRect(QPointF(0, 0), child->parent()->size()); //kDebug(32500) <<"proposeMove:" << move <<" |" << newPosition <<" |" << parentShapeRect; if (qAbs(newPosition.x()) < 10) // align left relation->anchor->setAlignment(KoTextAnchor::Left); else if (qAbs(parentShapeRect.width() - newPosition.x()) < 10.0) relation->anchor->setAlignment(KoTextAnchor::Right); else if (qAbs(parentShapeRect.width() / 2.0 - newPosition.x()) < 10.0) relation->anchor->setAlignment(KoTextAnchor::Center); /*else { relation->anchor->setAlignment(KoTextAnchor::HorizontalOffset); // TODO //QPointF offset = relation->anchor->offset(); //offset.setX(offset.x() + move.x()); //relation->anchor->setOffset(offset); } */ if (qAbs(newPosition.y()) < 10.0) // TopOfFrame { kDebug(32500) <<" TopOfFrame"; relation->anchor->setAlignment(KoTextAnchor::TopOfFrame); } else if (qAbs(parentShapeRect.height() - newPosition.y()) < 10.0) { kDebug(32500) <<" BottomOfFrame"; relation->anchor->setAlignment(KoTextAnchor::BottomOfFrame); // TODO } else { // need layout info.. QTextBlock block = relation->anchor->document()->findBlock(relation->anchor->positionInDocument()); QTextLayout *layout = block.layout(); if (layout->lineCount() > 0) { KoTextShapeData *data = dynamic_cast<KoTextShapeData*>(child->parent()->userData()); Q_ASSERT(data); QTextLine tl = layout->lineAt(0); qreal y = tl.y() - data->documentOffset() - newPosition.y(); if (y >= 0 && y < 10) { kDebug(32500) <<" TopOfParagraph" << y <<""; relation->anchor->setAlignment(KoTextAnchor::TopOfParagraph); } else { tl = layout->lineAt(layout->lineCount() - 1); y = newPosition.y() - tl.y() - data->documentOffset() - tl.ascent(); if (y >= 0 && y < 10) { kDebug(32500) <<" BottomOfParagraph" << y; relation->anchor->setAlignment(KoTextAnchor::BottomOfParagraph); // TODO } else { tl = layout->lineForTextPosition(relation->anchor->positionInDocument() - block.position()); y = tl.y() - data->documentOffset() - newPosition.y(); if (y >= 0 && y < 10) { kDebug(32500) <<" AboveCurrentLine"; relation->anchor->setAlignment(KoTextAnchor::AboveCurrentLine); } //else do VerticalOffset here as well? } } } } move.setX(0); // let the text layout move it. move.setY(0); }
void KWRootAreaProviderBase::doPostLayout(KoTextLayoutRootArea *rootArea, bool /*isNewRootArea*/) { KoShape *shape = rootArea->associatedShape(); if (!shape) { return; } KoTextShapeData *data = qobject_cast<KoTextShapeData*>(shape->userData()); Q_ASSERT(data); QRectF updateRect = shape->outlineRect(); QSizeF newSize = shape->size() - QSizeF(data->leftPadding() + data->rightPadding(), data->topPadding() + data->bottomPadding()); KoBorder *border = shape->border(); if (border) { newSize -= QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder)); } if (data->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight ||data->resizeMethod() == KoTextShapeData::AutoGrowHeight) { newSize.setHeight(rootArea->bottom() - rootArea->top()); // adjust size to have at least the defined minimum height Q_ASSERT(frameSet()->shapeCount() > 0); KoShape *firstShape = frameSet()->shapes().first(); if (firstShape->minimumHeight() > newSize.height()) newSize.setHeight(firstShape->minimumHeight()); } if (data->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight ||data->resizeMethod() == KoTextShapeData::AutoGrowWidth) { newSize.setWidth(rootArea->right() - rootArea->left()); } newSize += QSizeF(data->leftPadding() + data->rightPadding(), data->topPadding() + data->bottomPadding()); if (border) { newSize += QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder)); } if (newSize != rootArea->associatedShape()->size()) { rootArea->associatedShape()->setSize(newSize); // transfer the new size to the copy-shapes foreach(KWCopyShape *cs, frameSet()->copyShapes()) { cs->setSize(newSize); }