[okular/frameworks] /: Merge remote-tracking branch 'origin/master' into frameworks

Albert Astals Cid aacid at kde.org
Sat Oct 29 09:13:48 UTC 2016


Git commit 62eea3336b3fdf62102b68bc1ea12f9f8fbce390 by Albert Astals Cid.
Committed on 29/10/2016 at 09:13.
Pushed by aacid into branch 'frameworks'.

Merge remote-tracking branch 'origin/master' into frameworks

M  +0    -3    Mainpage.dox
A  +1    -0    autotests/generatorstest.cpp     [License: GPL (v2+)]
R  +13   -0    autotests/parttest.cpp
M  +1    -0    conf/dlggeneral.cpp
M  +73   -13   conf/dlggeneralbase.ui
M  +3    -0    conf/okular.kcfg
M  +0    -9    core/area.h
M  +1    -0    core/document.cpp
M  +20   -2    doc/index.docbook
M  +1    -0    generators/chm/okularApplication_chm.desktop
M  +1    -1    generators/comicbook/document.cpp
M  +1    -0    generators/comicbook/okularApplication_comicbook.desktop
M  +1    -0    generators/djvu/okularApplication_djvu.desktop
M  +1    -0    generators/dvi/okularApplication_dvi.desktop
M  +1    -0    generators/epub/okularApplication_epub.desktop
M  +1    -0    generators/fax/okularApplication_fax.desktop
M  +1    -0    generators/fictionbook/okularApplication_fb.desktop
M  +1    -0    generators/kimgio/okularApplication_kimgio.desktop
M  +1    -0    generators/mobipocket/okularApplication_mobi.desktop
M  +1    -0    generators/ooo/okularApplication_ooo.desktop
M  +1    -0    generators/plucker/okularApplication_plucker.desktop
M  +1    -0    generators/poppler/okularApplication_pdf.desktop
M  +1    -0    generators/spectre/okularApplication_ghostview.desktop
M  +1    -0    generators/tiff/okularApplication_tiff.desktop
M  +1    -0    generators/txt/okularApplication_txt.desktop
M  +1    -0    generators/xps/okularApplication_xps.desktop
R  +1    -0    shell/org.kde.okular.desktop
M  +71   -12   ui/embeddedfilesdialog.cpp
M  +11   -1    ui/embeddedfilesdialog.h
M  +8    -5    ui/guiutils.cpp
M  +2    -0    ui/guiutils.h
M  +4    -4    ui/pagepainter.cpp
M  +25   -6    ui/pageview.cpp
M  +1    -1    ui/pageviewannotator.cpp
M  +29   -21   ui/thumbnaillist.cpp
M  +59   -12   ui/tocmodel.cpp

http://commits.kde.org/okular/62eea3336b3fdf62102b68bc1ea12f9f8fbce390

diff --cc autotests/generatorstest.cpp
index 9d63c91,0000000..e8e1962
mode 100644,000000..100644
--- a/autotests/generatorstest.cpp
+++ b/autotests/generatorstest.cpp
@@@ -1,74 -1,0 +1,75 @@@
 +/***************************************************************************
 + *   Copyright (C) 2015 by Alex Richardson <arichardson.kde at gmail.com>     *
 + *                                                                         *
 + *   This program is free software; you can redistribute it and/or modify  *
 + *   it under the terms of the GNU General Public License as published by  *
 + *   the Free Software Foundation; either version 2 of the License, or     *
 + *   (at your option) any later version.                                   *
 + ***************************************************************************/
 +
 +#include <QtTest/QTest>
 +#include <QDirIterator>
 +#include <QDebug>
 +#include <QStringList>
 +#include <KPluginFactory>
 +#include <KPluginLoader>
 +
 +#include "../generator.h"
 +
 +class GeneratorsTest : public QObject
 +{
 +    Q_OBJECT
 +private slots:
 +    void testLoadsCorrectly();
 +};
 +
 +void GeneratorsTest::testLoadsCorrectly()
 +{
 +    QCoreApplication::setLibraryPaths(QStringList());
 +    QVERIFY2(QDir(QStringLiteral(GENERATORS_BUILD_DIR)).exists(), GENERATORS_BUILD_DIR);
 +    // find all possible generators in $CMAKE_BINARY_DIR/generators
 +    // We can't simply hardcore the list of generators since some might not be built
 +    // depending on which dependencies were found by CMake
 +    QStringList generatorLibs;
 +    QDirIterator it(QStringLiteral(GENERATORS_BUILD_DIR), QDir::Files | QDir::Executable, QDirIterator::Subdirectories);
 +    while (it.hasNext()) {
 +        it.next();
 +        if (QLibrary::isLibrary(it.fileName())) {
 +            if (it.fileName().startsWith(QLatin1String("kio_"))) {
 +                continue; // don't check kio_msits.so
 +            }
 +            generatorLibs <<  it.fileInfo().absoluteFilePath();
 +        }
 +    }
 +    int failures = 0;
 +    int successful = 0;
 +    foreach (const QString& lib, generatorLibs) {
 +        KPluginLoader loader(lib);
 +        QVERIFY2(!loader.fileName().isEmpty(), qPrintable(lib));
++        qDebug() << loader.fileName();
 +        auto factory = loader.factory();
 +        if (!factory) {
 +            qWarning() << "Could not get KPluginFactory for" << lib;
 +            failures++;
 +            continue;
 +        }
 +        Okular::Generator* generator = factory->create<Okular::Generator>();
 +        if (!generator) {
 +            qWarning() << "Failed to cast" << lib << "to Okular::Generator";
 +            // without the necessary Q_INTERFACES() qobject_cast fails!
 +            auto obj = factory->create<QObject>();
 +            qDebug() << "Object is of type " << obj->metaObject()->className();
 +            qDebug() << "dynamic_cast:" << dynamic_cast<Okular::Generator*>(obj);
 +            qDebug() << "qobject_cast:" << qobject_cast<Okular::Generator*>(obj);
 +            failures++;
 +            continue;
 +        }
 +        successful++;
 +    }
 +    qDebug() << "Successfully loaded" << successful << "generators";
 +    QCOMPARE(failures, 0);
 +}
 +
 +QTEST_MAIN(GeneratorsTest)
 +
 +#include "generatorstest.moc"
diff --cc autotests/parttest.cpp
index 46d359d,9afa47d..96085d7
--- a/autotests/parttest.cpp
+++ b/autotests/parttest.cpp
@@@ -117,22 -111,32 +117,35 @@@ void PartTest::testFowardPDF(
      QFETCH(QString, dir);
  
      QVariantList dummyArgs;
 -    Okular::Part part(NULL, NULL, dummyArgs, KGlobal::mainComponent());
 +    Okular::Part part(NULL, NULL, dummyArgs);
  
 -    KTempDir tempDir(dir);
 -    QFile f(KDESRCDIR "data/synctextest.tex");
 -    const QString texDestination = tempDir.name() + "synctextest.tex";
 -    QVERIFY(f.copy(texDestination));
 +    // Create temp dir named like this: ${system temp dir}/${random string}/${dir}
 +    const QTemporaryDir tempDir;
 +    const QDir workDir(QDir(tempDir.path()).filePath(dir));
 +    workDir.mkpath(QStringLiteral("."));
  
 +    QFile f(QStringLiteral(KDESRCDIR "data/synctextest.tex"));
 +    const QString texDestination = workDir.path() + QStringLiteral("/synctextest.tex");
 +    QVERIFY(f.copy(texDestination));
      QProcess process;
 -    process.setWorkingDirectory(tempDir.name());
 -    process.start("pdflatex", QStringList() << "-synctex=1" << "-interaction=nonstopmode" << texDestination);
 +    process.setWorkingDirectory(workDir.path());
 +    process.start(QStringLiteral("pdflatex"), QStringList() << QStringLiteral("-synctex=1") << QStringLiteral("-interaction=nonstopmode") << texDestination);
+     bool started = process.waitForStarted();
+     if (!started) {
+         qDebug() << "start error:" << process.error();
+         qDebug() << "start stdout:" << process.readAllStandardOutput();
+         qDebug() << "start stderr:" << process.readAllStandardError();
+     }
+     QVERIFY(started);
+ 
      process.waitForFinished();
+     if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
+         qDebug() << "exit error:" << process.error() << "status" << process.exitStatus() << "code" << process.exitCode();
+         qDebug() << "exit stdout:" << process.readAllStandardOutput();
+         qDebug() << "exit stderr:" << process.readAllStandardError();
+     }
  
 -    const QString pdfResult = tempDir.name() + "synctextest.pdf";
 +    const QString pdfResult = workDir.path() + QStringLiteral("/synctextest.pdf");
      
      QVERIFY(QFile::exists(pdfResult));
      
diff --cc conf/dlggeneralbase.ui
index c180533,6486747..323d74c
mode 100644,100755..100644
--- a/conf/dlggeneralbase.ui
+++ b/conf/dlggeneralbase.ui
diff --cc core/document.cpp
index 848aadd,6953b1f..8bc037e
--- a/core/document.cpp
+++ b/core/document.cpp
@@@ -814,21 -815,21 +814,22 @@@ bool DocumentPrivate::openRelativeFile
      return true;
  }
  
 -Generator * DocumentPrivate::loadGeneratorLibrary( const KService::Ptr &service )
 +Generator * DocumentPrivate::loadGeneratorLibrary( const KPluginMetaData &service )
  {
 -    KPluginFactory *factory = KPluginLoader( service->library() ).factory();
 +    KPluginLoader loader( service.fileName() );
++    qDebug() << service.fileName();
 +    KPluginFactory *factory = loader.factory();
      if ( !factory )
      {
 -        kWarning(OkularDebug).nospace() << "Invalid plugin factory for " << service->library() << "!";
 +        qCWarning(OkularCoreDebug).nospace() << "Invalid plugin factory for " << service.fileName() << ":" << loader.errorString();
          return 0;
      }
 -    Generator * generator = factory->create< Okular::Generator >( service->pluginKeyword(), 0 );
 -    GeneratorInfo info( factory->componentData() );
 -    info.generator = generator;
 -    if ( info.data.isValid() && info.data.aboutData() )
 -        info.catalogName = info.data.aboutData()->catalogName();
 -    m_loadedGenerators.insert( service->name(), info );
 -    return generator;
 +
 +    Generator * plugin = factory->create<Okular::Generator>();
 +
 +    GeneratorInfo info( plugin, service );
 +    m_loadedGenerators.insert( service.pluginId(), info );
 +    return plugin;
  }
  
  void DocumentPrivate::loadAllGeneratorLibraries()
diff --cc generators/comicbook/document.cpp
index 54c4c3c,72b2c55..34c4cb5
--- a/generators/comicbook/document.cpp
+++ b/generators/comicbook/document.cpp
@@@ -78,7 -75,7 +78,7 @@@ bool Document::open( const QString &fil
          if ( !processArchive() ) {
              return false;
          }
-     } else if ( mime.inherits( QStringLiteral("application/x-cbr") ) || mime.inherits( QStringLiteral("application/x-rar") ) ) {
 -    } else if ( mime->is( "application/x-cbr" ) || mime->name() == "application/x-rar" || mime->name() == "application/vnd.rar" ) {
++    } else if ( mime.inherits( QStringLiteral("application/x-cbr") ) || mime.inherits( QStringLiteral("application/x-rar") ) || mime.inherits( QStringLiteral("application/vnd.rar") ) ) {
          if ( !Unrar::isAvailable() ) {
              mLastErrorString = i18n( "Cannot open document, unrar was not found." );
              return false;
diff --cc ui/embeddedfilesdialog.cpp
index 4d17841,ec0d2b1..f3916f6
--- a/ui/embeddedfilesdialog.cpp
+++ b/ui/embeddedfilesdialog.cpp
@@@ -11,20 -11,19 +11,24 @@@
  
  #include <QAction>
  #include <QCursor>
+ #include <QDir>
  #include <QDateTime>
+ #include <QFileInfo>
  #include <QMenu>
  #include <QTreeWidget>
+ #include <QTemporaryFile>
  
 -#include <kglobal.h>
 -#include <kicon.h>
 -#include <klocale.h>
 -#include <kmimetype.h>
 +#include <QIcon>
 +#include <KLocalizedString>
 +#include <QMimeType>
 +#include <QMimeDatabase>
  #include <kstandardguiitem.h>
 +#include <KFormat>
 +#include <KConfigGroup>
 +#include <QDialogButtonBox>
 +#include <QPushButton>
 +#include <QVBoxLayout>
+ #include <krun.h>
  
  #include "core/document.h"
  #include "guiutils.h"
@@@ -40,24 -39,18 +44,29 @@@ static QString dateToString( const QDat
  		: i18nc( "Unknown date", "Unknown" );
  }
  
 -EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const Okular::Document *document) : KDialog(parent)
 +EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const Okular::Document *document) : QDialog(parent)
  {
 -	setCaption(i18nc("@title:window", "Embedded Files"));
 -	setButtons(Close | User1 | User2);
 -	setDefaultButton(Close);
 -	setButtonGuiItem(User1, KStandardGuiItem::save());
 -	setButtonGuiItem(User2, KGuiItem(i18nc("@action:button", "View"), "document-open"));
 -	enableButton(User1, false);
 -	enableButton(User2, false);
 +	setWindowTitle(i18nc("@title:window", "Embedded Files"));
 +	QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
 +	QVBoxLayout *mainLayout = new QVBoxLayout;
 +	setLayout(mainLayout);
 +	mUser1Button = new QPushButton;
 +	buttonBox->addButton(mUser1Button, QDialogButtonBox::ActionRole);
 +	connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
 +	connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
 +	buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
 +	KGuiItem::assign(mUser1Button, KStandardGuiItem::save());
 +	mUser1Button->setEnabled(false);
 +
++	mUser2Button = new QPushButton;
++	buttonBox->addButton(mUser2Button, QDialogButtonBox::ActionRole);
++	KGuiItem::assign(mUser2Button, KGuiItem(i18nc("@action:button", "View"), "document-open"));
++	mUser1Button->setEnabled(false);
+ 
  	m_tw = new QTreeWidget(this);
 -	setMainWidget(m_tw);
 +	mainLayout->addWidget(m_tw);
-         mainLayout->addWidget(buttonBox);
++	mainLayout->addWidget(buttonBox);
 +
  	QStringList header;
  	header.append(i18nc("@title:column", "Name"));
  	header.append(i18nc("@title:column", "Description"));
@@@ -73,36 -66,39 +82,39 @@@
  	{
  		QTreeWidgetItem *twi = new QTreeWidgetItem();
  		twi->setText(0, ef->name());
-         QMimeDatabase db;
-         QMimeType mime = db.mimeTypeForFile( ef->name(), QMimeDatabase::MatchExtension);
 -		KMimeType::Ptr mime = KMimeType::findByPath( ef->name(), 0, true );
 -		if (mime)
++		QMimeDatabase db;
++		QMimeType mime = db.mimeTypeForFile( ef->name(), QMimeDatabase::MatchExtension);
 +		if (mime.isValid())
  		{
-             twi->setIcon(0, QIcon::fromTheme(mime.iconName()));
 -			twi->setIcon(0, KIcon(mime->iconName()));
++			twi->setIcon(0, QIcon::fromTheme(mime.iconName()));
  		}
  		twi->setText(1, ef->description());
 -		twi->setText(2, ef->size() <= 0 ? i18nc("Not available size", "N/A") : KGlobal::locale()->formatByteSize(ef->size()));
 +		twi->setText(2, ef->size() <= 0 ? i18nc("Not available size", "N/A") : KFormat().formatByteSize(ef->size()));
  		twi->setText(3, dateToString( ef->creationDate() ) );
  		twi->setText(4, dateToString( ef->modificationDate() ) );
  		twi->setData( 0, EmbeddedFileRole, qVariantFromValue( ef ) );
  		m_tw->addTopLevelItem(twi);
  	}
--        // Having filled the columns, it is nice to resize them to be able to read the contents
--        for (int lv = 0; lv <  m_tw->columnCount(); ++lv) {
--                m_tw->resizeColumnToContents(lv);
--        }
--        // This is a bit dubious, but I'm not seeing a nice way to say "expand to fit contents"
--        m_tw->setMinimumWidth(640);
--        m_tw->updateGeometry();
 -
 -	connect(this, SIGNAL(user1Clicked()), this, SLOT(saveFile()));
 -	connect(this, SIGNAL(user2Clicked()), this, SLOT(viewFile()));
 -
 -	connect(m_tw, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(attachViewContextMenu(QPoint)));
 -	connect(m_tw, SIGNAL(itemSelectionChanged()), this, SLOT(updateSaveButton()));
++	// Having filled the columns, it is nice to resize them to be able to read the contents
++	for (int lv = 0; lv <  m_tw->columnCount(); ++lv) {
++		m_tw->resizeColumnToContents(lv);
++	}
++	// This is a bit dubious, but I'm not seeing a nice way to say "expand to fit contents"
++	m_tw->setMinimumWidth(640);
++	m_tw->updateGeometry();
 +
 +	connect(mUser1Button, SIGNAL(clicked()), this, SLOT(saveFile()));
++	connect(mUser2Button, SIGNAL(clicked()), this, SLOT(viewFile()));
 +	connect(m_tw, &QWidget::customContextMenuRequested, this, &EmbeddedFilesDialog::attachViewContextMenu);
 +	connect(m_tw, &QTreeWidget::itemSelectionChanged, this, &EmbeddedFilesDialog::updateSaveButton);
+ 	connect(m_tw, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(viewFileItem(QTreeWidgetItem*,int)));
  }
  
  void EmbeddedFilesDialog::updateSaveButton()
  {
  	bool enable = (m_tw->selectedItems().count() > 0);
 -	enableButton(User1, enable);
 -	enableButton(User2, enable);
 +	mUser1Button->setEnabled(enable);
++	mUser2Button->setEnabled(enable);
  }
  
  void EmbeddedFilesDialog::saveFile()
@@@ -125,7 -137,8 +153,8 @@@ void EmbeddedFilesDialog::attachViewCon
          return;
  
      QMenu menu( this );
 -    QAction* saveAsAct = menu.addAction( KIcon( "document-save-as" ), i18nc( "@action:inmenu", "&Save As..." ) );
 -    QAction* viewAct = menu.addAction( KIcon( "document-open" ), i18nc( "@action:inmenu", "&View..." ) );
 +    QAction* saveAsAct = menu.addAction( QIcon::fromTheme( QStringLiteral("document-save-as") ), i18nc( "@action:inmenu", "&Save As..." ) );
++    QAction* viewAct = menu.addAction( QIcon::fromTheme( QStringLiteral("document-open" ) ), i18nc( "@action:inmenu", "&View..." ) );
  
      QAction* act = menu.exec( QCursor::pos() );
      if ( !act )
diff --cc ui/embeddedfilesdialog.h
index 7ec55a8,bb83540..1def992
--- a/ui/embeddedfilesdialog.h
+++ b/ui/embeddedfilesdialog.h
@@@ -10,10 -10,12 +10,13 @@@
  #ifndef _EMBEDDEDFILESDIALOG_H_
  #define _EMBEDDEDFILESDIALOG_H_
  
 -#include <kdialog.h>
 +#include <QDialog>
  
  class QTreeWidget;
 +class QPushButton;
+ class QTemporaryFile;
+ class QTreeWidgetItem;
+ 
  namespace Okular {
  class Document;
  class EmbeddedFile;
@@@ -32,9 -36,10 +37,14 @@@ Q_OBJEC
  
  	private:
  		void saveFile( Okular::EmbeddedFile* );
+ 		void viewFile( Okular::EmbeddedFile* );
  
  		QTreeWidget *m_tw;
-         QPushButton *mUser1Button;
++
++                
++		QPushButton *mUser1Button;
++		QPushButton *mUser2Button;
+ 		QList< QSharedPointer<QTemporaryFile> > m_openedFiles;
  };
  
  #endif
diff --cc ui/guiutils.cpp
index 14bb85c,b432105..d4c9228
--- a/ui/guiutils.cpp
+++ b/ui/guiutils.cpp
@@@ -205,18 -202,22 +205,21 @@@ KIconLoader* iconLoader(
  void saveEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent )
  {
      const QString caption = i18n( "Where do you want to save %1?", ef->name() );
 -    const QString path = KFileDialog::getSaveFileName( ef->name(), QString(), parent, caption,
 -                                                       KFileDialog::ConfirmOverwrite );
 +    const QString path = QFileDialog::getSaveFileName( parent, caption, ef->name() );
      if ( path.isEmpty() )
          return;
+     QFile targetFile( path );
+     writeEmbeddedFile( ef, parent, targetFile );
+ }
  
-     QFile f( path );
-     if ( !f.open( QIODevice::WriteOnly ) )
+ void writeEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent, QFile& target ) {
+     if ( !target.open( QIODevice::WriteOnly ) )
      {
-         KMessageBox::error( parent, i18n( "Could not open \"%1\" for writing. File was not saved.", path ) );
+         KMessageBox::error( parent, i18n( "Could not open \"%1\" for writing. File was not saved.", target.fileName() ) );
          return;
      }
-     f.write( ef->data() );
-     f.close();
+     target.write( ef->data() );
+     target.close();
  }
  
  Okular::Movie* renditionMovieFromScreenAnnotation( const Okular::ScreenAnnotation *annotation )
diff --cc ui/pageview.cpp
index 339ba69,bb540cb..3e8d650
--- a/ui/pageview.cpp
+++ b/ui/pageview.cpp
@@@ -223,16 -214,16 +223,16 @@@ public
      KActionMenu * aViewMode;
      KToggleAction * aViewContinuous;
      QAction * aPrevAction;
 -    KAction * aToggleForms;
 -    KAction * aSpeakDoc;
 -    KAction * aSpeakPage;
 -    KAction * aSpeakStop;
 +    QAction * aToggleForms;
 +    QAction * aSpeakDoc;
 +    QAction * aSpeakPage;
 +    QAction * aSpeakStop;
      KActionCollection * actionCollection;
      QActionGroup * mouseModeActionGroup;
 -    KAction * aFitWindowToPage;
 +    QAction * aFitWindowToPage;
  
      int setting_viewCols;
- 
+     bool rtl_Mode;
      // Keep track of whether tablet pen is currently pressed down
      bool penDown;
  };
diff --cc ui/tocmodel.cpp
index ccbaa4c,fcc7658..0a4608c
--- a/ui/tocmodel.cpp
+++ b/ui/tocmodel.cpp
@@@ -12,8 -12,9 +12,9 @@@
  #include <qapplication.h>
  #include <qdom.h>
  #include <qlist.h>
+ #include <qtreeview.h>
  
 -#include <kicon.h>
 +#include <QIcon>
  
  #include "pageitemdelegate.h"
  #include "core/document.h"
@@@ -198,7 -217,31 +226,31 @@@ QVariant TOCModel::data( const QModelIn
              break;
          case Qt::DecorationRole:
              if ( item->highlight )
-                 return QIcon::fromTheme( QApplication::layoutDirection() == Qt::RightToLeft ? QStringLiteral("arrow-left") : QStringLiteral("arrow-right") );
+             {
 -                const QVariant icon = KIcon( QApplication::layoutDirection() == Qt::RightToLeft ? "arrow-left" : "arrow-right" );
++                const QVariant icon = QIcon::fromTheme( QApplication::layoutDirection() == Qt::RightToLeft ? QStringLiteral("arrow-left") : QStringLiteral("arrow-right") );
+                 TOCItem *lastHighlighted = d->currentPage.last();
+ 
+                 // in the mobile version our parent is not a QTreeView; add icon to the last highlighted item
+                 // TODO misusing parent() here, fix
+                 QTreeView *view = dynamic_cast< QTreeView* > ( QObject::parent() );
+                 if ( !view )
+                 {
+                     if ( item == lastHighlighted )
+                         return icon;
+                     return QVariant();
+                 }
+ 
+                 if ( view->isExpanded( index ) )
+                 {
+                     // if this is the last highlighted node, its child is on a page below, thus it needs icon
+                     if ( item == lastHighlighted )
+                         return icon;
+                 }
+                 else
+                 {
+                     return icon;
+                 }
+             }
              break;
          case PageItemDelegate::PageRole:
              if ( item->viewport.isValid() )


More information about the kde-doc-english mailing list