diff --git a/qt4/src/poppler-link.cc b/qt4/src/poppler-link.cc index b810c55..4715f25 100644 --- a/qt4/src/poppler-link.cc +++ b/qt4/src/poppler-link.cc @@ -23,6 +23,7 @@ */ #include +#include #include #include @@ -70,24 +71,6 @@ class LinkDestinationPrivate : public QSharedData changeZoom = false; } -class LinkPrivate -{ - public: - LinkPrivate( const QRectF &area ); - virtual ~LinkPrivate(); - - QRectF linkArea; -}; - - LinkPrivate::LinkPrivate( const QRectF &area ) - : linkArea( area ) - { - } - - LinkPrivate::~LinkPrivate() - { - } - class LinkGotoPrivate : public LinkPrivate { public: @@ -710,4 +693,18 @@ class LinkMoviePrivate : public LinkPrivate return false; } + + LinkOCGState::LinkOCGState( LinkOCGStatePrivate *ocgp ) + : Link ( *ocgp ) + { + } + + LinkOCGState::~LinkOCGState() + { + } + + Link::LinkType LinkOCGState::linkType() const + { + return OCGState; + } } diff --git a/qt4/src/poppler-link.h b/qt4/src/poppler-link.h index 2c4bb55..2a3a375 100644 --- a/qt4/src/poppler-link.h +++ b/qt4/src/poppler-link.h @@ -31,6 +31,8 @@ struct Ref; class MediaRendition; +class MovieAnnotation; +class ScreenAnnotation; namespace Poppler { @@ -45,6 +47,7 @@ class LinkMoviePrivate; class LinkDestinationData; class LinkDestinationPrivate; class LinkRenditionPrivate; +class LinkOCGStatePrivate; class MediaRendition; class SoundObject; @@ -170,6 +173,8 @@ class POPPLER_QT4_EXPORT LinkDestination */ class POPPLER_QT4_EXPORT Link { + friend class OptContentModel; + public: /// \cond PRIVATE Link( const QRectF &linkArea ); @@ -190,7 +195,8 @@ class POPPLER_QT4_EXPORT Link Sound, ///< A link representing a sound to be played Movie, ///< An action to be executed on a movie Rendition, ///< A rendition link \since 0.20 - JavaScript ///< A JavaScript code to be interpreted \since 0.10 + JavaScript, ///< A JavaScript code to be interpreted \since 0.10 + OCGState ///< An Optional Content Group state change \since 0.49 }; /** @@ -606,6 +612,30 @@ class POPPLER_QT4_EXPORT LinkMovie : public Link Q_DISABLE_COPY( LinkMovie ) }; +/** + * OCGState: an optional content group state change. + * + * \since 0.49 + */ +class POPPLER_QT4_EXPORT LinkOCGState : public Link +{ + public: + /** + * Create a new OCGState link. This is only used by Poppler::Page. + */ + LinkOCGState( LinkOCGStatePrivate *ocgp ); + /** + * Destructor. + */ + ~LinkOCGState(); + + LinkType linkType() const; + + private: + Q_DECLARE_PRIVATE( LinkOCGState ) + Q_DISABLE_COPY( LinkOCGState ) +}; + } #endif diff --git a/qt4/src/poppler-optcontent-private.h b/qt4/src/poppler-optcontent-private.h index 98eda07..ae6b02b 100644 --- a/qt4/src/poppler-optcontent-private.h +++ b/qt4/src/poppler-optcontent-private.h @@ -60,7 +60,7 @@ namespace Poppler QString name() const { return m_name; } ItemState state() const { return m_stateBackup; } - bool setState(ItemState state, QSet &changedItems); + void setState(ItemState state, bool obeyRadioGroups, QSet &changedItems); QList childList() { return m_children; } diff --git a/qt4/src/poppler-optcontent.cc b/qt4/src/poppler-optcontent.cc index 431f0ee..879b385 100644 --- a/qt4/src/poppler-optcontent.cc +++ b/qt4/src/poppler-optcontent.cc @@ -25,11 +25,13 @@ #include "poppler-optcontent-private.h" #include "poppler-private.h" +#include "poppler-link-private.h" #include #include #include "poppler/OptionalContent.h" +#include "poppler/Link.h" namespace Poppler { @@ -63,7 +65,7 @@ namespace Poppler OptContentItem *thisItem = itemsInGroup.at(i); if (thisItem != itemToSetOn) { QSet newChangedItems; - thisItem->setState(OptContentItem::Off, newChangedItems); + thisItem->setState(OptContentItem::Off, false /*obeyRadioGroups*/, newChangedItems); changedItems += newChangedItems; } } @@ -111,31 +113,33 @@ namespace Poppler } - bool OptContentItem::setState(ItemState state, QSet &changedItems) + void OptContentItem::setState(ItemState state, bool obeyRadioGroups, QSet &changedItems) { + if (state == m_state) + return; + m_state = state; m_stateBackup = m_state; changedItems.insert(this); QSet empty; Q_FOREACH (OptContentItem *child, m_children) { ItemState oldState = child->m_stateBackup; - child->setState(state == OptContentItem::On ? child->m_stateBackup : OptContentItem::Off, empty); + child->setState(state == OptContentItem::On ? child->m_stateBackup : OptContentItem::Off, true /*obeyRadioGroups*/, empty); child->m_enabled = state == OptContentItem::On; child->m_stateBackup = oldState; } - if (!m_group) { - return false; + if (!m_group || !obeyRadioGroups) { + return; } if ( state == OptContentItem::On ) { m_group->setState( OptionalContentGroup::On ); for (int i = 0; i < m_rbGroups.size(); ++i) { - RadioButtonGroup *rbgroup = m_rbGroups.at(i); + RadioButtonGroup *rbgroup = m_rbGroups.at(i); changedItems += rbgroup->setItemOn( this ); } } else if ( state == OptContentItem::Off ) { m_group->setState( OptionalContentGroup::Off ); } - return true; } void OptContentItem::addChild( OptContentItem *child ) @@ -353,36 +357,20 @@ namespace Poppler case Qt::CheckStateRole: { const bool newvalue = value.toBool(); - if (newvalue) { - if (node->state() != OptContentItem::On) { - QSet changedItems; - node->setState(OptContentItem::On, changedItems); - changedItems += node->recurseListChildren(false); - QModelIndexList indexes; - Q_FOREACH (OptContentItem *item, changedItems) { - indexes.append(d->indexFromItem(item, 0)); - } - qStableSort(indexes); - Q_FOREACH (const QModelIndex &changedIndex, indexes) { - emit dataChanged(changedIndex, changedIndex); - } - return true; + QSet changedItems; + node->setState(newvalue ? OptContentItem::On : OptContentItem::Off, true /*obeyRadioGroups*/, changedItems); + + if (!changedItems.isEmpty()) { + changedItems += node->recurseListChildren(false); + QModelIndexList indexes; + Q_FOREACH (OptContentItem *item, changedItems) { + indexes.append(d->indexFromItem(item, 0)); } - } else { - if (node->state() != OptContentItem::Off) { - QSet changedItems; - node->setState(OptContentItem::Off, changedItems); - changedItems += node->recurseListChildren(false); - QModelIndexList indexes; - Q_FOREACH (OptContentItem *item, changedItems) { - indexes.append(d->indexFromItem(item, 0)); - } - qStableSort(indexes); - Q_FOREACH (const QModelIndex &changedIndex, indexes) { - emit dataChanged(changedIndex, changedIndex); - } - return true; + qStableSort(indexes); + Q_FOREACH (const QModelIndex &changedIndex, indexes) { + emit dataChanged(changedIndex, changedIndex); } + return true; } break; } @@ -406,6 +394,49 @@ namespace Poppler return QAbstractItemModel::headerData( section, orientation, role ); } + void OptContentModel::applyLink( LinkOCGState *link ) + { + ::LinkOCGState *popplerLinkOCGState = static_cast(link->d_ptr)->popplerLinkOCGState; + + QSet changedItems; + + GooList *statesList = popplerLinkOCGState->getStateList(); + for (int i = 0; i < statesList->getLength(); ++i) { + ::LinkOCGState::StateList *stateList = (::LinkOCGState::StateList*)statesList->get(i); + + GooList *refsList = stateList->list; + for (int j = 0; j < refsList->getLength(); ++j) { + Ref *ref = (Ref *)refsList->get(j); + OptContentItem *item = d->itemFromRef(QString::number(ref->num)); + + if (stateList->st == ::LinkOCGState::On) { + item->setState(OptContentItem::On, popplerLinkOCGState->getPreserveRB(), changedItems); + } else if (stateList->st == ::LinkOCGState::Off) { + item->setState(OptContentItem::Off, popplerLinkOCGState->getPreserveRB(), changedItems); + } else { + OptContentItem::ItemState newState = item->state() == OptContentItem::On ? OptContentItem::Off : OptContentItem::On; + item->setState(newState, popplerLinkOCGState->getPreserveRB(), changedItems); + } + } + } + + if (!changedItems.isEmpty()) { + QSet aux; + Q_FOREACH (OptContentItem *item, aux) { + changedItems += item->recurseListChildren(false); + } + + QModelIndexList indexes; + Q_FOREACH (OptContentItem *item, changedItems) { + indexes.append(d->indexFromItem(item, 0)); + } + qStableSort(indexes); + Q_FOREACH (const QModelIndex &changedIndex, indexes) { + emit dataChanged(changedIndex, changedIndex); + } + } + } + void OptContentModelPrivate::addChild( OptContentItem *parent, OptContentItem *child ) { parent->addChild( child ); diff --git a/qt4/src/poppler-optcontent.h b/qt4/src/poppler-optcontent.h index 3f47853..26c5098 100644 --- a/qt4/src/poppler-optcontent.h +++ b/qt4/src/poppler-optcontent.h @@ -24,6 +24,7 @@ #include #include "poppler-export.h" +#include "poppler-link.h" class OCGs; @@ -65,6 +66,12 @@ namespace Poppler virtual QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; + /** + * Applies the Optional Contentn Changes specified by that link. + * \since 0.49 + */ + void applyLink( LinkOCGState *link ); + private: OptContentModel( OCGs *optContent, QObject *parent = 0); diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc index 9e466da..30192e0 100644 --- a/qt4/src/poppler-page.cc +++ b/qt4/src/poppler-page.cc @@ -59,6 +59,7 @@ #include "poppler-page-transition-private.h" #include "poppler-page-private.h" #include "poppler-link-extractor-private.h" +#include "poppler-link-private.h" #include "poppler-annotation-private.h" #include "poppler-form.h" #include "poppler-media.h" @@ -210,6 +211,14 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo } break; + case actionOCGState: + { + ::LinkOCGState *plocg = (::LinkOCGState *)a; + + LinkOCGStatePrivate *locgp = new LinkOCGStatePrivate( linkArea, plocg ); + popplerLink = new LinkOCGState( locgp ); + } + case actionUnknown: break; }