void KoStyleStack::push( const QDomElement& style ) { m_stack.append( style ); #ifdef DEBUG_STYLESTACK kdDebug(30003) << "pushed " << style.attributeNS( m_styleNSURI, "name", QString::null ) << " -> count=" << m_stack.count() << endl; #endif }
QString ElementWrapper::xmlBase() const { if (!d->xmlBaseParsed) // xmlBase not computed yet { QDomElement current = d->element; while (!current.isNull()) { if (current.hasAttributeNS(xmlNamespace(), QLatin1String("base"))) { d->xmlBase = current.attributeNS(xmlNamespace(), QLatin1String("base")); return d->xmlBase; } QDomNode parent = current.parentNode(); if (!parent.isNull() && parent.isElement()) current = parent.toElement(); else current = QDomElement(); } d->xmlBaseParsed = true; } return d->xmlBase; }
bool KoStyleStack::isUserStyle( const QDomElement& e, const QString& family ) const { if ( e.attributeNS( m_styleNSURI, "family", QString::null ) != family ) return false; const QDomElement parent = e.parentNode().toElement(); //kdDebug(30003) << k_funcinfo << "tagName=" << e.tagName() << " parent-tagName=" << parent.tagName() << endl; return parent.localName() == "styles" /*&& parent.namespaceURI() == KoXmlNS::office*/; }
bool KPrTextDocument::loadSpanTag( const QDomElement& tag, KoOasisContext& context, KoTextParag* parag, uint pos, QString& textData, KoTextCustomItem* & customItem ) { const QString localName( tag.localName() ); const bool isTextNS = tag.namespaceURI() == KoXmlNS::text; kdDebug( 32500 ) << "KPrTextDocument::loadSpanTag: " << localName << endl; if ( isTextNS ) { if ( localName == "a" ) { QString href( tag.attributeNS( KoXmlNS::xlink, "href", QString::null ) ); if ( href.startsWith( "#" ) ) { context.styleStack().save(); // We have a reference to a bookmark (### TODO) // As we do not support it now, treat it as a <span> without formatting parag->loadOasisSpan( tag, context, pos ); // recurse context.styleStack().restore(); } else { // The text is contained in a <span> inside the <a> element. In theory // we could have multiple spans there, but OO ensures that there is always only one, // splitting the hyperlink if necessary (at format changes). // Note that we ignore the formatting of the span. QDomElement spanElem = KoDom::namedItemNS( tag, KoXmlNS::text, "span" ); QString text; if ( spanElem.isNull() ) text = tag.text(); if ( spanElem.isNull() ) text = tag.text(); else { // The save/restore of the stack is done by the caller (KoTextParag::loadOasisSpan) // This allows to use the span's format for the variable. //kdDebug(32500) << "filling stack with " << spanElem.attributeNS( KoXmlNS::text, "style-name", QString::null ) << endl; context.fillStyleStack( spanElem, KoXmlNS::text, "style-name", "text" ); text = spanElem.text(); } textData = KoTextObject::customItemChar(); // hyperlink placeholder // unused tag.attributeNS( KoXmlNS::office, "name", QString::null ) KoVariableCollection& coll = context.variableCollection(); customItem = new KoLinkVariable( this, text, href, coll.formatCollection()->format( "STRING" ), &coll ); } return true; } } else // non "text:" tags { kdDebug()<<"Extension found tagName : "<< localName <<endl; } return false; }
QString KoStyleStack::attributeNS( const char* nsURI, const char* name, const char* detail ) const { QString fullName( name ); if ( detail ) { fullName += '-'; fullName += detail; } QValueList<QDomElement>::ConstIterator it = m_stack.end(); while ( it != m_stack.begin() ) { --it; QDomElement properties = KoDom::namedItemNS( *it, m_styleNSURI, m_propertiesTagName ); if ( properties.hasAttributeNS( nsURI, name ) ) return properties.attributeNS( nsURI, name, QString::null ); if ( detail && properties.hasAttributeNS( nsURI, fullName ) ) return properties.attributeNS( nsURI, fullName, QString::null ); } return QString::null; }
bool KoDocumentInfoUserMetadata::loadOasis( const QDomNode& metaDoc ) { QDomNode n = metaDoc.firstChild(); for ( ; !n.isNull(); n = n.nextSibling() ) { if (n.isElement()) { QDomElement e = n.toElement(); if ( e.namespaceURI() == KoXmlNS::meta && e.localName() == "user-defined" && !e.text().isEmpty() ) { QString name = e.attributeNS( KoXmlNS::meta, "name", QString::null ); if ( !m_reserved.contains( name ) ) m_metaList[ name ] = e.text(); } } } return true; }
bool KoDocumentInfoAuthor::loadOasis( const QDomNode& metaDoc ) { QDomElement e = KoDom::namedItemNS( metaDoc, KoXmlNS::dc, "creator" ); if ( !e.isNull() && !e.text().isEmpty() ) m_fullName = e.text(); QDomNode n = metaDoc.firstChild(); for ( ; !n.isNull(); n = n.nextSibling() ) { if (n.isElement()) { QDomElement e = n.toElement(); if ( e.namespaceURI() == KoXmlNS::meta && e.localName() == "user-defined" && !e.text().isEmpty() ) { QString name = e.attributeNS( KoXmlNS::meta, "name", QString::null ); if ( name == "initial" ) m_initial = e.text(); else if ( name == "author-title" ) m_title = e.text(); else if ( name == "company" ) m_company = e.text(); else if ( name == "email" ) m_email = e.text(); else if ( name == "telephone" ) m_telephoneHome = e.text(); else if ( name == "telephone-work" ) m_telephoneWork = e.text(); else if ( name == "fax" ) m_fax = e.text(); else if ( name == "country" ) m_country = e.text(); else if ( name == "postal-code" ) m_postalCode = e.text(); else if ( name == "city" ) m_city = e.text(); else if ( name == "street" ) m_street = e.text(); else if ( name == "position" ) m_position = e.text(); } } } return true; }
// Font size is a bit special. "115%" applies to "the fontsize of the parent style". // This can be generalized though (hasAttributeThatCanBePercentOfParent() ? :) // Although, if we also add support for fo:font-size-rel here then it's not general anymore. double KoStyleStack::fontSize() const { const QString name = "font-size"; double percent = 1; QValueList<QDomElement>::ConstIterator it = m_stack.end(); // reverse iterator while ( it != m_stack.begin() ) { --it; QDomElement properties = KoDom::namedItemNS( *it, m_styleNSURI, m_propertiesTagName ).toElement(); if ( properties.hasAttributeNS( m_foNSURI, name ) ) { const QString value = properties.attributeNS( m_foNSURI, name, QString::null ); if ( value.endsWith( "%" ) ) percent *= value.left( value.length() - 1 ).toDouble() / 100.0; else return percent * KoUnit::parseValue( value ); // e.g. 12pt } } return 0; }
void KoOasisLoadingContext::fillStyleStack( const QDomElement& object, const char* nsURI, const char* attrName, const char* family ) { // find all styles associated with an object and push them on the stack if ( object.hasAttributeNS( nsURI, attrName ) ) { const QString styleName = object.attributeNS( nsURI, attrName, QString::null ); const QDomElement* style = 0; bool isStyleAutoStyle = false; if ( m_useStylesAutoStyles ) { // When loading something from styles.xml, look into the styles.xml auto styles first style = m_styles.findStyleAutoStyle( styleName, family ); // and fallback to looking at styles(), which includes the user styles from styles.xml if ( style ) isStyleAutoStyle = true; } if ( !style ) style = m_styles.findStyle( styleName, family ); if ( style ) addStyles( style, family, isStyleAutoStyle ); else kdWarning(32500) << "fillStyleStack: no style named " << styleName << " found." << endl; } }
void AppUpdater::finishedRead( int id, bool errors ) { (void)errors; // we'll get called here alternately by the setHost( ) request and the actual GET request // we don't care about setHost, so just return and wait for the GET response if( id != httpGetID ) return; QDomDocument doc; QString err; int line, col; if (!doc.setContent(http.readAll(), true, &err, &line, &col)) { headline.setText( "<font size=4>Couldn't contact the update server...</font>" ); details.setText( QString( "Make sure you're connected to the internet." ) ); acceptButton.setText( tr("OK") ); acceptButton.disconnect( ); // make sure it wasn't connected by anything else previously connect( &acceptButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); removeBrowserAndIgnoreButton( ); if(!checkingOnStartup) this->show( ); return; } QDomElement channel = doc.documentElement().firstChild().toElement(); QDomNodeList items = channel.elementsByTagName("item"); QPair<QString, QString> latest(MCBUILDER_VERSION, ""); bool updateAvailable = false; for (int i=0, j=items.size(); i<j; i++) { QDomElement item = items.item(i).toElement(); if( item.isNull() ) continue; QDomNodeList enclosures = item.elementsByTagName("enclosure"); for (int k=0, l=enclosures.size(); k<l; k++) { QDomElement enclosure = enclosures.item(k).toElement(); if (enclosure.isNull()) continue; QString version = enclosure.attributeNS( "http://www.andymatuschak.org/xml-namespaces/sparkle", "version", "not-found" ); // each item can have multiple enclosures, of which at least one // should have a version field if (version == "not-found") continue; if( versionCompare(version, latest.first) > 0 ) { latest.first = version; QDomNodeList descs = item.elementsByTagName("description"); //I(descs.size() == 1); QDomElement desc = descs.item(0).toElement(); //I(!desc.isNull()); latest.second = desc.text(); updateAvailable = true; } } } // add the appropriate elements/info depending on whether an update is available if( updateAvailable ) { headline.setText( "<font size=4>A new version of mcbuilder is available!</font>" ); QString d = QString( "mcbuilder %1 is now available (you have %2). Would you like to download it?" ) .arg(latest.first).arg( MCBUILDER_VERSION ); details.setText( d ); browser.setHtml( latest.second ); acceptButton.setText( tr("Visit Download Page") ); acceptButton.disconnect( ); ignoreButton.disconnect( ); connect( &acceptButton, SIGNAL( clicked() ), this, SLOT( visitDownloadsPage() ) ); connect( &ignoreButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); if( textLayout.indexOf( &browser ) < 0 ) // if the browser's not in the layout, then insert it after the details line textLayout.insertWidget( textLayout.indexOf( &details ) + 1, &browser ); if( buttonLayout.indexOf( &ignoreButton ) < 0 ) // put the ignore button on the left buttonLayout.insertWidget( 0, &ignoreButton ); this->show( ); } else { headline.setText( "<font size=4>You're up to date!</font>" ); details.setText( QString( "You're running the latest version of mcbuilder, version %1." ).arg( MCBUILDER_VERSION ) ); acceptButton.setText( tr("OK") ); acceptButton.disconnect( ); connect( &acceptButton, SIGNAL( clicked() ), this, SLOT( accept() ) ); removeBrowserAndIgnoreButton( ); if(!checkingOnStartup) this->show( ); } }
channels_container_t RSS10Parser::Parse (const QDomDocument& doc, const IDType_t& feedId) const { channels_container_t result; QMap<QString, Channel_ptr> item2Channel; QDomElement root = doc.documentElement (); QDomElement channelDescr = root.firstChildElement ("channel"); while (!channelDescr.isNull ()) { Channel_ptr channel (new Channel (feedId)); channel->Title_ = channelDescr.firstChildElement ("title").text ().trimmed (); channel->Link_ = channelDescr.firstChildElement ("link").text (); channel->Description_ = channelDescr.firstChildElement ("description").text (); channel->PixmapURL_ = channelDescr.firstChildElement ("image") .firstChildElement ("url").text (); channel->LastBuild_ = GetDCDateTime (channelDescr); QDomElement itemsRoot = channelDescr.firstChildElement ("items"); QDomNodeList seqs = itemsRoot.elementsByTagNameNS (RDF_, "Seq"); channelDescr = channelDescr.nextSiblingElement ("channel"); if (!seqs.size ()) continue; QDomElement seqElem = seqs.at (0).toElement (); QDomNodeList lis = seqElem.elementsByTagNameNS (RDF_, "li"); for (int i = 0; i < lis.size (); ++i) item2Channel [lis.at (i).toElement ().attribute ("resource")] = channel; result.push_back (channel); } QDomElement itemDescr = root.firstChildElement ("item"); while (!itemDescr.isNull ()) { QString about = itemDescr.attributeNS (RDF_, "about"); if (item2Channel.contains (about)) { Item_ptr item (new Item (item2Channel [about]->ChannelID_)); item->Title_ = itemDescr.firstChildElement ("title").text (); item->Link_ = itemDescr.firstChildElement ("link").text (); item->Description_ = itemDescr.firstChildElement ("description").text (); GetDescription (itemDescr, item->Description_); item->Categories_ = GetAllCategories (itemDescr); item->Author_ = GetAuthor (itemDescr); item->PubDate_ = GetDCDateTime (itemDescr); item->Unread_ = true; item->NumComments_ = GetNumComments (itemDescr); item->CommentsLink_ = GetCommentsRSS (itemDescr); item->CommentsPageLink_ = GetCommentsLink (itemDescr); item->Enclosures_ = GetEncEnclosures (itemDescr, item->ItemID_); QPair<double, double> point = GetGeoPoint (itemDescr); item->Latitude_ = point.first; item->Longitude_ = point.second; if (item->Guid_.isEmpty ()) item->Guid_ = "empty"; item2Channel [about]->Items_.push_back (item); } itemDescr = itemDescr.nextSiblingElement ("item"); } return result; }
void KoParagStyle::loadStyle( QDomElement & styleElem, KoOasisContext& context ) { // Load name m_name = styleElem.attributeNS( KoXmlNS::style, "name", QString::null ); m_displayName = styleElem.attributeNS( KoXmlNS::style, "display-name", QString::null ); if ( m_displayName.isEmpty() ) m_displayName = m_name; // OOo hack //m_bOutline = m_name.startsWith( "Heading" ); // real OASIS solution: m_bOutline = styleElem.hasAttributeNS( KoXmlNS::style, "default-outline-level" ); context.styleStack().save(); context.addStyles( &styleElem, "paragraph" ); // Load all parents - only because we don't support inheritance. KoParagLayout layout; KoParagLayout::loadOasisParagLayout( layout, context ); // loadOasisParagLayout doesn't load the counter. It's modelled differently for parags and for styles. int level = 0; bool listOK = false; const QString listStyleName = styleElem.attributeNS( KoXmlNS::style, "list-style-name", QString::null ); if ( m_bOutline ) { level = styleElem.attributeNS( KoXmlNS::style, "default-outline-level", QString::null ).toInt(); // 1-based listOK = context.pushOutlineListLevelStyle( level ); // allow overriding the outline numbering, see http://lists.oasis-open.org/archives/office/200310/msg00033.html if ( !listStyleName.isEmpty() ) context.pushListLevelStyle( listStyleName, level ); } else { // ######## BIG difference here. In the OOo/OASIS format, one list style has infos for 10 list levels... // ###### so we can't know a level at this point... // The only solution I can think of, to preserve document content when importing OO but // not necessarily the styles used when editing, is: // 1) when importing from OOo, convert each non-heading style with numbering // into 10 kotext styles (at least those used by the document) [TODO] // 2) for KWord's own loading/saving, to add a hack into the file format, say // style:default-level. // Note that default-level defaults to "1", i.e. works for non-nested OOo lists too. level = styleElem.attributeNS( KoXmlNS::style, "default-level", "1" ).toInt(); // 1-based listOK = !listStyleName.isEmpty(); if ( listOK ) listOK = context.pushListLevelStyle( listStyleName, level ); } if ( listOK ) { const QDomElement listStyle = context.listStyleStack().currentListStyle(); // The tag is either text:list-level-style-number or text:list-level-style-bullet const bool ordered = listStyle.localName() == "list-level-style-number"; Q_ASSERT( !layout.counter ); layout.counter = new KoParagCounter; layout.counter->loadOasis( context, -1, ordered, m_bOutline, level, true ); context.listStyleStack().pop(); } // This way, KoTextParag::setParagLayout also sets the style pointer, to this style layout.style = this; m_paragLayout = layout; m_format.load( context ); context.styleStack().restore(); }