diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ea559a594..eea05ebf6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,54 +1,54 @@ include: - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-before.yml - https://invent.kde.org/sysadmin/ci-tooling/raw/master/invent/ci-applications-linux.yml build_ubuntu_18_04: stage: build image: ubuntu:bionic only: - merge_requests before_script: - sed -i -e 's/# deb-src/deb-src/g' /etc/apt/sources.list - apt-get update - apt-get build-dep --yes --no-install-recommends okular - apt-get install --yes --no-install-recommends ninja-build libkf5crash-dev script: - mkdir -p build && cd build - cmake -G Ninja .. - ninja build_ubuntu_20_04: stage: build image: ubuntu:focal only: - merge_requests before_script: - sed -i -e 's/# deb-src/deb-src/g' /etc/apt/sources.list - apt-get update - apt-get build-dep --yes --no-install-recommends okular - apt-get install --yes --no-install-recommends ninja-build script: - mkdir -p build && cd build - cmake -DOKULAR_UI=desktop -G Ninja .. - ninja - rm -rf * - cmake -DOKULAR_UI=mobile -G Ninja .. - ninja build_clazy_clang_tidy: stage: build image: debian:unstable only: - merge_requests before_script: - echo 'deb-src http://deb.debian.org/debian unstable main' >> /etc/apt/sources.list - apt-get update - apt-get build-dep --yes --no-install-recommends okular - apt-get install --yes --no-install-recommends ninja-build clazy clang clang-tidy python python-yaml libkf5crash-dev libkf5purpose-dev libegl-dev jq script: - srcdir=`pwd` && mkdir -p /tmp/okular_build && cd /tmp/okular_build && CC=clang CXX=clazy CXXFLAGS="-Werror -Wno-deprecated-declarations" cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -G Ninja $srcdir && cat compile_commands.json | jq '[.[] | select(.file | contains("'"$srcdir"'"))]' > compile_commands.aux.json && cat compile_commands.aux.json | jq '[.[] | select(.file | contains("/synctex/")| not)]' > compile_commands.json - - CLAZY_CHECKS="level0,incorrect-emit,qhash-namespace,detaching-temporary,range-loop,qdeleteall,inefficient-qlist-soft,qstring-left,const-signal-or-slot,connect-3arg-lambda,qproperty-without-notify" ninja + - CLAZY_CHECKS="level0,level1" ninja # Fix the poppler header, remove when debian:unstable ships poppler 0.82 or later - sed -i "N;N;N;N; s#class MediaRendition\;\nclass MovieAnnotation\;\nclass ScreenAnnotation;#class MediaRendition\;#g" /usr/include/poppler/qt5/poppler-link.h - "run-clang-tidy -header-filter='.*/okular/.*' -checks='-*,performance-*,bugprone-*,readability-inconsistent-declaration-parameter-name,readability-string-compare,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-make-unique,modernize-make-shared,modernize-use-override,modernize-use-equals-delete,modernize-use-emplace,modernize-loop-convert,modernize-use-nullptr,-bugprone-macro-parentheses,-bugprone-narrowing-conversions,-bugprone-branch-clone,-bugprone-incorrect-roundings' -config=\"{WarningsAsErrors: '*'}\"" diff --git a/autotests/modifyannotationpropertiestest.cpp b/autotests/modifyannotationpropertiestest.cpp index 548eac5c5..430c8f280 100644 --- a/autotests/modifyannotationpropertiestest.cpp +++ b/autotests/modifyannotationpropertiestest.cpp @@ -1,171 +1,167 @@ /*************************************************************************** * Copyright (C) 2013 by Jon Mease * * * * 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 #include #include #include "../settings_core.h" #include #include #include "core/document.h" #include "testingutils.h" -static const QColor RED = QColor(255, 0, 0); -static const QColor GREEN = QColor(0, 255, 0.0); -// static const QColor BLUE = QColor(0, 0, 255); - class ModifyAnnotationPropertiesTest : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void init(); void cleanup(); void testModifyAnnotationProperties(); void testModifyDefaultAnnotationProperties(); void testModifyAnnotationPropertiesWithRotation_Bug318828(); private: Okular::Document *m_document; Okular::TextAnnotation *m_annot1; }; void ModifyAnnotationPropertiesTest::initTestCase() { Okular::SettingsCore::instance( QStringLiteral("editannotationcontentstest") ); m_document = new Okular::Document( nullptr ); } void ModifyAnnotationPropertiesTest::cleanupTestCase() { delete m_document; } void ModifyAnnotationPropertiesTest::init() { const QString testFile = QStringLiteral(KDESRCDIR "data/file1.pdf"); QMimeDatabase db; const QMimeType mime = db.mimeTypeForFile( testFile ); QCOMPARE( m_document->openDocument(testFile, QUrl(), mime), Okular::Document::OpenSuccess ); // Undo and Redo should be unavailable when docuemnt is first opened. QVERIFY( !m_document->canUndo() ); QVERIFY( !m_document->canRedo() ); // Create two distinct text annotations m_annot1 = new Okular::TextAnnotation(); m_annot1->setBoundingRectangle( Okular::NormalizedRect( 0.1, 0.1, 0.15, 0.15 ) ); m_annot1->setContents( QStringLiteral( "Hello, World" ) ); m_annot1->setAuthor( QStringLiteral("Jon Mease") ); - m_annot1->style().setColor( RED ); + m_annot1->style().setColor( Qt::red ); m_annot1->style().setWidth( 4.0 ); m_document->addPageAnnotation( 0, m_annot1 ); } void ModifyAnnotationPropertiesTest::cleanup() { m_document->closeDocument(); // m_annot1 and m_annot2 are deleted when document is closed } void ModifyAnnotationPropertiesTest::testModifyAnnotationProperties() { // Add m_annot1 to document and record its properties XML string QString origLine1Xml = TestingUtils::getAnnotationXml( m_annot1 ); // Tell document we're going to modify m_annot1's properties m_document->prepareToModifyAnnotationProperties( m_annot1 ); // Now modify m_annot1's properties and record properties XML string m_annot1->style().setWidth( 8.0 ); - m_annot1->style().setColor( GREEN ); + m_annot1->style().setColor( Qt::green ); m_document->modifyPageAnnotationProperties( 0, m_annot1 ); QString m_annot1XmlA = TestingUtils::getAnnotationXml( m_annot1 ); QCOMPARE( 8.0, m_annot1->style().width() ); - QCOMPARE( GREEN, m_annot1->style().color() ); + QCOMPARE( QColor(Qt::green), m_annot1->style().color() ); // undo modification and check that original properties have been restored m_document->undo(); QCOMPARE( 4.0, m_annot1->style().width() ); - QCOMPARE( RED, m_annot1->style().color() ); + QCOMPARE( QColor(Qt::red), m_annot1->style().color() ); QCOMPARE( origLine1Xml, TestingUtils::getAnnotationXml( m_annot1 ) ); // redo modification and verify that new properties have been restored m_document->redo(); QCOMPARE( 8.0, m_annot1->style().width() ); - QCOMPARE( GREEN, m_annot1->style().color() ); + QCOMPARE( QColor(Qt::green), m_annot1->style().color() ); QCOMPARE( m_annot1XmlA, TestingUtils::getAnnotationXml( m_annot1 ) ); // Verify that default values are properly restored. (We haven't explicitly set opacity yet) QCOMPARE( 1.0, m_annot1->style().opacity() ); m_document->prepareToModifyAnnotationProperties( m_annot1 ); m_annot1->style().setOpacity( 0.5 ); m_document->modifyPageAnnotationProperties( 0, m_annot1 ); QCOMPARE( 0.5, m_annot1->style().opacity() ); m_document->undo(); QCOMPARE( 1.0, m_annot1->style().opacity() ); QCOMPARE( m_annot1XmlA, TestingUtils::getAnnotationXml( m_annot1 ) ); // And finally undo back to original properties m_document->undo(); QCOMPARE( 4.0, m_annot1->style().width() ); - QCOMPARE( RED, m_annot1->style().color() ); + QCOMPARE( QColor(Qt::red), m_annot1->style().color() ); QCOMPARE( origLine1Xml, TestingUtils::getAnnotationXml( m_annot1 ) ); } void ModifyAnnotationPropertiesTest::testModifyDefaultAnnotationProperties() { QString origLine1Xml = TestingUtils::getAnnotationXml( m_annot1 ); // Verify that default values are properly restored. (We haven't explicitly set opacity yet) QCOMPARE( 1.0, m_annot1->style().opacity() ); m_document->prepareToModifyAnnotationProperties( m_annot1 ); m_annot1->style().setOpacity( 0.5 ); m_document->modifyPageAnnotationProperties( 0, m_annot1 ); QCOMPARE( 0.5, m_annot1->style().opacity() ); m_document->undo(); QCOMPARE( 1.0, m_annot1->style().opacity() ); QCOMPARE( origLine1Xml, TestingUtils::getAnnotationXml( m_annot1 ) ); } void ModifyAnnotationPropertiesTest::testModifyAnnotationPropertiesWithRotation_Bug318828() { Okular::NormalizedRect boundingRect = Okular::NormalizedRect( 0.1, 0.1, 0.15, 0.15 ); Okular::NormalizedRect transformedBoundingRect; m_annot1->setBoundingRectangle( boundingRect ); m_document->addPageAnnotation( 0, m_annot1 ); transformedBoundingRect = m_annot1->transformedBoundingRectangle(); // Before page rotation boundingRect and transformedBoundingRect should be equal QCOMPARE( boundingRect, transformedBoundingRect ); m_document->setRotation( 1 ); // After rotation boundingRect should remain unchanged but // transformedBoundingRect should no longer equal boundingRect QCOMPARE( boundingRect, m_annot1->boundingRectangle() ); transformedBoundingRect = m_annot1->transformedBoundingRectangle(); QVERIFY( !( boundingRect == transformedBoundingRect ) ); // Modifying the properties of m_annot1 while page is rotated shouldn't // alter either boundingRect or transformedBoundingRect m_document->prepareToModifyAnnotationProperties( m_annot1 ); m_annot1->style().setOpacity( 0.5 ); m_document->modifyPageAnnotationProperties( 0, m_annot1 ); QCOMPARE( boundingRect, m_annot1->boundingRectangle() ); QCOMPARE( transformedBoundingRect, m_annot1->transformedBoundingRectangle() ); } QTEST_MAIN( ModifyAnnotationPropertiesTest ) #include "modifyannotationpropertiestest.moc" diff --git a/ui/presentationsearchbar.cpp b/ui/presentationsearchbar.cpp index 5c3b288a7..2fbc9e959 100644 --- a/ui/presentationsearchbar.cpp +++ b/ui/presentationsearchbar.cpp @@ -1,149 +1,149 @@ /*************************************************************************** * Copyright (C) 2007 by Pino Toscano * * * * 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 "presentationsearchbar.h" #include #include #include #include #include #include #include #include #include #include "searchlineedit.h" #define SNAP_DELTA 15 class HandleDrag : public QWidget { Q_OBJECT public: HandleDrag( QWidget *parent = Q_NULLPTR ) : QWidget( parent ) { setCursor( Qt::SizeAllCursor ); setFixedWidth( style()->pixelMetric( QStyle::PM_ToolBarHandleExtent ) ); - installEventFilter( parent ); } void paintEvent( QPaintEvent * ) override { QStyleOption opt; opt.initFrom( this ); opt.state |= QStyle::State_Horizontal; QStylePainter p( this ); p.drawPrimitive( QStyle::PE_IndicatorToolBarHandle, opt ); } }; PresentationSearchBar::PresentationSearchBar( Okular::Document *document, QWidget *anchor, QWidget *parent ) : QWidget( parent ), m_anchor( anchor ), m_snapped( true ) { setAutoFillBackground( true ); QHBoxLayout * lay = new QHBoxLayout( this ); lay->setContentsMargins( 0, 0, 0, 0 ); m_handle = new HandleDrag( this ); + m_handle->installEventFilter( this ); lay->addWidget( m_handle ); QToolButton * closeBtn = new QToolButton( this ); closeBtn->setIcon( QIcon::fromTheme( QStringLiteral("dialog-close") ) ); closeBtn->setIconSize( QSize( 24, 24 ) ); closeBtn->setToolTip( i18n( "Close" ) ); closeBtn->setAutoRaise( true ); lay->addWidget( closeBtn ); m_search = new SearchLineEdit( this, document ); m_search->setClearButtonEnabled( true ); m_search->setSearchCaseSensitivity( Qt::CaseInsensitive ); m_search->setSearchMinimumLength( 0 ); m_search->setSearchType( Okular::Document::NextMatch ); m_search->setSearchId( PRESENTATION_SEARCH_ID ); m_search->setSearchColor( qRgb( 255, 255, 64 ) ); m_search->setSearchMoveViewport( true ); lay->addWidget( m_search ); QPushButton * findNextBtn = new QPushButton( QIcon::fromTheme( QStringLiteral("go-down-search") ), i18n( "Find Next" ), this ); lay->addWidget( findNextBtn ); m_anchor->installEventFilter( this ); connect( closeBtn, &QAbstractButton::clicked, this, &QWidget::close ); connect(findNextBtn, &QPushButton::clicked, m_search, &SearchLineEdit::findNext); } PresentationSearchBar::~PresentationSearchBar() { } void PresentationSearchBar::forceSnap() { m_point = QPoint( m_anchor->width() / 2, m_anchor->height() ); m_snapped = true; move( m_point.x() - width() / 2, m_point.y() - height() ); } void PresentationSearchBar::focusOnSearchEdit() { m_search->setFocus(); } void PresentationSearchBar::resizeEvent( QResizeEvent * ) { // if in snap mode, then force the snap and place ourselves correctly again if ( m_snapped ) forceSnap(); } bool PresentationSearchBar::eventFilter( QObject *obj, QEvent *e ) { if ( obj == m_handle && ( e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove ) ) { QMouseEvent *me = (QMouseEvent*)e; if ( e->type() == QEvent::MouseButtonPress ) { m_drag = m_handle->mapTo( this, me->pos() ); } else if ( e->type() == QEvent::MouseButtonRelease ) { m_drag = QPoint(); } else if ( e->type() == QEvent::MouseMove ) { QPoint snapdelta( width() / 2, height() ); QPoint delta = m_handle->mapTo( this, me->pos() ) - m_drag; QPoint newpostemp = pos() + delta; QPoint tmp = newpostemp + snapdelta - m_point; QPoint newpos = abs( tmp.x() ) < SNAP_DELTA && abs( tmp.y() ) < SNAP_DELTA ? m_point - snapdelta : newpostemp; m_snapped = newpos == ( m_point - snapdelta ); move( newpos ); } return true; } if ( obj == m_anchor && e->type() == QEvent::Resize ) { m_point = QPoint( m_anchor->width() / 2, m_anchor->height() ); if ( m_snapped ) move( m_point.x() - width() / 2, m_point.y() - height() ); } return false; } #include "presentationsearchbar.moc"