Exemplo n.º 1
0
KisImageWSP KisKraLoader::loadXML(const KoXmlElement& element)
{
    QString attr;
    KisImageWSP image = 0;
    QString name;
    qint32 width;
    qint32 height;
    QString profileProductName;
    double xres;
    double yres;
    QString colorspacename;
    const KoColorSpace * cs;

    if ((attr = element.attribute(MIME)) == NATIVE_MIMETYPE) {

        if ((m_d->imageName = element.attribute(NAME)).isNull()) {
            m_d->errorMessages << i18n("Image does not have a name.");
            return KisImageWSP(0);
        }

        if ((attr = element.attribute(WIDTH)).isNull()) {
            m_d->errorMessages << i18n("Image does not specify a width.");
            return KisImageWSP(0);
        }
        width = attr.toInt();

        if ((attr = element.attribute(HEIGHT)).isNull()) {
            m_d->errorMessages << i18n("Image does not specify a height.");
            return KisImageWSP(0);
        }

        height = attr.toInt();

        m_d->imageComment = element.attribute(DESCRIPTION);

        xres = 100.0 / 72.0;
        if (!(attr = element.attribute(X_RESOLUTION)).isNull()) {
            if (attr.toDouble() > 1.0) {
                xres = attr.toDouble() / 72.0;
            }
        }

        yres = 100.0 / 72.0;
        if (!(attr = element.attribute(Y_RESOLUTION)).isNull()) {
            if (attr.toDouble() > 1.0) {
                yres = attr.toDouble() / 72.0;
            }
        }

        if ((colorspacename = element.attribute(COLORSPACE_NAME)).isNull()) {
            // An old file: take a reasonable default.
            // Krita didn't support anything else in those
            // days anyway.
            colorspacename = "RGBA";
        }

        profileProductName = element.attribute(PROFILE);
        // A hack for an old colorspacename
        convertColorSpaceNames(colorspacename, profileProductName);

        QString colorspaceModel = KoColorSpaceRegistry::instance()->colorSpaceColorModelId(colorspacename).id();
        QString colorspaceDepth = KoColorSpaceRegistry::instance()->colorSpaceColorDepthId(colorspacename).id();

        if (profileProductName.isNull()) {
            // no mention of profile so get default profile";
            cs = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, "");
        } else {
            cs = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, profileProductName);
        }

        if (cs == 0) {
            // try once more without the profile
            cs = KoColorSpaceRegistry::instance()->colorSpace(colorspaceModel, colorspaceDepth, "");
            if (cs == 0) {
                m_d->errorMessages << i18n("Image specifies an unsupported color model: %1.", colorspacename);
                return KisImageWSP(0);
            }
        }

        if (m_d->document) {
            image = new KisImage(m_d->document->createUndoStore(), width, height, cs, name);
        }
        else {
            image = new KisImage(0, width, height, cs, name);
        }
        image->setResolution(xres, yres);
        loadNodes(element, image, const_cast<KisGroupLayer*>(image->rootLayer().data()));

        KoXmlNode child;
        for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
            KoXmlElement e = child.toElement();
            if(e.tagName() == "ProjectionBackgroundColor") {
                if (e.hasAttribute("ColorData")) {
                    QByteArray colorData = QByteArray::fromBase64(e.attribute("ColorData").toLatin1());
                    KoColor color((const quint8*)colorData.data(), image->colorSpace());
                    image->setDefaultProjectionColor(color);
                }
            }

            if (e.tagName().toLower() == "animation") {
                loadAnimationMetadata(e, image);
            }
        }

        for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
            KoXmlElement e = child.toElement();
            if(e.tagName() == "compositions") {
                loadCompositions(e, image);
            }
        }
    }
    KoXmlNode child;
    for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
        KoXmlElement e = child.toElement();
        if (e.tagName() == "assistants") {
            loadAssistantsList(e);
        }
    }
    return image;
}
Exemplo n.º 2
0
bool Context::load( const KoXmlDocument &document ) {
    m_document = document; // create a copy, document is deleted under our feet
    
    // Check if this is the right app
    KoXmlElement elm = m_document.documentElement();
    QString value = elm.attribute( "mime", QString() );
    if ( value.isEmpty() ) {
        kError() << "No mime type specified!" << endl;
//        setErrorMessage( i18n( "Invalid document. No mimetype specified." ) );
        return false;
    } else if ( value != "application/x-vnd.kde.kplato" ) {
        kError() << "Unknown mime type " << value << endl;
//        setErrorMessage( i18n( "Invalid document. Expected mimetype application/x-vnd.kde.kplato, got %1", value ) );
        return false;
    }
    QString m_syntaxVersion = elm.attribute( "version", "0.0" );
    if ( m_syntaxVersion > "0.0" ) {
/*        int ret = KMessageBox::warningContinueCancel(
                      0, i18n( "This document was created with a newer version of KPlato (syntax version: %1)\n"
                               "Opening it in this version of KPlato will lose some information.", m_syntaxVersion ),
                      i18n( "File-Format Mismatch" ), KGuiItem( i18n( "Continue" ) ) );
        if ( ret == KMessageBox::Cancel ) {
            setErrorMessage( "USER_CANCELED" );
            return false;
        }*/
    }

#ifdef KOXML_USE_QDOM
    int numNodes = elm.childNodes().count();
#else
    int numNodes = elm.childNodesCount();
#endif
    
    KoXmlNode n = elm.firstChild();
    for ( ; ! n.isNull(); n = n.nextSibling() ) {
        if ( ! n.isElement() ) {
            continue;
        }
        KoXmlElement element = n.toElement();
        if ( element.tagName() == "context" ) {
            m_context = element;
            m_contextLoaded = true;
/*            currentView = element.attribute("current-view");
            currentEstimateType = element.attribute("estimate-type").toInt();
            currentSchedule = element.attribute("current-schedule").toLong();
            actionViewExpected = element.attribute("view-expected").toInt();
            actionViewOptimistic = element.attribute("view-optimistic").toInt();
            actionViewPessimistic = element.attribute("view-pessimistic").toInt();
        
            QDomNodeList list = element.childNodes();
            for (int i=0; i<list.count(); ++i) {
                if (list.item(i).isElement()) {
                    QDomElement e = list.item(i).toElement();
                    if (e.tagName() == "gantt-view") {
                        ganttview.ganttviewsize = e.attribute("ganttview-size").toInt();
                        ganttview.taskviewsize = e.attribute("taskview-size").toInt();
                        ganttview.currentNode = e.attribute("current-node");
                        ganttview.showResources = e.attribute("show-resources").toInt();
                        ganttview.showTaskName = e.attribute("show-taskname").toInt();
                        ganttview.showTaskLinks = e.attribute("show-tasklinks").toInt();
                        ganttview.showProgress = e.attribute("show-progress").toInt();
                        ganttview.showPositiveFloat = e.attribute("show-positivefloat").toInt();
                        ganttview.showCriticalTasks = attribute("show-criticaltasks").toInt();
                        ganttview.showCriticalPath = e.attribute("show-criticalpath").toInt();
                        ganttview.showNoInformation = e.attribute("show-noinformation").toInt();
        
                        QDomNodeList list = e.childNodes();
                        for (int i=0; i<list.count(); ++i) {
                            if (list.item(i).isElement()) {
                              QDomElement g = list.item(i).toElement();
                                if (g.tagName() == "closed-nodes") {
                                    QDomNodeList list = g.childNodes();
                                    for (int i=0; i<list.count(); ++i) {
                                        if (list.item(i).isElement()) {
                                            QDomElement ei = list.item(i).toElement();
                                            if (ei.tagName() == "node") {
                                                ganttview.closedNodes.append(ei.attribute("id"));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } else if (e.tagName() == "accounts-view") {
                        accountsview.accountsviewsize = e.attribute("accountsview-size").toInt();
                        accountsview.periodviewsize = e.attribute("periodview-size").toInt();
                        accountsview.date = QDate::fromString(e.attribute("date"), Qt::ISODate);
                        accountsview.period = e.attribute("period").toInt();
                        accountsview.cumulative = e.attribute("cumulative").toInt();
        
                        QDomNodeList list = e.childNodes();
                        for (int i=0; i<list.count(); ++i) {
                            if (list.item(i).isElement()) {
                                QDomElement g = list.item(i).toElement();
                                if (g.tagName() == "closed-items") {
                                    QDomNodeList list = g.childNodes();
                                    for (int i=0; i<list.count(); ++i) {
                                        if (list.item(i).isElement()) {
                                            QDomElement ei = list.item(i).toElement();
                                            if (ei.tagName() == "account") {
                                                 accountsview.closedItems.append(ei.attribute("name"));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        kError()<<"Unknown tag: "<<e.tagName()<<endl;
                    }
                }
            }*/
        }
    }
    return true;
}
Exemplo n.º 3
0
bool Doc::loadXML(const KoXmlDocument& doc, KoStore*)
{
    QPointer<KoUpdater> updater;
    if (progressUpdater()) {
        updater = progressUpdater()->startSubtask(1, "KSpread::Doc::loadXML");
        updater->setProgress(0);
    }

    d->spellListIgnoreAll.clear();
    // <spreadsheet>
    KoXmlElement spread = doc.documentElement();

    if (spread.attribute("mime") != "application/x-kspread" && spread.attribute("mime") != "application/vnd.kde.kspread") {
        setErrorMessage(i18n("Invalid document. Expected mimetype application/x-kspread or application/vnd.kde.kspread, got %1" , spread.attribute("mime")));
        return false;
    }

    bool ok = false;
    int version = spread.attribute("syntaxVersion").toInt(&ok);
    map()->setSyntaxVersion(ok ? version : 0);
    if (map()->syntaxVersion() > CURRENT_SYNTAX_VERSION) {
        int ret = KMessageBox::warningContinueCancel(
                      0, i18n("This document was created with a newer version of Calligra Sheets (syntax version: %1)\n"
                              "When you open it with this version of Calligra Sheets, some information may be lost.", map()->syntaxVersion()),
                      i18n("File Format Mismatch"), KStandardGuiItem::cont());
        if (ret == KMessageBox::Cancel) {
            setErrorMessage("USER_CANCELED");
            return false;
        }
    }

    // <locale>
    KoXmlElement loc = spread.namedItem("locale").toElement();
    if (!loc.isNull())
        static_cast<Localization*>(map()->calculationSettings()->locale())->load(loc);

    if (updater) updater->setProgress(5);

    KoXmlElement defaults = spread.namedItem("defaults").toElement();
    if (!defaults.isNull()) {
        double dim = defaults.attribute("row-height").toDouble(&ok);
        if (!ok)
            return false;
        map()->setDefaultRowHeight(dim);

        dim = defaults.attribute("col-width").toDouble(&ok);

        if (!ok)
            return false;

        map()->setDefaultColumnWidth(dim);
    }

    KoXmlElement ignoreAll = spread.namedItem("SPELLCHECKIGNORELIST").toElement();
    if (!ignoreAll.isNull()) {
        KoXmlElement spellWord = spread.namedItem("SPELLCHECKIGNORELIST").toElement();

        spellWord = spellWord.firstChild().toElement();
        while (!spellWord.isNull()) {
            if (spellWord.tagName() == "SPELLCHECKIGNOREWORD") {
                d->spellListIgnoreAll.append(spellWord.attribute("word"));
            }
            spellWord = spellWord.nextSibling().toElement();
        }
    }

    if (updater) updater->setProgress(40);
    // In case of reload (e.g. from konqueror)
    qDeleteAll(map()->sheetList());
    map()->sheetList().clear();

    KoXmlElement styles = spread.namedItem("styles").toElement();
    if (!styles.isNull()) {
        if (!map()->styleManager()->loadXML(styles)) {
            setErrorMessage(i18n("Styles cannot be loaded."));
            return false;
        }
    }

    // <map>
    KoXmlElement mymap = spread.namedItem("map").toElement();
    if (mymap.isNull()) {
        setErrorMessage(i18n("Invalid document. No map tag."));
        return false;
    }
    if (!map()->loadXML(mymap)) {
        return false;
    }

    // named areas
    const KoXmlElement areaname = spread.namedItem("areaname").toElement();
    if (!areaname.isNull())
        map()->namedAreaManager()->loadXML(areaname);

    //Backwards compatibility with older versions for paper layout
    if (map()->syntaxVersion() < 1) {
        KoXmlElement paper = spread.namedItem("paper").toElement();
        if (!paper.isNull()) {
            loadPaper(paper);
        }
    }

    if (updater) updater->setProgress(85);

    KoXmlElement element(spread.firstChild().toElement());
    while (!element.isNull()) {
        QString tagName(element.tagName());

        if (tagName != "locale" && tagName != "map" && tagName != "styles"
                && tagName != "SPELLCHECKIGNORELIST" && tagName != "areaname"
                && tagName != "paper") {
            // belongs to a plugin, load it and save it for later use
            QDomDocument doc;
            KoXml::asQDomElement(doc, element);
            d->savedDocParts[ tagName ] = doc;
        }

        element = element.nextSibling().toElement();
    }

    if (updater) updater->setProgress(90);
    initConfig();
    if (updater) updater->setProgress(100);

    return true;
}
Exemplo n.º 4
0
MetaInfo ZefaniaLex::buildIndexFromXmlDoc(KoXmlDocument *xmldoc)
{
    try {

    MetaInfo info;
    int couldBe = 0;//1 = RMac

    Document indexdoc;
    const QString index = indexPath();
    QString fileTitle;
    QString uid;
    QString type;

    QDir dir("/");
    dir.mkpath(index);

    RefText refText;
    refText.setSettings(m_settings);

    IndexWriter* writer = NULL;
    const TCHAR* stop_words[] = { NULL };
    standard::StandardAnalyzer an(stop_words);

    if(IndexReader::indexExists(index.toStdString().c_str())) {
        if(IndexReader::isLocked(index.toStdString().c_str())) {
            myDebug() << "Index was locked... unlocking it.";
            IndexReader::unlock(index.toStdString().c_str());
        }
    }
    writer = new IndexWriter(index.toStdString().c_str() , &an, true);

    writer->setMaxFieldLength(0x7FFFFFFFL);
    writer->setUseCompoundFile(false);

    KoXmlNode item = xmldoc->documentElement().firstChild();
    type = xmldoc->documentElement().toElement().attribute("type", "");

    for(int c = 0; !item.isNull();) {
        QString key = "";
        QString title = "";
        QString trans = "";
        QString pron = "";
        QString desc = "";
        KoXmlElement e = item.toElement();
        if(e.tagName().compare("INFORMATION", Qt::CaseInsensitive) == 0) {
            KoXmlNode title = item.namedItem("subject");
            KoXmlNode identifer = item.namedItem("identifier");

            fileTitle = title.toElement().text();
            uid = identifer.toElement().text();

        } else if(e.tagName().compare("item", Qt::CaseInsensitive) == 0) {
            key = e.attribute("id");
            KoXmlNode details = item.firstChild();
            while(!details.isNull()) {
                KoXmlElement edetails = details.toElement();
                if(edetails.tagName().compare("title", Qt::CaseInsensitive) == 0) {
                    title = edetails.text();
                } else if(edetails.tagName().compare("transliteration", Qt::CaseInsensitive) == 0) {
                    trans = edetails.text();
                } else if(edetails.tagName().compare("pronunciation", Qt::CaseInsensitive) == 0) {
                    KoXmlNode em = details.firstChild();
                    while(!em.isNull()) {
                        if(em.toElement().tagName().compare("em", Qt::CaseInsensitive) == 0)
                            pron = "<em>" + em.toElement().text() + "</em>";
                        em = em.nextSibling();
                    }
                } else if(edetails.tagName().compare("description", Qt::CaseInsensitive) == 0) {
                    KoXmlNode descNode = details.firstChild();
                    while(!descNode.isNull()) {
                        if(descNode.nodeType() == 2) {
                            desc += descNode.toText().data();
                        } else if(descNode.nodeType() == 1) {
                            KoXmlElement descElement = descNode.toElement();
                            if(descElement.tagName().compare("reflink", Qt::CaseInsensitive) == 0) {
                                if(descElement.hasAttribute("mscope")) {
                                    const QString mscope = descElement.attribute("mscope", ";;;");

                                    VerseUrl url;
                                    url.fromMscope(mscope);

                                    desc += " <a href=\"" + url.toString() + "\">" + refText.toString(url) + "</a> ";
                                } else if(descElement.hasAttribute("target")) {
                                    desc += descElement.text();
                                }

                            } else if(descElement.tagName().compare("see", Qt::CaseInsensitive) == 0) {
                                const QString target = descElement.attribute("target", "");
                                //todo: currently we assume target = x-self
                                StrongUrl url;
                                bool ok = url.fromText(descElement.text());
                                if(ok)
                                    desc += " <a href=\"" + url.toString() + "\">" + descElement.text() + "</a> ";
                            }
                        }

                        descNode = descNode.nextSibling();
                    }
                    desc += "<hr />";
                }
                details = details.nextSibling();
            }
            if(couldBe == 0) {
                if(key.toUpper() == "A-APF" || key.toUpper() == "X-NSN" || key.toUpper() == "V-PAP-DPN") {
                    couldBe = 1;
                }
            }
            QString content = "<h3 class='strongTitle'>" + key + " - " + title + "</h3>";
            if(!trans.isEmpty()) {
                content += " (" + trans + ") ";
            }
            if(!pron.isEmpty()) {
                content += " [" + pron + "] ";
            }
            content += "<br />" + desc;
            indexdoc.clear();
#ifdef OBV_USE_WSTRING
            indexdoc.add(*_CLNEW Field(_T("key"), key.toStdWString().c_str(), Field::STORE_YES |  Field::INDEX_TOKENIZED));
            indexdoc.add(*_CLNEW Field(_T("content"), content.toStdWString().c_str(), Field::STORE_YES |  Field::INDEX_TOKENIZED));
#else
            indexdoc.add(*_CLNEW Field(_T("key"), reinterpret_cast<const wchar_t *>(key.utf16()), Field::STORE_YES |  Field::INDEX_TOKENIZED));
            indexdoc.add(*_CLNEW Field(_T("content"), reinterpret_cast<const wchar_t *>(content.utf16()), Field::STORE_YES |  Field::INDEX_TOKENIZED));
#endif
            writer->addDocument(&indexdoc);

        }
        item = item.nextSibling();
        c++;
    }
    writer->setUseCompoundFile(true);
    writer->optimize();

    writer->close();
    delete writer;
    info.setName(fileTitle);
    info.setUID(uid);
    if(type == "x-strong") {
        info.setDefaultModule(OBVCore::DefaultStrongDictModule);
        info.setContent(OBVCore::StrongsContent);
    } else if(type == "x-dictionary") {
        if(couldBe == 1) {
            info.setDefaultModule(OBVCore::DefaultRMACDictModule);
            info.setContent(OBVCore::RMacContent);
        } else {
            info.setDefaultModule(OBVCore::DefaultDictModule);
        }
    }
    return info;
    }
    catch(...) {
        return MetaInfo();
    }
}
Exemplo n.º 5
0
void CalculationSettings::loadOdf(const KoXmlElement& body)
{
    KoXmlNode settings = KoXml::namedItemNS( body, KoXmlNS::table, "calculation-settings" );
    kDebug() <<"Calculation settings found?"<< !settings.isNull();
    if ( !settings.isNull() )
    {
        KoXmlElement element = settings.toElement();
        if ( element.hasAttributeNS( KoXmlNS::table,  "case-sensitive" ) )
        {
            d->caseSensitiveComparisons = true;
            QString value = element.attributeNS( KoXmlNS::table, "case-sensitive", "true" );
            if ( value == "false" )
                d->caseSensitiveComparisons = false;
        }
        else if ( element.hasAttributeNS( KoXmlNS::table, "precision-as-shown" ) )
        {
            d->precisionAsShown = false;
            QString value = element.attributeNS( KoXmlNS::table, "precision-as-shown", "false" );
            if ( value == "true" )
                d->precisionAsShown = true;
        }
        else if ( element.hasAttributeNS( KoXmlNS::table, "search-criteria-must-apply-to-whole-cell" ) )
        {
            d->wholeCellSearchCriteria = true;
            QString value = element.attributeNS( KoXmlNS::table, "search-criteria-must-apply-to-whole-cell", "true" );
            if ( value == "false" )
                d->wholeCellSearchCriteria = false;
        }
        else if ( element.hasAttributeNS( KoXmlNS::table, "automatic-find-labels" ) )
        {
            d->automaticFindLabels = true;
            QString value = element.attributeNS( KoXmlNS::table, "automatic-find-labels", "true" );
            if ( value == "false" )
                d->automaticFindLabels = false;
        }
        else if ( element.hasAttributeNS( KoXmlNS::table, "use-regular-expressions" ) )
        {
            d->useRegularExpressions = true;
            QString value = element.attributeNS( KoXmlNS::table, "use-regular-expressions", "true" );
            if ( value == "false" )
                d->useRegularExpressions = false;
        }
        else if ( element.hasAttributeNS( KoXmlNS::table, "null-year" ) )
        {
            d->refYear = 1930;
            QString value = element.attributeNS( KoXmlNS::table, "null-year", "1930" );
            if ( value == "false" )
                d->refYear = false;
        }

        forEachElement( element, settings )
        {
            if ( element.namespaceURI() != KoXmlNS::table )
                continue;
            else if ( element.tagName() ==  "null-date" )
            {
                d->refDate = QDate( 1899, 12, 30 );
                QString valueType = element.attributeNS( KoXmlNS::table, "value-type", "date" );
                if( valueType == "date" )
                {
                    QString value = element.attributeNS( KoXmlNS::table, "date-value", "1899-12-30" );
                    QDate date = QDate::fromString( value, Qt::ISODate );
                    if ( date.isValid() )
                        d->refDate = date;
                }
                else
                {
                    kDebug() <<"CalculationSettings: Error on loading null date."
                             << "Value type """ << valueType << """ not handled"
                             << ", falling back to default." << endl;
                    // NOTE Stefan: I don't know why different types are possible here!
                }
            }
            else if ( element.tagName() ==  "iteration" )
            {
                // TODO
            }
        }
    }
Exemplo n.º 6
0
bool PasteCommand::processXmlData(Element *element, KoXmlDocument *data)
{
    const QRect pasteArea = element->rect();
    Sheet *const sheet = element->sheet();
    Q_ASSERT(sheet == m_sheet);
    Map *const map = sheet->map();

    const KoXmlElement root = data->documentElement(); // "spreadsheet-snippet"
    if (root.hasAttribute("cut")) {
        const Region cutRegion(root.attribute("cut"), map, sheet);
        if (cutRegion.isValid()) {
            const Cell destination(sheet, pasteArea.topLeft());
            map->dependencyManager()->regionMoved(cutRegion, destination);
        }
    }

    const int sourceHeight = root.attribute("rows").toInt();
    const int sourceWidth  = root.attribute("columns").toInt();

    // Find size of rectangle that we want to paste to (either clipboard size or current selection)
    const bool noRowsInClipboard    = root.namedItem("rows").toElement().isNull();
    const bool noColumnsInClipboard = root.namedItem("columns").toElement().isNull();
    const bool noRowsSelected       = !Region::Range(pasteArea).isRow();
    const bool noColumnsSelected    = !Region::Range(pasteArea).isColumn();
    const bool biggerSelectedWidth  = pasteArea.width()  >= sourceWidth;
    const bool biggerSelectedHeight = pasteArea.height() >= sourceHeight;

    const int pasteWidth  = biggerSelectedWidth && noRowsSelected && noRowsInClipboard
                            ? pasteArea.width() : sourceWidth;
    const int pasteHeight = biggerSelectedHeight && noColumnsSelected && noColumnsInClipboard
                            ? pasteArea.height() : sourceHeight;

    const int xOffset = noRowsInClipboard ? pasteArea.left() - 1 : 0;
    const int yOffset = noColumnsInClipboard ? pasteArea.top() - 1 : 0;

    kDebug(36005) << "selected size (col x row):" << pasteArea.width() << 'x' << pasteArea.height();
    kDebug(36005) << "source size (col x row):" << sourceWidth << 'x' << sourceHeight;
    kDebug(36005) << "paste area size (col x row):" << pasteWidth << 'x' << pasteHeight;
    kDebug(36005) << "xOffset:" << xOffset << "yOffset:" << yOffset;

    // Determine the shift direction, if needed.
    if (m_insertMode == ShiftCells) {
        if (!noColumnsInClipboard && !noRowsInClipboard) {
            // There are columns and rows in the source data.
            m_insertMode = ShiftCellsRight; // faster than down
        } else if (!noColumnsInClipboard) {
            // There are columns in the source data.
            m_insertMode = ShiftCellsRight;
        } else if (!noRowsInClipboard) {
            // There are rows in the source data.
            m_insertMode = ShiftCellsDown;
        } else {
            // Should not happen.
            // ShiftCells should only be set, if the data contains columns/rows.
            Q_ASSERT(false);
            m_insertMode = ShiftCellsRight; // faster than down
        }
    }

    const bool noColumns = noColumnsInClipboard && noColumnsSelected;
    const bool noRows = noRowsInClipboard && noRowsSelected;

    // Shift cells down.
    if (m_insertMode == ShiftCellsDown) {
        // Cases:
        // 1. Columns AND rows are contained in either source or selection
        // 1.a Columns in source and rows in selection
        //      I.e. yOffset=0
        //      Clear everything.
        //      Taking the column data/style and fill all columns.
        // 1.b Columns and rows in source, but not in selection
        //      I.e. xOffset=0,yOffset=0
        //      Leave everything as is? No, data from different sheet is possible!
        //      Clear everything.
        //      Fill with the source column/row data/style,
        //      i.e. the sheet data becomes equal to the source data.
        //      Same procedure as in 1.e
        // 1.c Columns and rows in selection, but not in source
        //      Clear everything.
        //      Fill with the source data. Tiling -> HUGE task!
        // 1.d Rows in source and columns in selection
        //      I.e. xOffset=0
        //      Clear everything.
        //      Taking the row data/style and fill all rows.
        // 1.e Columns AND rows in both
        //      I.e. xOffset=0,yOffset=0
        //      Leave everything as is? No, data from different sheet is possible!
        //      Clear everything.
        //      Fill with the source column/row data/style,
        //      i.e. the sheet data becomes equal to the source data.
        //      Same procedure as in 1.b
        // 2. Columns are present in either source or selection, but no rows
        // 2a Columns in source
        //      I.e. yOffset=0
        //      Clear the appropriate columns in the paste area.
        //      Fill them with the source data.
        // 2b Columns in selection
        //      Clear the selected columns.
        //      Fill them with the source data. Tiling -> HUGE task!
        // 2c Columns in both
        //      I.e. yOffset=0
        //      Clear the selected columns.
        //      Fill them with the source column data/style.
        // 3. Rows are present in either source or selection, but no columns
        // 3a Rows in source
        //      I.e. xOffset=0
        //      Insert rows.
        //      Fill in data.
        // 3b Rows in selection
        //      Insert rows.
        //      Fill in data. Tiling -> HUGE task!
        // 3c Rows in both
        //      I.e. xOffset=0
        //      Insert rows.
        //      Fill in data/style from source rows.
        // 4. Neither column, nor rows are present
        //      Shift the cell down.
        //      Fill in data.
        if ((!noColumns && !noRows) || (!noColumns && noRows)) {
            // Everything or only columns present.
            DeleteCommand *const command = new DeleteCommand(this);
            command->setSheet(m_sheet);
            command->add(Region(pasteArea.x(), pasteArea.y(), pasteWidth, pasteHeight, sheet));
            command->setMode(DeleteCommand::OnlyCells);
        } else if (noColumns && !noRows) {
            // Rows present.
            InsertDeleteRowManipulator *const command = new InsertDeleteRowManipulator(this);
            command->setSheet(sheet);
            command->add(Region(pasteArea.x(), pasteArea.y(), pasteWidth, pasteHeight, sheet));
        } else {
            // Neither columns, nor rows present.
            ShiftManipulator *const command = new ShiftManipulator(this);
            command->setSheet(sheet);
            command->add(Region(pasteArea.x(), pasteArea.y(), pasteWidth, pasteHeight, sheet));
            command->setDirection(ShiftManipulator::ShiftBottom);
        }
    }
    // Shift cells right.
    if (m_insertMode == ShiftCellsRight) {
        // Cases:
        // Same as for ShiftCellsDown,
        // except that clearing and inserting are exchanged for cases 2 and 3.
        // Shifting a column to the right is the same as column insertion.
        // Shifting a row to the right is the same as clearing the row.
        if ((!noColumns && !noRows) || (noColumns && !noRows)) {
            // Everything or only rows present.
            DeleteCommand *const command = new DeleteCommand(this);
            command->setSheet(m_sheet);
            command->add(Region(pasteArea.x(), pasteArea.y(), pasteWidth, pasteHeight, sheet));
            command->setMode(DeleteCommand::OnlyCells);
        } else if (!noColumns && noRows) {
            // Columns present.
            InsertDeleteColumnManipulator *const command = new InsertDeleteColumnManipulator(this);
            command->setSheet(sheet);
            command->add(Region(pasteArea.x(), pasteArea.y(), pasteWidth, pasteHeight, sheet));
        } else {
            // Neither columns, nor rows present.
            ShiftManipulator *const command = new ShiftManipulator(this);
            command->setSheet(sheet);
            command->add(Region(pasteArea.x(), pasteArea.y(), pasteWidth, pasteHeight, sheet));
            command->setDirection(ShiftManipulator::ShiftRight);
        }
    }

    // This command will collect as many cell loads as possible in the iteration.
    PasteCellCommand *pasteCellCommand = 0;

    KoXmlElement e = root.firstChild().toElement(); // "columns", "rows" or "cell"
    for (; !e.isNull(); e = e.nextSibling().toElement()) {
        // If the element is not a cell, unset the pasteCellCommand pointer.
        // If existing, it is attached as child commnand, so no leaking here.
        if (e.tagName() != "cell") {
            pasteCellCommand = 0;
        }

        // entire columns given
        if (e.tagName() == "columns" && !sheet->isProtected()) {
            const int number = e.attribute("count").toInt();
            if (m_insertMode == NoInsertion) {
                // Clear the existing content; not the column style.
                DeleteCommand *const command = new DeleteCommand(this);
                command->setSheet(m_sheet);
                const int col = e.attribute("column").toInt();
                const int cols = qMax(pasteArea.width(), number);
                const Region region(col + xOffset, 1, cols, KS_rowMax, m_sheet);
                command->add(region);
                command->setMode(DeleteCommand::OnlyCells);
            }

            // Set the column style.
            ColumnFormat columnFormat;
            columnFormat.setSheet(sheet);
            KoXmlElement c = e.firstChild().toElement();
            for (; !c.isNull(); c = c.nextSibling().toElement()) {
                if (c.tagName() != "column") {
                    continue;
                }
                if (columnFormat.load(c, xOffset, m_pasteMode)) {
                    const int col = columnFormat.column();
                    const int cols = qMax(pasteArea.width(), number);
                    for (int coff = 0; col - xOffset + coff <= cols; coff += number) {
                        ColumnStyleCommand *const command = new ColumnStyleCommand(this);
                        command->setSheet(m_sheet);
                        command->add(Region(col + coff, 1, 1, 1, m_sheet));
                        command->setTemplate(columnFormat);
                    }
                }
            }
        }

        // entire rows given
        if (e.tagName() == "rows" && !sheet->isProtected()) {
            const int number = e.attribute("count").toInt();
            if (m_insertMode == NoInsertion) {
                // Clear the existing content; not the row style.
                DeleteCommand *const command = new DeleteCommand(this);
                command->setSheet(m_sheet);
                const int row = e.attribute("row").toInt();
                const int rows = qMax(pasteArea.height(), number);
                const Region region(1, row + yOffset, KS_colMax, rows, m_sheet);
                command->add(region);
                command->setMode(DeleteCommand::OnlyCells);
            }

            // Set the row style.
            RowFormat rowFormat;
            rowFormat.setSheet(sheet);
            KoXmlElement c = e.firstChild().toElement();
            for (; !c.isNull(); c = c.nextSibling().toElement()) {
                if (c.tagName() != "row") {
                    continue;
                }
                if (rowFormat.load(c, yOffset, m_pasteMode)) {
                    const int row = rowFormat.row();
                    const int rows = qMax(pasteArea.height(), number);
                    for (int roff = 0; row - yOffset + roff <= rows; roff += number) {
                        RowStyleCommand *const command = new RowStyleCommand(this);
                        command->setSheet(m_sheet);
                        command->add(Region(1, rowFormat.row(), 1, 1, m_sheet));
                        command->setTemplate(rowFormat);
                    }
                }
            }
        }

        if (e.tagName() == "cell") {
            // Create a new PasteCellCommand, if necessary.
            if (!pasteCellCommand) {
                pasteCellCommand = new PasteCellCommand(this);
                pasteCellCommand->setSheet(m_sheet);
                pasteCellCommand->m_pasteMode = m_pasteMode;
                pasteCellCommand->m_pasteOperation = m_operation;
                pasteCellCommand->m_pasteFC = m_pasteFC;
            }

            // Source cell location:
            const int row = e.attribute("row").toInt();
            const int col = e.attribute("column").toInt();

            // tile the selection with the clipboard contents
            for (int roff = 0; row + roff <= pasteHeight; roff += sourceHeight) {
                for (int coff = 0; col + coff <= pasteWidth; coff += sourceWidth) {
                    kDebug(36005) << "cell at" << (col + xOffset + coff) << ',' << (row + yOffset + roff)
                    << " with roff,coff=" << roff << ',' << coff
                    << ", xOffset:" << xOffset << ", yOffset:" << yOffset << endl;

                    // Destination cell:
                    const Cell cell(sheet, col + xOffset + coff, row + yOffset + roff);
                    // Do nothing, if the sheet and the cell are protected.
                    if (sheet->isProtected() && !cell.style().notProtected()) {
                        continue;
                    }
                    // Add the destination cell and the XML element itself.
                    pasteCellCommand->addXmlElement(cell, e);
                }
            }
        }
    }
    return true;
}
Exemplo n.º 7
0
void SvgParser::applyFilter(KoShape *shape)
{
    SvgGraphicsContext *gc = m_context.currentGC();
    if (! gc)
        return;

    if (gc->filterId.isEmpty())
        return;

    SvgFilterHelper *filter = findFilter(gc->filterId);
    if (! filter)
        return;

    KoXmlElement content = filter->content();

    // parse filter region
    QRectF bound(shape->position(), shape->size());
    // work on bounding box without viewbox tranformation applied
    // so user space coordinates of bounding box and filter region match up
    bound = gc->viewboxTransform.inverted().mapRect(bound);

    QRectF filterRegion(filter->position(bound), filter->size(bound));

    // convert filter region to boundingbox units
    QRectF objectFilterRegion;
    objectFilterRegion.setTopLeft(SvgUtil::userSpaceToObject(filterRegion.topLeft(), bound));
    objectFilterRegion.setSize(SvgUtil::userSpaceToObject(filterRegion.size(), bound));

    KoFilterEffectLoadingContext context(m_context.xmlBaseDir());
    context.setShapeBoundingBox(bound);
    // enable units conversion
    context.enableFilterUnitsConversion(filter->filterUnits() == SvgFilterHelper::UserSpaceOnUse);
    context.enableFilterPrimitiveUnitsConversion(filter->primitiveUnits() == SvgFilterHelper::UserSpaceOnUse);

    KoFilterEffectRegistry *registry = KoFilterEffectRegistry::instance();

    KoFilterEffectStack *filterStack = 0;

    QSet<QString> stdInputs;
    stdInputs << "SourceGraphic" << "SourceAlpha";
    stdInputs << "BackgroundImage" << "BackgroundAlpha";
    stdInputs << "FillPaint" << "StrokePaint";

    QMap<QString, KoFilterEffect*> inputs;

    // create the filter effects and add them to the shape
    for (KoXmlNode n = content.firstChild(); !n.isNull(); n = n.nextSibling()) {
        KoXmlElement primitive = n.toElement();
        KoFilterEffect *filterEffect = registry->createFilterEffectFromXml(primitive, context);
        if (!filterEffect) {
            debugFlake << "filter effect" << primitive.tagName() << "is not implemented yet";
            continue;
        }

        const QString input = primitive.attribute("in");
        if (!input.isEmpty()) {
            filterEffect->setInput(0, input);
        }
        const QString output = primitive.attribute("result");
        if (!output.isEmpty()) {
            filterEffect->setOutput(output);
        }

        QRectF subRegion;
        // parse subregion
        if (filter->primitiveUnits() == SvgFilterHelper::UserSpaceOnUse) {
            const QString xa = primitive.attribute("x");
            const QString ya = primitive.attribute("y");
            const QString wa = primitive.attribute("width");
            const QString ha = primitive.attribute("height");

            if (xa.isEmpty() || ya.isEmpty() || wa.isEmpty() || ha.isEmpty()) {
                bool hasStdInput = false;
                bool isFirstEffect = filterStack == 0;
                // check if one of the inputs is a standard input
                foreach(const QString &input, filterEffect->inputs()) {
                    if ((isFirstEffect && input.isEmpty()) || stdInputs.contains(input)) {
                        hasStdInput = true;
                        break;
                    }
                }
                if (hasStdInput || primitive.tagName() == "feImage") {
                    // default to 0%, 0%, 100%, 100%
                    subRegion.setTopLeft(QPointF(0, 0));
                    subRegion.setSize(QSizeF(1, 1));
                } else {
                    // defaults to bounding rect of all referenced nodes
                    foreach(const QString &input, filterEffect->inputs()) {
                        if (!inputs.contains(input))
                            continue;

                        KoFilterEffect *inputFilter = inputs[input];
                        if (inputFilter)
                            subRegion |= inputFilter->filterRect();
                    }
                }
            } else {
                const qreal x = parseUnitX(xa);
                const qreal y = parseUnitY(ya);
                const qreal w = parseUnitX(wa);
                const qreal h = parseUnitY(ha);
                subRegion.setTopLeft(SvgUtil::userSpaceToObject(QPointF(x, y), bound));
                subRegion.setSize(SvgUtil::userSpaceToObject(QSizeF(w, h), bound));
            }
        } else {
Exemplo n.º 8
0
bool SvgParser::parseGradient(const KoXmlElement &e, const KoXmlElement &referencedBy)
{
    // IMPROVEMENTS:
    // - Store the parsed colorstops in some sort of a cache so they don't need to be parsed again.
    // - A gradient inherits attributes it does not have from the referencing gradient.
    // - Gradients with no color stops have no fill or stroke.
    // - Gradients with one color stop have a solid color.

    SvgGraphicsContext *gc = m_context.currentGC();
    if (!gc)
        return false;

    SvgGradientHelper gradhelper;

    if (e.hasAttribute("xlink:href")) {
        QString href = e.attribute("xlink:href").mid(1);
        if (! href.isEmpty()) {
            // copy the referenced gradient if found
            SvgGradientHelper *pGrad = findGradient(href);
            if (pGrad)
                gradhelper = *pGrad;
        } else {
            //gc->fillType = SvgGraphicsContext::None; // <--- TODO Fill OR Stroke are none
            return false;
        }
    }

    // Use the gradient that is referencing, or if there isn't one, the original gradient.
    KoXmlElement b;
    if (!referencedBy.isNull())
        b = referencedBy;
    else
        b = e;

    QString gradientId = b.attribute("id");

    if (! gradientId.isEmpty()) {
        // check if we have this gradient already parsed
        // copy existing gradient if it exists
        if (m_gradients.find(gradientId) != m_gradients.end())
            gradhelper.copyGradient(m_gradients[ gradientId ].gradient());
    }

    if (b.attribute("gradientUnits") == "userSpaceOnUse")
        gradhelper.setGradientUnits(SvgGradientHelper::UserSpaceOnUse);

    // parse color prop
    QColor c = gc->currentColor;

    if (!b.attribute("color").isEmpty()) {
        m_context.styleParser().parseColor(c, b.attribute("color"));
    } else {
        // try style attr
        QString style = b.attribute("style").simplified();
        const QStringList substyles = style.split(';', QString::SkipEmptyParts);
        for (QStringList::ConstIterator it = substyles.begin(); it != substyles.end(); ++it) {
            QStringList substyle = it->split(':');
            QString command = substyle[0].trimmed();
            QString params  = substyle[1].trimmed();
            if (command == "color")
                m_context.styleParser().parseColor(c, params);
        }
    }
    gc->currentColor = c;

    if (b.tagName() == "linearGradient") {
        QLinearGradient *g = new QLinearGradient();
        if (gradhelper.gradientUnits() == SvgGradientHelper::ObjectBoundingBox) {
            g->setCoordinateMode(QGradient::ObjectBoundingMode);
            g->setStart(QPointF(SvgUtil::fromPercentage(b.attribute("x1", "0%")),
                                SvgUtil::fromPercentage(b.attribute("y1", "0%"))));
            g->setFinalStop(QPointF(SvgUtil::fromPercentage(b.attribute("x2", "100%")),
                                    SvgUtil::fromPercentage(b.attribute("y2", "0%"))));
        } else {
            g->setStart(QPointF(SvgUtil::fromUserSpace(b.attribute("x1").toDouble()),
                                SvgUtil::fromUserSpace(b.attribute("y1").toDouble())));
            g->setFinalStop(QPointF(SvgUtil::fromUserSpace(b.attribute("x2").toDouble()),
                                    SvgUtil::fromUserSpace(b.attribute("y2").toDouble())));
        }
        // preserve color stops
        if (gradhelper.gradient())
            g->setStops(gradhelper.gradient()->stops());
        gradhelper.setGradient(g);
    } else if (b.tagName() == "radialGradient") {
        QRadialGradient *g = new QRadialGradient();
        if (gradhelper.gradientUnits() == SvgGradientHelper::ObjectBoundingBox) {
            g->setCoordinateMode(QGradient::ObjectBoundingMode);
            g->setCenter(QPointF(SvgUtil::fromPercentage(b.attribute("cx", "50%")),
                                 SvgUtil::fromPercentage(b.attribute("cy", "50%"))));
            g->setRadius(SvgUtil::fromPercentage(b.attribute("r", "50%")));
            g->setFocalPoint(QPointF(SvgUtil::fromPercentage(b.attribute("fx", "50%")),
                                     SvgUtil::fromPercentage(b.attribute("fy", "50%"))));
        } else {
            g->setCenter(QPointF(SvgUtil::fromUserSpace(b.attribute("cx").toDouble()),
                                 SvgUtil::fromUserSpace(b.attribute("cy").toDouble())));
            g->setFocalPoint(QPointF(SvgUtil::fromUserSpace(b.attribute("fx").toDouble()),
                                     SvgUtil::fromUserSpace(b.attribute("fy").toDouble())));
            g->setRadius(SvgUtil::fromUserSpace(b.attribute("r").toDouble()));
        }
        // preserve color stops
        if (gradhelper.gradient())
            g->setStops(gradhelper.gradient()->stops());
        gradhelper.setGradient(g);
    } else {
        return false;
    }

    // handle spread method
    QString spreadMethod = b.attribute("spreadMethod");
    if (!spreadMethod.isEmpty()) {
        if (spreadMethod == "reflect")
            gradhelper.gradient()->setSpread(QGradient::ReflectSpread);
        else if (spreadMethod == "repeat")
            gradhelper.gradient()->setSpread(QGradient::RepeatSpread);
        else
            gradhelper.gradient()->setSpread(QGradient::PadSpread);
    } else
        gradhelper.gradient()->setSpread(QGradient::PadSpread);

    // Parse the color stops. The referencing gradient does not have colorstops,
    // so use the stops from the gradient it references to (e in this case and not b)
    m_context.styleParser().parseColorStops(gradhelper.gradient(), e);
    gradhelper.setTransform(SvgUtil::parseTransform(b.attribute("gradientTransform")));
    m_gradients.insert(gradientId, gradhelper);

    return true;
}