KUndo2Command* KoCreateShapeStrategy::createCommand() { Q_D(KoShapeRubberSelectStrategy); KoCreateShapesTool *parent = static_cast<KoCreateShapesTool*>(d_ptr->tool); KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value(parent->shapeId()); if (! factory) { warnFlake << "Application requested a shape that is not registered" << parent->shapeId(); return 0; } const KoProperties *props = parent->shapeProperties(); KoShape *shape; if (props) shape = factory->createShape(props, parent->canvas()->shapeController()->resourceManager()); else shape = factory->createDefaultShape(parent->canvas()->shapeController()->resourceManager()); if (shape->shapeId().isEmpty()) shape->setShapeId(factory->id()); QRectF rect = d->selectedRect(); shape->setPosition(rect.topLeft()); QSizeF newSize = rect.size(); // if the user has dragged when creating the shape, // resize the shape to the dragged size if (newSize.width() > 1.0 && newSize.height() > 1.0) shape->setSize(newSize); KUndo2Command * cmd = parent->canvas()->shapeController()->addShape(shape); if (cmd) { KoSelection *selection = parent->canvas()->shapeManager()->selection(); selection->deselectAll(); selection->select(shape); } return cmd; }
void TestKoShapeFactory::testOdfElement() { KoShapeFactoryBase * factory = new KoPathShapeFactory(QStringList()); QVERIFY(factory->odfElements().front().second.contains("path")); QVERIFY(factory->odfElements().front().second.contains("line")); QVERIFY(factory->odfElements().front().second.contains("polyline")); QVERIFY(factory->odfElements().front().second.contains("polygon")); QVERIFY(factory->odfElements().front().first == KoXmlNS::draw); QBuffer xmldevice; xmldevice.open(QIODevice::WriteOnly); QTextStream xmlstream(&xmldevice); xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; xmlstream << "<office:document-content xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\" xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\" xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\" xmlns:presentation=\"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0\" xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\" xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\" xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\" xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\" xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\" xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\" xmlns:math=\"http://www.w3.org/1998/Math/MathML\" xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\" xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\" xmlns:koffice=\"http://www.koffice.org/2005/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"; xmlstream << "<office:body>"; xmlstream << "<office:text>"; xmlstream << "<text:p text:style-name=\"P1\"><?opendocument cursor-position?></text:p>"; xmlstream << "<draw:path svg:d=\"M10,10L100,100\"></draw:path>"; xmlstream << "</office:text>"; xmlstream << "</office:body>"; xmlstream << "</office:document-content>"; xmldevice.close(); KoXmlDocument doc; QString errorMsg; int errorLine = 0; int errorColumn = 0; QCOMPARE(doc.setContent(&xmldevice, true, &errorMsg, &errorLine, &errorColumn), true); QCOMPARE(errorMsg.isEmpty(), true); QCOMPARE(errorLine, 0); QCOMPARE(errorColumn, 0); KoXmlElement contentElement = doc.documentElement(); KoXmlElement bodyElement = contentElement.firstChild().toElement(); // XXX: When loading is implemented, these no doubt have to be // sensibly filled. KoOdfStylesReader stylesReader; KoOdfLoadingContext odfContext(stylesReader, 0); KoShapeLoadingContext shapeContext(odfContext, 0); KoXmlElement textElement = bodyElement.firstChild().firstChild().toElement(); QVERIFY(textElement.tagName() == "p"); QCOMPARE(factory->supports(textElement, shapeContext), false); KoXmlElement pathElement = bodyElement.firstChild().lastChild().toElement(); QVERIFY(pathElement.tagName() == "path"); QCOMPARE(factory->supports(pathElement, shapeContext), true); KoShape *shape = factory->createDefaultShape(); QVERIFY(shape); QVERIFY(shape->loadOdf(pathElement, shapeContext)); delete shape; delete factory; }
void TestKoShapeFactory::testCreateDefaultShape() { KoShapeFactoryBase * factory = new KoPathShapeFactory(QStringList()); KoShape *shape = factory->createDefaultShape(); QVERIFY(shape != 0); delete shape; delete factory; }
/// KoTextOnShapeContainer KoTextOnShapeContainer::KoTextOnShapeContainer(KoShape *childShape, KoResourceManager *documentResources) : KoShapeContainer(*(new KoTextOnShapeContainerPrivate(this))) { Q_D(KoTextOnShapeContainer); Q_ASSERT(childShape); d->content = childShape; setSize(childShape->size()); setZIndex(childShape->zIndex()); setTransformation(childShape->transformation()); if (childShape->parent()) { childShape->parent()->addShape(this); childShape->setParent(0); } childShape->setPosition(QPointF()); // since its relative to my position, this won't move it childShape->setSelectable(false); d->model = new KoTextOnShapeContainerModel(this, d); addShape(childShape); QSet<KoShape*> delegates; delegates << childShape; KoShapeFactoryBase *factory = KoShapeRegistry::instance()->get("TextShapeID"); if (factory) { // not installed, thats too bad, but allowed d->textShape = factory->createDefaultShape(documentResources); Q_ASSERT(d->textShape); // would be a bug in the text shape; if (d->resizeBehavior == TextFollowsPreferredTextRect) { d->textShape->setSize(d->preferredTextRect.size()); } else { d->textShape->setSize(size()); } d->textShape->setTransformation(childShape->transformation()); if (d->resizeBehavior == TextFollowsPreferredTextRect) { d->textShape->setPosition(d->preferredTextRect.topLeft()); } KoTextShapeDataBase *shapeData = qobject_cast<KoTextShapeDataBase*>(d->textShape->userData()); Q_ASSERT(shapeData); // would be a bug in kotext shapeData->setVerticalAlignment(Qt::AlignVCenter); addShape(d->textShape); d->textShape->setZIndex(childShape->zIndex() + 1); d->textShape->setSelectable(false); delegates << d->textShape; } else { kWarning(30006) << "Text shape factory not found"; } static_cast<KoTextOnShapeContainerModel*>(d->model)->lock = false; setToolDelegates(delegates); }
KoShape *KoTosContainer::createTextShape(KoDocumentResourceManager *documentResources) { if (!documentResources) { warnFlake << "KoDocumentResourceManager not found"; return 0; } Q_D(KoTosContainer); delete textShape(); delete d->model; d->model = new KoTosContainerModel(); QSet<KoShape*> delegates; delegates << this; KoShape *textShape = 0; KoShapeFactoryBase *factory = KoShapeRegistry::instance()->get("TextShapeID"); if (factory) { // not installed, thats too bad, but allowed textShape = factory->createDefaultShape(documentResources); Q_ASSERT(textShape); // would be a bug in the text shape; if (d->resizeBehavior == TextFollowsPreferredTextRect) { textShape->setSize(d->preferredTextRect.size()); } else { textShape->setSize(size()); } if (d->resizeBehavior == TextFollowsPreferredTextRect) { textShape->setPosition(d->preferredTextRect.topLeft()); } else { textShape->setPosition(QPointF(0, 0)); } textShape->setSelectable(false); textShape->setRunThrough(runThrough()); KoTextShapeDataBase *shapeData = qobject_cast<KoTextShapeDataBase*>(textShape->userData()); Q_ASSERT(shapeData); // would be a bug in kotext // TODO check if that is correct depending on the resize mode shapeData->setVerticalAlignment(Qt::AlignVCenter); addShape(textShape); // textShape->setZIndex(zIndex() + 1); // not needed as there as the text shape is the only sub shape delegates << textShape; } else { warnFlake << "Text shape factory not found"; } setToolDelegates(delegates); return textShape; }
KoCreateShapeStrategy::KoCreateShapeStrategy(KoCreateShapesTool *tool, const QPointF &clicked) : KoShapeRubberSelectStrategy(tool, clicked, tool->canvas()->snapToGrid()) { KoCreateShapesTool *parent = static_cast<KoCreateShapesTool*>(d_ptr->tool); KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value(parent->shapeId()); if (factory) { const KoProperties *props = parent->shapeProperties(); KoShape *shape; if (props) { shape = factory->createShape(props); } else { shape = factory->createDefaultShape(); } m_outline = shape->outline(); m_outlineBoundingRect = m_outline.boundingRect(); delete 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; }
KoShape* KisShapeToolHelper::createEllipseShape(const QRectF& rect) { KoShape* shape; KoShapeFactoryBase *rectFactory = KoShapeRegistry::instance()->value("EllipseShape"); if (rectFactory) { shape = rectFactory->createDefaultShape(); shape->setSize(rect.size()); shape->setPosition(rect.topLeft()); } else { //Fallback if the plugin wasn't found KoPathShape* path = new KoPathShape(); path->setShapeId(KoPathShapeId); QPointF rightMiddle = QPointF(rect.left() + rect.width(), rect.top() + rect.height() / 2); path->moveTo(rightMiddle); path->arcTo(rect.width() / 2, rect.height() / 2, 0, 360.0); path->close(); path->normalize(); shape = path; } return shape; }
KoShape* KisShapeToolHelper::createRectangleShape(const QRectF& rect) { KoShape* shape; KoShapeFactoryBase *rectFactory = KoShapeRegistry::instance()->value("RectangleShape"); if (rectFactory) { shape = rectFactory->createDefaultShape(); shape->setSize(rect.size()); shape->setPosition(rect.topLeft()); } else { //Fallback if the plugin wasn't found KoPathShape* path = new KoPathShape(); path->setShapeId(KoPathShapeId); path->moveTo(rect.topLeft()); path->lineTo(rect.topLeft() + QPointF(rect.width(), 0)); path->lineTo(rect.bottomRight()); path->lineTo(rect.topLeft() + QPointF(0, rect.height())); path->close(); path->normalize(); shape = path; } return shape; }
ChartShape::ChartShape(KoDocumentResourceManager *resourceManager) : KoFrameShape(KoXmlNS::draw, "object") , KoShapeContainer(new ChartLayout) , d (new Private(this)) { d->resourceManager = resourceManager; setShapeId(ChartShapeId); // Instantiated all children first d->proxyModel = new ChartProxyModel(this, &d->tableSource); d->plotArea = new PlotArea(this); d->document = new ChartDocument(this); d->legend = new Legend(this); // Configure the plotarea. // We need this as the very first step, because some methods // here rely on the d->plotArea pointer. addShape(d->plotArea); d->plotArea->plotAreaInit(); d->plotArea->setZIndex(0); setClipped(d->plotArea, true); setInheritsTransform(d->plotArea, true); // Configure the legend. d->legend->setVisible(true); d->legend->setZIndex(1); setClipped(d->legend, true); setInheritsTransform(d->legend, true); // A few simple defaults (chart type and subtype in this case) setChartType(BarChartType); setChartSubType(NormalChartSubtype); // Create the Title, which is a standard TextShape. KoShapeFactoryBase *textShapeFactory = KoShapeRegistry::instance()->value(TextShapeId); if (textShapeFactory) d->title = textShapeFactory->createDefaultShape(resourceManager); // Potential problem 1) No TextShape installed if (!d->title) { d->title = new TextLabelDummy; if (ENABLE_USER_INTERACTION) KMessageBox::error(0, i18n("The plugin needed for displaying text labels in a chart is not available."), i18n("Plugin Missing")); // Potential problem 2) TextShape incompatible } else if (dynamic_cast<TextLabelData*>(d->title->userData()) == 0 && ENABLE_USER_INTERACTION) KMessageBox::error(0, i18n("The plugin needed for displaying text labels is not compatible with the current version of the chart Flake shape."), i18n("Plugin Incompatible")); // In both cases we need a KoTextShapeData instance to function. This is // enough for unit tests, so there has to be no TextShape plugin doing the // actual text rendering, we just need KoTextShapeData which is in the libs. if (dynamic_cast<TextLabelData*>(d->title->userData()) == 0) { TextLabelData *dataDummy = new TextLabelData; KoTextDocumentLayout *documentLayout = new KoTextDocumentLayout(dataDummy->document()); dataDummy->document()->setDocumentLayout(documentLayout); d->title->setUserData(dataDummy); } // Start with a reasonable default size that we can base all following relative // positions of chart elements on. setSize(QSizeF(CM_TO_POINT(8), CM_TO_POINT(5))); // Add the title to the shape addShape(d->title); QFont font = titleData()->document()->defaultFont(); font.setPointSizeF(12.0); titleData()->document()->setDefaultFont(font); titleData()->document()->setHtml("<div align=\"center\">" + i18n("Title") + "</font></div>"); // Position the title center at the very top. d->title->setSize(QSizeF(CM_TO_POINT(5), CM_TO_POINT(0.7))); d->title->setPosition(QPointF(size().width() / 2.0 - d->title->size().width() / 2.0, 0.0)); d->title->setVisible(false); d->title->setZIndex(2); setClipped(d->title, true); setInheritsTransform(d->title, true); // Create the Subtitle and add it to the shape. if (textShapeFactory) d->subTitle = textShapeFactory->createDefaultShape(resourceManager); if (!d->subTitle) { d->subTitle = new TextLabelDummy; } if (dynamic_cast<TextLabelData*>(d->subTitle->userData()) == 0) { TextLabelData *dataDummy = new TextLabelData; KoTextDocumentLayout *documentLayout = new KoTextDocumentLayout(dataDummy->document()); dataDummy->document()->setDocumentLayout(documentLayout); d->subTitle->setUserData(dataDummy); } addShape(d->subTitle); font = subTitleData()->document()->defaultFont(); font.setPointSizeF(10.0); subTitleData()->document()->setDefaultFont(font); subTitleData()->document()->setHtml("<div align=\"center\">" + i18n("Subtitle") + "</div>"); // Position it in the center, just below the title. d->subTitle->setSize(QSizeF(CM_TO_POINT(5), CM_TO_POINT(0.6))); d->subTitle->setPosition(QPointF(size().width() / 2.0 - d->title->size().width() / 2.0, d->title->size().height())); d->subTitle->setVisible(false); d->subTitle->setZIndex(3); setClipped(d->subTitle, true); setInheritsTransform(d->subTitle, true); // Create the Footer and add it to the shape. if (textShapeFactory) d->footer = textShapeFactory->createDefaultShape(resourceManager); if (!d->footer) { d->footer = new TextLabelDummy; } if (dynamic_cast<TextLabelData*>(d->footer->userData()) == 0) { TextLabelData *dataDummy = new TextLabelData; KoTextDocumentLayout *documentLayout = new KoTextDocumentLayout(dataDummy->document()); dataDummy->document()->setDocumentLayout(documentLayout); d->footer->setUserData(dataDummy); } addShape(d->footer); font = footerData()->document()->defaultFont(); font.setPointSizeF(10.0); footerData()->document()->setDefaultFont(font); footerData()->document()->setHtml("<div align=\"center\">" + i18n("Footer") + "</div>"); // Position the footer in the center, at the bottom. d->footer->setSize(QSizeF(CM_TO_POINT(5), CM_TO_POINT(0.6))); d->footer->setPosition(QPointF(size().width() / 2.0 - d->footer->size().width() / 2.0, size().height() - d->footer->size().height())); d->footer->setVisible(false); d->footer->setZIndex(4); setClipped(d->footer, true); setInheritsTransform(d->footer, true); // Set default contour (for how text run around is done around this shape) // to prevent a crash in LO setTextRunAroundContour(KoShape::ContourBox); // Enable auto-resizing of chart labels foreach(KoShape *label, labels()) { TextLabelData *labelData = qobject_cast<TextLabelData*>(label->userData()); KoTextDocument doc(labelData->document()); //FIXME doc.setResizeMethod(KoTextDocument::AutoResize); }
void ConnectionTool::mousePressEvent(KoPointerEvent * event) { if (!m_currentShape) { return; } KoShape * hitShape = findShapeAtPosition(event->point); int hitHandle = handleAtPoint(m_currentShape, event->point); if (m_editMode == EditConnection && hitHandle >= 0) { // create connection handle change strategy m_currentStrategy = new KoPathConnectionPointStrategy(this, dynamic_cast<KoConnectionShape*>(m_currentShape), hitHandle); } else if (m_editMode == EditConnectionPoint) { if (hitHandle >= KoConnectionPoint::FirstCustomConnectionPoint) { // start moving custom connection point m_currentStrategy = new MoveConnectionPointStrategy(m_currentShape, hitHandle, this); } } else if (m_editMode == CreateConnection) { // create new connection shape, connect it to the active connection point // and start editing the new connection // create the new connection shape KoShapeFactoryBase *factory = KoShapeRegistry::instance()->value("KoConnectionShape"); KoShape *shape = factory->createDefaultShape(canvas()->shapeController()->resourceManager()); KoConnectionShape * connectionShape = dynamic_cast<KoConnectionShape*>(shape); if (!connectionShape) { delete shape; resetEditMode(); return; } //set connection type connectionShape->setType(m_connectionType); // get the position of the connection point we start our connection from QPointF cp = m_currentShape->shapeToDocument(m_currentShape->connectionPoint(m_activeHandle).position); // move both handles to that point connectionShape->moveHandle(0, cp); connectionShape->moveHandle(1, cp); // connect the first handle of the connection shape to our connection point if (!connectionShape->connectFirst(m_currentShape, m_activeHandle)) { delete shape; resetEditMode(); return; } //add connector label connectionShape->createTextShape(canvas()->shapeController()->resourceManager()); connectionShape->setPlainText(""); // create the connection edit strategy from the path tool m_currentStrategy = new KoPathConnectionPointStrategy(this, connectionShape, 1); if (!m_currentStrategy) { delete shape; resetEditMode(); return; } // update our handle data setEditMode(m_editMode, shape, 1); // add connection shape to the shape manager so it gets painted canvas()->shapeManager()->addShape(connectionShape); } else { // pressing on a shape in idle mode switches to corresponding edit mode if (hitShape) { if (dynamic_cast<KoConnectionShape*>(hitShape)) { int hitHandle = handleAtPoint(hitShape, event->point); setEditMode(EditConnection, hitShape, hitHandle); if (hitHandle >= 0) { // start editing connection shape m_currentStrategy = new KoPathConnectionPointStrategy(this, dynamic_cast<KoConnectionShape*>(m_currentShape), m_activeHandle); } } } else { resetEditMode(); } } }