Changeset View
Changeset View
Standalone View
Standalone View
ui/pageviewannotator.cpp
Show All 27 Lines | |||||
28 | #include <qmenu.h> | 28 | #include <qmenu.h> | ||
29 | 29 | | |||
30 | // system includes | 30 | // system includes | ||
31 | #include <math.h> | 31 | #include <math.h> | ||
32 | #include <memory> | 32 | #include <memory> | ||
33 | #include <QStandardPaths> | 33 | #include <QStandardPaths> | ||
34 | 34 | | |||
35 | // local includes | 35 | // local includes | ||
36 | #include "conf/editannottooldialog.h" | ||||
36 | #include "core/area.h" | 37 | #include "core/area.h" | ||
37 | #include "core/document.h" | 38 | #include "core/document.h" | ||
38 | #include "core/page.h" | 39 | #include "core/page.h" | ||
39 | #include "core/annotations.h" | 40 | #include "core/annotations.h" | ||
41 | #include "ui/annotationactionhandler.h" | ||||
40 | #include "settings.h" | 42 | #include "settings.h" | ||
41 | #include "annotationtools.h" | 43 | #include "annotationtools.h" | ||
42 | #include "guiutils.h" | 44 | #include "guiutils.h" | ||
43 | #include "pageview.h" | 45 | #include "pageview.h" | ||
44 | #include "debug_ui.h" | 46 | #include "debug_ui.h" | ||
45 | 47 | | |||
46 | /** @short PickPointEngine */ | 48 | /** @short PickPointEngine */ | ||
47 | class PickPointEngine : public AnnotatorEngine | 49 | class PickPointEngine : public AnnotatorEngine | ||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Line(s) | 147 | { | |||
157 | { | 159 | { | ||
158 | QFont f; | 160 | QFont f; | ||
159 | f.fromString( m_annotElement.attribute( QStringLiteral("font") ) ); | 161 | f.fromString( m_annotElement.attribute( QStringLiteral("font") ) ); | ||
160 | ta->setTextFont( f ); | 162 | ta->setTextFont( f ); | ||
161 | } | 163 | } | ||
162 | // set font color | 164 | // set font color | ||
163 | if ( m_annotElement.hasAttribute( QStringLiteral("textColor") ) ) | 165 | if ( m_annotElement.hasAttribute( QStringLiteral("textColor") ) ) | ||
164 | { | 166 | { | ||
165 | if ( inplaceIntent == Okular::TextAnnotation::TypeWriter ) | | |||
166 | ta->setTextColor( m_annotElement.attribute( QStringLiteral("textColor") ) ); | 167 | ta->setTextColor( m_annotElement.attribute( QStringLiteral("textColor") ) ); | ||
167 | else | | |||
168 | ta->setTextColor( Qt::black ); | | |||
169 | } | 168 | } | ||
170 | //set width | 169 | //set width | ||
171 | if ( m_annotElement.hasAttribute( QStringLiteral ( "width" ) ) ) | 170 | if ( m_annotElement.hasAttribute( QStringLiteral ( "width" ) ) ) | ||
172 | { | 171 | { | ||
173 | ta->style().setWidth( m_annotElement.attribute( QStringLiteral ( "width" ) ).toDouble() ); | 172 | ta->style().setWidth( m_annotElement.attribute( QStringLiteral ( "width" ) ).toDouble() ); | ||
174 | } | 173 | } | ||
175 | //set boundary | 174 | //set boundary | ||
176 | rect.left = qMin(startpoint.x,point.x); | 175 | rect.left = qMin(startpoint.x,point.x); | ||
▲ Show 20 Lines • Show All 474 Lines • ▼ Show 20 Line(s) | 649 | private: | |||
651 | // data | 650 | // data | ||
652 | PageView * m_pageView; | 651 | PageView * m_pageView; | ||
653 | // TODO: support more pages | 652 | // TODO: support more pages | ||
654 | std::unique_ptr<Okular::RegularAreaRect> selection; | 653 | std::unique_ptr<Okular::RegularAreaRect> selection; | ||
655 | Okular::NormalizedPoint lastPoint; | 654 | Okular::NormalizedPoint lastPoint; | ||
656 | QRect rect; | 655 | QRect rect; | ||
657 | }; | 656 | }; | ||
658 | 657 | | |||
659 | 658 | /** @short AnnotationTools*/ | |||
660 | /** PageViewAnnotator **/ | 659 | class AnnotationTools | ||
661 | | ||||
662 | PageViewAnnotator::PageViewAnnotator( PageView * parent, Okular::Document * storage ) | | |||
663 | : QObject( parent ), m_document( storage ), m_pageView( parent ), | | |||
664 | m_toolBar( nullptr ), m_engine( nullptr ), m_textToolsEnabled( false ), m_toolsEnabled( false ), | | |||
665 | m_continuousMode( false ), m_hidingWasForced( false ), m_lastToolID( -1 ), m_lockedItem( nullptr ) | | |||
666 | { | 660 | { | ||
667 | reparseConfig(); | 661 | public: | ||
668 | } | 662 | AnnotationTools() : m_toolsCount( 0 ) {} | ||
669 | 663 | | |||
670 | void PageViewAnnotator::reparseConfig() | 664 | void setTools( QStringList tools ) | ||
671 | { | 665 | { | ||
672 | m_items.clear(); | | |||
673 | | ||||
674 | // Read tool list from configuration. It's a list of XML <tool></tool> elements | | |||
675 | const QStringList userTools = Okular::Settings::annotationTools(); | | |||
676 | | ||||
677 | // Populate m_toolsDefinition | 666 | // Populate m_toolsDefinition | ||
678 | QDomDocument doc; | 667 | m_toolsCount = 0; | ||
679 | m_toolsDefinition = doc.createElement( QStringLiteral("annotatingTools") ); | 668 | m_toolsDefinition.clear(); | ||
680 | foreach ( const QString &toolXml, userTools ) | 669 | QDomElement root = m_toolsDefinition.createElement( QStringLiteral( "root" ) ); | ||
670 | m_toolsDefinition.appendChild( root ); | ||||
671 | foreach ( const QString &toolXml, tools ) | ||||
681 | { | 672 | { | ||
682 | QDomDocument entryParser; | 673 | QDomDocument entryParser; | ||
683 | if ( entryParser.setContent( toolXml ) ) | 674 | if ( entryParser.setContent( toolXml ) ) { | ||
684 | m_toolsDefinition.appendChild( doc.importNode( entryParser.documentElement(), true ) ); | 675 | root.appendChild( m_toolsDefinition.importNode( entryParser.documentElement(), true ) ); | ||
685 | else | 676 | m_toolsCount++; | ||
677 | } else { | ||||
686 | qCWarning(OkularUiDebug) << "Skipping malformed tool XML in AnnotationTools setting"; | 678 | qCWarning(OkularUiDebug) << "Skipping malformed tool XML in AnnotationTools setting"; | ||
687 | } | 679 | } | ||
688 | | ||||
689 | // Create the AnnotationToolItems from the XML dom tree | | |||
690 | QDomNode toolDescription = m_toolsDefinition.firstChild(); | | |||
691 | while ( toolDescription.isElement() ) | | |||
692 | { | | |||
693 | QDomElement toolElement = toolDescription.toElement(); | | |||
694 | if ( toolElement.tagName() == QLatin1String("tool") ) | | |||
695 | { | | |||
696 | AnnotationToolItem item; | | |||
697 | item.id = toolElement.attribute(QStringLiteral("id")).toInt(); | | |||
698 | if ( toolElement.hasAttribute( QStringLiteral("name") ) ) | | |||
699 | item.text = toolElement.attribute( QStringLiteral("name") ); | | |||
700 | else | | |||
701 | item.text = defaultToolName( toolElement ); | | |||
702 | item.pixmap = makeToolPixmap( toolElement ); | | |||
703 | QDomNode shortcutNode = toolElement.elementsByTagName( QStringLiteral("shortcut") ).item( 0 ); | | |||
704 | if ( shortcutNode.isElement() ) | | |||
705 | item.shortcut = shortcutNode.toElement().text(); | | |||
706 | QDomNodeList engineNodeList = toolElement.elementsByTagName( QStringLiteral("engine") ); | | |||
707 | if ( engineNodeList.size() > 0 ) | | |||
708 | { | | |||
709 | QDomElement engineEl = engineNodeList.item( 0 ).toElement(); | | |||
710 | if ( !engineEl.isNull() && engineEl.hasAttribute( QStringLiteral("type") ) ) | | |||
711 | item.isText = engineEl.attribute( QStringLiteral("type") ) == QLatin1String( "TextSelector" ); | | |||
712 | } | 680 | } | ||
713 | m_items.push_back( item ); | | |||
714 | } | 681 | } | ||
715 | toolDescription = toolDescription.nextSibling(); | 682 | | ||
683 | QStringList toStringList() | ||||
684 | { | ||||
685 | QStringList tools; | ||||
686 | QDomElement toolElement = m_toolsDefinition.documentElement().firstChildElement(); | ||||
687 | QString str; | ||||
688 | QTextStream stream(&str); | ||||
689 | while( !toolElement.isNull() ) | ||||
690 | { | ||||
691 | str.clear(); | ||||
692 | toolElement.save(stream, -1 /* indent disabled */); | ||||
693 | tools << str; | ||||
694 | toolElement = toolElement.nextSiblingElement(); | ||||
716 | } | 695 | } | ||
696 | return tools; | ||||
717 | } | 697 | } | ||
718 | 698 | | |||
719 | PageViewAnnotator::~PageViewAnnotator() | 699 | QDomElement tool( int toolID ) | ||
720 | { | 700 | { | ||
721 | delete m_engine; | 701 | QDomElement toolElement = m_toolsDefinition.documentElement().firstChildElement(); | ||
702 | while( !toolElement.isNull() && toolElement.attribute("id").toInt() != toolID ) { | ||||
703 | toolElement = toolElement.nextSiblingElement(); | ||||
704 | } | ||||
705 | return toolElement; // can return a null element | ||||
722 | } | 706 | } | ||
723 | 707 | | |||
724 | void PageViewAnnotator::setEnabled( bool on ) | 708 | void appendTool( QDomElement toolElement ) | ||
725 | { | 709 | { | ||
726 | if ( !on ) | 710 | toolElement = toolElement.cloneNode().toElement(); | ||
727 | { | 711 | toolElement.setAttribute( QStringLiteral( "id" ), ++m_toolsCount ); | ||
728 | // remove toolBar | 712 | m_toolsDefinition.documentElement().appendChild( toolElement ); | ||
729 | if ( m_toolBar ) | | |||
730 | m_toolBar->hideAndDestroy(); | | |||
731 | m_toolBar = nullptr; | | |||
732 | // deactivate the active tool, if any | | |||
733 | slotToolSelected( -1 ); | | |||
734 | return; | | |||
735 | } | 713 | } | ||
736 | 714 | | |||
737 | // if no tools are defined, don't show the toolbar | 715 | bool updateTool( QDomElement newToolElement, int toolID ) | ||
738 | if ( !m_toolsDefinition.hasChildNodes() ) | | |||
739 | return; | | |||
740 | | ||||
741 | // create toolBar | | |||
742 | if ( !m_toolBar ) | | |||
743 | { | 716 | { | ||
744 | m_toolBar = new PageViewToolBar( m_pageView, m_pageView->viewport() ); | 717 | QDomElement toolElement = tool( toolID ); | ||
745 | m_toolBar->setSide( (PageViewToolBar::Side)Okular::Settings::editToolBarPlacement() ); | 718 | if ( toolElement.isNull() ) | ||
746 | m_toolBar->setItems( m_items ); | 719 | return false; | ||
747 | m_toolBar->setToolsEnabled( m_toolsEnabled ); | 720 | newToolElement = newToolElement.cloneNode().toElement(); | ||
748 | m_toolBar->setTextToolsEnabled( m_textToolsEnabled ); | 721 | newToolElement.setAttribute( QStringLiteral( "id" ), toolID ); | ||
749 | connect(m_toolBar, &PageViewToolBar::toolSelected, this, &PageViewAnnotator::slotToolSelected); | 722 | QDomNode oldTool = m_toolsDefinition.documentElement().replaceChild( newToolElement, toolElement ); | ||
750 | connect(m_toolBar, &PageViewToolBar::orientationChanged, this, &PageViewAnnotator::slotSaveToolbarOrientation); | 723 | return !oldTool.isNull(); | ||
751 | | ||||
752 | connect(m_toolBar, &PageViewToolBar::buttonDoubleClicked, this, &PageViewAnnotator::slotToolDoubleClicked); | | |||
753 | m_toolBar->setCursor(Qt::ArrowCursor); | | |||
754 | } | 724 | } | ||
755 | 725 | | |||
756 | // show the toolBar | 726 | private: | ||
757 | m_toolBar->showAndAnimate(); | 727 | QDomDocument m_toolsDefinition; | ||
758 | } | 728 | int m_toolsCount; | ||
729 | }; | ||||
759 | 730 | | |||
760 | void PageViewAnnotator::setTextToolsEnabled( bool enabled ) | 731 | /** PageViewAnnotator **/ | ||
732 | PageViewAnnotator::PageViewAnnotator( PageView * parent, Okular::Document * storage ) | ||||
733 | : QObject( parent ), m_document( storage ), m_pageView( parent ), | ||||
734 | m_actionHandler( nullptr ), m_engine( nullptr ), m_toolsDefinition( nullptr ), | ||||
735 | m_quickToolsDefinition( nullptr ), m_continuousMode( true ), m_lastToolID( -1 ), | ||||
736 | m_lockedItem( nullptr ) | ||||
761 | { | 737 | { | ||
762 | m_textToolsEnabled = enabled; | 738 | reparseConfig(); | ||
763 | if ( m_toolBar ) | | |||
764 | m_toolBar->setTextToolsEnabled( m_textToolsEnabled ); | | |||
765 | } | 739 | } | ||
766 | 740 | | |||
767 | void PageViewAnnotator::setToolsEnabled( bool enabled ) | 741 | void PageViewAnnotator::reparseConfig() | ||
768 | { | 742 | { | ||
769 | m_toolsEnabled = enabled; | 743 | // Read tool list from configuration. It's a list of XML <tool></tool> elements | ||
770 | if ( m_toolBar ) | 744 | if( !m_toolsDefinition ) | ||
771 | m_toolBar->setToolsEnabled( m_toolsEnabled ); | 745 | m_toolsDefinition = new AnnotationTools(); | ||
772 | } | 746 | m_toolsDefinition->setTools( Okular::Settings::annotationTools() ); | ||
773 | 747 | | |||
774 | void PageViewAnnotator::setHidingForced( bool forced ) | 748 | if( !m_quickToolsDefinition ) | ||
775 | { | 749 | m_quickToolsDefinition = new AnnotationTools(); | ||
776 | m_hidingWasForced = forced; | 750 | m_quickToolsDefinition->setTools( Okular::Settings::quickAnnotationTools() ); | ||
751 | | ||||
752 | m_continuousMode = Okular::Settings::annotationContinuousMode(); | ||||
753 | | ||||
754 | if ( Okular::Settings::identityAuthor().isEmpty() ) | ||||
755 | detachAnnotation(); | ||||
756 | | ||||
757 | if( m_actionHandler ) | ||||
758 | m_actionHandler->reparseTools(); | ||||
777 | } | 759 | } | ||
778 | 760 | | |||
779 | bool PageViewAnnotator::hidingWasForced() const | 761 | PageViewAnnotator::~PageViewAnnotator() | ||
780 | { | 762 | { | ||
781 | return m_hidingWasForced; | 763 | delete m_engine; | ||
782 | } | 764 | } | ||
783 | 765 | | |||
784 | bool PageViewAnnotator::active() const | 766 | bool PageViewAnnotator::active() const | ||
785 | { | 767 | { | ||
786 | return m_engine && m_toolBar; | 768 | return m_engine != nullptr; | ||
787 | } | 769 | } | ||
788 | 770 | | |||
789 | bool PageViewAnnotator::annotating() const | 771 | bool PageViewAnnotator::annotating() const | ||
790 | { | 772 | { | ||
791 | return active() && m_lockedItem; | 773 | return active() && m_lockedItem; | ||
792 | } | 774 | } | ||
793 | 775 | | |||
794 | QCursor PageViewAnnotator::cursor() const | 776 | QCursor PageViewAnnotator::cursor() const | ||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Line(s) | 838 | { | |||
861 | annotation->setAuthor( Okular::Settings::identityAuthor() ); | 843 | annotation->setAuthor( Okular::Settings::identityAuthor() ); | ||
862 | m_document->addPageAnnotation( m_lockedItem->pageNumber(), annotation ); | 844 | m_document->addPageAnnotation( m_lockedItem->pageNumber(), annotation ); | ||
863 | 845 | | |||
864 | if ( annotation->openDialogAfterCreation() ) | 846 | if ( annotation->openDialogAfterCreation() ) | ||
865 | m_pageView->openAnnotationWindow( annotation, m_lockedItem->pageNumber() ); | 847 | m_pageView->openAnnotationWindow( annotation, m_lockedItem->pageNumber() ); | ||
866 | } | 848 | } | ||
867 | 849 | | |||
868 | if ( m_continuousMode ) | 850 | if ( m_continuousMode ) | ||
869 | slotToolSelected( m_lastToolID ); | 851 | selectTool( m_lastToolID ); | ||
870 | else | 852 | else | ||
871 | detachAnnotation(); | 853 | detachAnnotation(); | ||
872 | } | 854 | } | ||
873 | 855 | | |||
874 | return modifiedRect; | 856 | return modifiedRect; | ||
875 | } | 857 | } | ||
876 | 858 | | |||
877 | QRect PageViewAnnotator::routeMouseEvent( QMouseEvent * e, PageViewItem * item ) | 859 | QRect PageViewAnnotator::routeMouseEvent( QMouseEvent * e, PageViewItem * item ) | ||
Show All 12 Lines | 871 | { | |||
890 | // Unlike routeMouseEvent, routeTabletEvent must explicitly ignore events it doesn't care about so that | 872 | // Unlike routeMouseEvent, routeTabletEvent must explicitly ignore events it doesn't care about so that | ||
891 | // the corresponding mouse event will later be delivered. | 873 | // the corresponding mouse event will later be delivered. | ||
892 | if ( !item ) | 874 | if ( !item ) | ||
893 | { | 875 | { | ||
894 | e->ignore(); | 876 | e->ignore(); | ||
895 | return QRect(); | 877 | return QRect(); | ||
896 | } | 878 | } | ||
897 | 879 | | |||
898 | // We set all tablet events that take place over the annotations toolbar to ignore so that corresponding mouse | | |||
899 | // events will be delivered to the toolbar. However, we still allow the annotations code to handle | | |||
900 | // TabletMove and TabletRelease events in case the user is drawing an annotation onto the toolbar. | | |||
901 | const QPoint toolBarPos = m_toolBar->mapFromGlobal( e->globalPos() ); | | |||
902 | const QRect toolBarRect = m_toolBar->rect(); | | |||
903 | if ( toolBarRect.contains( toolBarPos ) ) | | |||
904 | { | | |||
905 | e->ignore(); | | |||
906 | if (e->type() == QEvent::TabletPress) | | |||
907 | return QRect(); | | |||
908 | } | | |||
909 | | ||||
910 | AnnotatorEngine::EventType eventType; | 880 | AnnotatorEngine::EventType eventType; | ||
911 | AnnotatorEngine::Button button; | 881 | AnnotatorEngine::Button button; | ||
912 | 882 | | |||
913 | // figure out the event type and button | 883 | // figure out the event type and button | ||
914 | AnnotatorEngine::decodeEvent( e, &eventType, &button ); | 884 | AnnotatorEngine::decodeEvent( e, &eventType, &button ); | ||
915 | 885 | | |||
916 | const QPointF globalPosF = e->globalPosF(); | 886 | const QPointF globalPosF = e->globalPosF(); | ||
917 | const QPointF localPosF = globalPosF - localOriginInGlobal; | 887 | const QPointF localPosF = globalPosF - localOriginInGlobal; | ||
918 | return performRouteMouseOrTabletEvent( eventType, button, localPosF, item ); | 888 | return performRouteMouseOrTabletEvent( eventType, button, localPosF, item ); | ||
919 | } | 889 | } | ||
920 | 890 | | |||
921 | bool PageViewAnnotator::routeKeyEvent( QKeyEvent * event ) | 891 | bool PageViewAnnotator::routeKeyEvent( QKeyEvent * event ) | ||
922 | { | 892 | { | ||
923 | if ( event->key() == Qt::Key_Escape ) | 893 | if ( event->key() == Qt::Key_Escape ) | ||
924 | { | 894 | { | ||
925 | detachAnnotation(); | 895 | detachAnnotation(); | ||
926 | return true; | 896 | return true; | ||
927 | } | 897 | } | ||
928 | return false; | 898 | return false; | ||
929 | } | 899 | } | ||
930 | 900 | | |||
931 | bool PageViewAnnotator::routePaints( const QRect & wantedRect ) const | 901 | bool PageViewAnnotator::routePaints( const QRect & wantedRect ) const | ||
932 | { | 902 | { | ||
933 | return m_engine && m_toolBar && wantedRect.intersects( m_lastDrawnRect ) && m_lockedItem; | 903 | return m_engine && wantedRect.intersects( m_lastDrawnRect ) && m_lockedItem; | ||
934 | } | 904 | } | ||
935 | 905 | | |||
936 | void PageViewAnnotator::routePaint( QPainter * painter, const QRect & paintRect ) | 906 | void PageViewAnnotator::routePaint( QPainter * painter, const QRect & paintRect ) | ||
937 | { | 907 | { | ||
938 | // if there's no locked item, then there's no decided place to draw on | 908 | // if there's no locked item, then there's no decided place to draw on | ||
939 | if ( !m_lockedItem ) | 909 | if ( !m_lockedItem ) | ||
940 | return; | 910 | return; | ||
941 | 911 | | |||
Show All 12 Lines | 916 | #endif | |||
954 | QRect annotRect = paintRect.intersected( m_lastDrawnRect ); | 924 | QRect annotRect = paintRect.intersected( m_lastDrawnRect ); | ||
955 | annotRect.translate( -itemRect.topLeft() ); | 925 | annotRect.translate( -itemRect.topLeft() ); | ||
956 | 926 | | |||
957 | // use current engine for painting (in virtual page coordinates) | 927 | // use current engine for painting (in virtual page coordinates) | ||
958 | m_engine->paint( painter, m_lockedItem->uncroppedWidth(), m_lockedItem->uncroppedHeight(), annotRect ); | 928 | m_engine->paint( painter, m_lockedItem->uncroppedWidth(), m_lockedItem->uncroppedHeight(), annotRect ); | ||
959 | painter->restore(); | 929 | painter->restore(); | ||
960 | } | 930 | } | ||
961 | 931 | | |||
962 | void PageViewAnnotator::slotToolSelected( int toolID ) | 932 | void PageViewAnnotator::selectTool( int toolID ) | ||
963 | { | 933 | { | ||
934 | | ||||
935 | // ask for Author's name if not already set | ||||
936 | if ( toolID > 0 && Okular::Settings::identityAuthor().isEmpty() ) | ||||
937 | { | ||||
938 | // get default username from the kdelibs/kdecore/KUser | ||||
939 | KUser currentUser; | ||||
940 | QString userName = currentUser.property( KUser::FullName ).toString(); | ||||
941 | userName = ""; | ||||
942 | // ask the user for confirmation/change | ||||
943 | if ( userName.isEmpty() ) | ||||
944 | { | ||||
945 | bool ok = false; | ||||
946 | userName = QInputDialog::getText(nullptr, | ||||
947 | i18n( "Bookmark annotation" ), | ||||
948 | i18n( "Insert a custom name for the annotation:" ), | ||||
949 | QLineEdit::Normal, | ||||
950 | QString(), | ||||
951 | &ok ); | ||||
952 | | ||||
953 | if ( !ok ) | ||||
954 | { | ||||
955 | detachAnnotation(); | ||||
956 | return; | ||||
957 | } | ||||
958 | } | ||||
959 | // save the name | ||||
960 | Okular::Settings::setIdentityAuthor( userName ); | ||||
961 | Okular::Settings::self()->save(); | ||||
962 | } | ||||
963 | | ||||
964 | // terminate any previous operation | 964 | // terminate any previous operation | ||
965 | if ( m_engine ) | 965 | if ( m_engine ) | ||
966 | { | 966 | { | ||
967 | delete m_engine; | 967 | delete m_engine; | ||
968 | m_engine = nullptr; | 968 | m_engine = nullptr; | ||
969 | } | 969 | } | ||
970 | m_lockedItem = nullptr; | 970 | m_lockedItem = nullptr; | ||
971 | if ( m_lastDrawnRect.isValid() ) | 971 | if ( m_lastDrawnRect.isValid() ) | ||
972 | { | 972 | { | ||
973 | m_pageView->viewport()->update( m_lastDrawnRect.translated( -m_pageView->contentAreaPosition() ) ); | 973 | m_pageView->viewport()->update( m_lastDrawnRect.translated( -m_pageView->contentAreaPosition() ) ); | ||
974 | m_lastDrawnRect = QRect(); | 974 | m_lastDrawnRect = QRect(); | ||
975 | } | 975 | } | ||
976 | 976 | | |||
977 | if ( toolID != m_lastToolID ) m_continuousMode = false; | | |||
978 | // store current tool for later usage | 977 | // store current tool for later usage | ||
979 | m_lastToolID = toolID; | 978 | m_lastToolID = toolID; | ||
980 | 979 | | |||
981 | // handle tool deselection | 980 | // handle tool deselection | ||
982 | if ( toolID == -1 ) | 981 | if ( toolID == -1 ) | ||
983 | { | 982 | { | ||
984 | m_pageView->displayMessage( QString() ); | 983 | m_pageView->displayMessage( QString() ); | ||
985 | m_pageView->updateCursor(); | 984 | m_pageView->updateCursor(); | ||
986 | return; | 985 | return; | ||
987 | } | 986 | } | ||
988 | 987 | | |||
989 | // for the selected tool create the Engine | 988 | // for the selected tool create the Engine | ||
990 | QDomNode toolNode = m_toolsDefinition.firstChild(); | 989 | QDomElement toolElement = m_toolsDefinition->tool( toolID ); | ||
991 | while ( toolNode.isElement() ) | 990 | if ( !toolElement.isNull() ) | ||
992 | { | 991 | { | ||
993 | QDomElement toolElement = toolNode.toElement(); | | |||
994 | toolNode = toolNode.nextSibling(); | | |||
995 | | ||||
996 | // only find out the element describing selected tool | | |||
997 | if ( toolElement.tagName() != QLatin1String("tool") || toolElement.attribute(QStringLiteral("id")).toInt() != toolID ) | | |||
998 | continue; | | |||
999 | | ||||
1000 | // parse tool properties | 992 | // parse tool properties | ||
1001 | QDomNode toolSubNode = toolElement.firstChild(); | 993 | QDomElement engineElement = toolElement.firstChildElement( QStringLiteral("engine") ); | ||
1002 | while ( toolSubNode.isElement() ) | 994 | if ( !engineElement.isNull() ) | ||
1003 | { | 995 | { | ||
1004 | QDomElement toolSubElement = toolSubNode.toElement(); | | |||
1005 | toolSubNode = toolSubNode.nextSibling(); | | |||
1006 | | ||||
1007 | // create the AnnotatorEngine | 996 | // create the AnnotatorEngine | ||
1008 | if ( toolSubElement.tagName() == QLatin1String("engine") ) | 997 | QString type = engineElement.attribute( QStringLiteral("type") ); | ||
1009 | { | | |||
1010 | QString type = toolSubElement.attribute( QStringLiteral("type") ); | | |||
1011 | if ( type == QLatin1String("SmoothLine") ) | 998 | if ( type == QLatin1String("SmoothLine") ) | ||
1012 | m_engine = new SmoothPathEngine( toolSubElement ); | 999 | m_engine = new SmoothPathEngine( engineElement ); | ||
1013 | else if ( type == QLatin1String("PickPoint") ) | 1000 | else if ( type == QLatin1String("PickPoint") ) | ||
1014 | m_engine = new PickPointEngine( toolSubElement ); | 1001 | m_engine = new PickPointEngine( engineElement ); | ||
1015 | else if ( type == QLatin1String("PolyLine") ) | 1002 | else if ( type == QLatin1String("PolyLine") ) | ||
1016 | m_engine = new PolyLineEngine( toolSubElement ); | 1003 | m_engine = new PolyLineEngine( engineElement ); | ||
1017 | else if ( type == QLatin1String("TextSelector") ) | 1004 | else if ( type == QLatin1String("TextSelector") ) | ||
1018 | m_engine = new TextSelectorEngine( toolSubElement, m_pageView ); | 1005 | m_engine = new TextSelectorEngine( engineElement, m_pageView ); | ||
1019 | else | 1006 | else | ||
1020 | qCWarning(OkularUiDebug).nospace() << "tools.xml: engine type:'" << type << "' is not defined!"; | 1007 | qCWarning(OkularUiDebug).nospace() << "tools.xml: engine type:'" << type << "' is not defined!"; | ||
1021 | } | | |||
1022 | 1008 | | |||
1023 | // display the tooltip | 1009 | // display the tooltip | ||
1024 | const QString annotType = toolElement.attribute( QStringLiteral("type") ); | 1010 | const QString annotType = toolElement.attribute( QStringLiteral("type") ); | ||
1025 | QString tip; | 1011 | QString tip; | ||
1026 | 1012 | | |||
1027 | if ( annotType == QLatin1String("ellipse") ) | 1013 | if ( annotType == QLatin1String("ellipse") ) | ||
1028 | tip = i18nc( "Annotation tool", "Draw an ellipse (drag to select a zone)" ); | 1014 | tip = i18nc( "Annotation tool", "Draw an ellipse (drag to select a zone)" ); | ||
1029 | else if ( annotType == QLatin1String("highlight") ) | 1015 | else if ( annotType == QLatin1String("highlight") ) | ||
Show All 27 Lines | |||||
1057 | 1043 | | |||
1058 | // consistency warning | 1044 | // consistency warning | ||
1059 | if ( !m_engine ) | 1045 | if ( !m_engine ) | ||
1060 | { | 1046 | { | ||
1061 | qCWarning(OkularUiDebug) << "tools.xml: couldn't find good engine description. check xml."; | 1047 | qCWarning(OkularUiDebug) << "tools.xml: couldn't find good engine description. check xml."; | ||
1062 | } | 1048 | } | ||
1063 | 1049 | | |||
1064 | m_pageView->updateCursor(); | 1050 | m_pageView->updateCursor(); | ||
1065 | // stop after parsing selected tool's node | | |||
1066 | break; | | |||
1067 | } | | |||
1068 | } | 1051 | } | ||
1069 | 1052 | | |||
1070 | void PageViewAnnotator::slotSaveToolbarOrientation( int side ) | 1053 | if( toolID > 0 ) | ||
1071 | { | 1054 | emit toolSelected(); | ||
1072 | Okular::Settings::setEditToolBarPlacement( (int)side ); | | |||
1073 | Okular::Settings::self()->save(); | | |||
1074 | } | 1055 | } | ||
1075 | 1056 | | |||
1076 | void PageViewAnnotator::slotToolDoubleClicked( int /*toolID*/ ) | 1057 | void PageViewAnnotator::selectStampTool( QString stampSymbol ) | ||
1077 | { | 1058 | { | ||
1078 | m_continuousMode = true; | 1059 | const int STAMP_TOOL_ID = 14; | ||
1060 | QDomElement toolElement = builtinTool( STAMP_TOOL_ID ); | ||||
1061 | QDomElement engineElement = toolElement.firstChildElement( QStringLiteral("engine") ); | ||||
1062 | QDomElement annotationElement = engineElement.firstChildElement( QStringLiteral("annotation") ); | ||||
1063 | engineElement.setAttribute( QStringLiteral( "hoverIcon" ), stampSymbol ); | ||||
1064 | annotationElement.setAttribute( QStringLiteral( "icon" ), stampSymbol ); | ||||
1065 | saveAnnotationTools(); | ||||
1066 | selectTool( STAMP_TOOL_ID ); | ||||
1079 | } | 1067 | } | ||
1080 | 1068 | | |||
1081 | void PageViewAnnotator::detachAnnotation() | 1069 | void PageViewAnnotator::detachAnnotation() | ||
1082 | { | 1070 | { | ||
1083 | m_toolBar->selectButton( -1 ); | 1071 | selectTool( -1 ); | ||
1072 | if( m_actionHandler ) | ||||
1073 | m_actionHandler->deselectAllAnnotationActions(); | ||||
1084 | } | 1074 | } | ||
1085 | 1075 | | |||
1086 | QString PageViewAnnotator::defaultToolName( const QDomElement &toolElement ) | 1076 | QString PageViewAnnotator::defaultToolName( const QDomElement &toolElement ) | ||
1087 | { | 1077 | { | ||
1088 | const QString annotType = toolElement.attribute( QStringLiteral("type") ); | 1078 | const QString annotType = toolElement.attribute( QStringLiteral("type") ); | ||
1089 | 1079 | | |||
1090 | if ( annotType == QLatin1String("ellipse") ) | 1080 | if ( annotType == QLatin1String("ellipse") ) | ||
1091 | return i18n( "Ellipse" ); | 1081 | return i18n( "Ellipse" ); | ||
▲ Show 20 Lines • Show All 181 Lines • ▼ Show 20 Line(s) | 1262 | { | |||
1273 | /* Unrecognized annotation type -- It shouldn't happen */ | 1263 | /* Unrecognized annotation type -- It shouldn't happen */ | ||
1274 | p.setPen( QPen( engineColor ) ); | 1264 | p.setPen( QPen( engineColor ) ); | ||
1275 | p.drawText( QPoint(20, 31), QStringLiteral("?") ); | 1265 | p.drawText( QPoint(20, 31), QStringLiteral("?") ); | ||
1276 | } | 1266 | } | ||
1277 | 1267 | | |||
1278 | return pixmap; | 1268 | return pixmap; | ||
1279 | } | 1269 | } | ||
1280 | 1270 | | |||
1271 | void PageViewAnnotator::setupActions( KActionCollection * ac ) | ||||
1272 | { | ||||
1273 | if ( !m_actionHandler ) { | ||||
1274 | m_actionHandler = new AnnotationActionHandler( this, ac ); | ||||
1275 | } | ||||
1276 | } | ||||
1277 | | ||||
1278 | bool PageViewAnnotator::continuousMode() | ||||
1279 | { | ||||
1280 | return m_continuousMode; | ||||
1281 | } | ||||
1282 | | ||||
1283 | void PageViewAnnotator::setContinuousMode( bool enabled ) | ||||
1284 | { | ||||
1285 | m_continuousMode = enabled; | ||||
1286 | Okular::Settings::setAnnotationContinuousMode( enabled ); | ||||
1287 | Okular::Settings::self()->save(); | ||||
1288 | } | ||||
1289 | | ||||
1290 | void PageViewAnnotator::setToolsEnabled( bool enabled ) | ||||
1291 | { | ||||
1292 | if ( m_actionHandler ) | ||||
1293 | m_actionHandler->setToolsEnabled( enabled ); | ||||
1294 | } | ||||
1295 | | ||||
1296 | void PageViewAnnotator::setTextToolsEnabled( bool enabled ) | ||||
1297 | { | ||||
1298 | if ( m_actionHandler ) | ||||
1299 | m_actionHandler->setTextToolsEnabled( enabled ); | ||||
1300 | } | ||||
1301 | | ||||
1302 | void PageViewAnnotator::saveAnnotationTools() | ||||
1303 | { | ||||
1304 | Okular::Settings::setAnnotationTools( m_toolsDefinition->toStringList() ); | ||||
1305 | Okular::Settings::setQuickAnnotationTools( m_quickToolsDefinition->toStringList() ); | ||||
1306 | Okular::Settings::self()->save(); | ||||
1307 | } | ||||
1308 | | ||||
1309 | int PageViewAnnotator::setQuickTool( int favToolID ) | ||||
1310 | { | ||||
1311 | int toolId = -1; | ||||
1312 | QDomElement favToolElement = m_quickToolsDefinition->tool( favToolID ); | ||||
1313 | if ( !favToolElement.isNull() && favToolElement.hasAttribute( QStringLiteral("sourceId") ) ) | ||||
1314 | { | ||||
1315 | toolId = favToolElement.attribute( QStringLiteral("sourceId") ).toInt(); | ||||
1316 | if ( m_toolsDefinition->updateTool( favToolElement, toolId ) ) | ||||
1317 | saveAnnotationTools(); | ||||
1318 | } | ||||
1319 | return toolId; | ||||
1320 | } | ||||
1321 | | ||||
1322 | QDomElement PageViewAnnotator::builtinTool( int toolID ) | ||||
1323 | { | ||||
1324 | return m_toolsDefinition->tool( toolID ); | ||||
1325 | } | ||||
1326 | | ||||
1327 | QDomElement PageViewAnnotator::quickTool( int toolID ) | ||||
1328 | { | ||||
1329 | return m_quickToolsDefinition->tool( toolID ); | ||||
1330 | } | ||||
1331 | | ||||
1332 | QDomElement PageViewAnnotator::currentEngineElement() | ||||
1333 | { | ||||
1334 | return m_toolsDefinition->tool( m_lastToolID ).firstChildElement( QStringLiteral("engine") ); | ||||
1335 | } | ||||
1336 | | ||||
1337 | QDomElement PageViewAnnotator::currentAnnotationElement() | ||||
1338 | { | ||||
1339 | return currentEngineElement().firstChildElement( QStringLiteral("annotation") ); | ||||
1340 | } | ||||
1341 | | ||||
1342 | void PageViewAnnotator::setAnnotationWidth( double width ) | ||||
1343 | { | ||||
1344 | currentAnnotationElement().setAttribute( QStringLiteral( "width" ), width ); | ||||
1345 | saveAnnotationTools(); | ||||
1346 | selectTool( m_lastToolID ); | ||||
1347 | } | ||||
1348 | | ||||
1349 | void PageViewAnnotator::setAnnotationColor( QColor color ) | ||||
1350 | { | ||||
1351 | currentEngineElement().setAttribute( QStringLiteral( "color" ), color.name(QColor::HexRgb ) ); | ||||
1352 | QDomElement annotationElement = currentAnnotationElement(); | ||||
1353 | QString annotType = annotationElement.attribute( QStringLiteral( "type" ) ); | ||||
1354 | if ( annotType == "Typewriter" || annotType == "FreeText" ) { | ||||
1355 | annotationElement.setAttribute( QStringLiteral( "textColor" ), color.name( QColor::HexRgb ) ); | ||||
1356 | } else { | ||||
1357 | annotationElement.setAttribute( QStringLiteral( "color" ), color.name( QColor::HexRgb ) ); | ||||
1358 | } | ||||
1359 | saveAnnotationTools(); | ||||
1360 | selectTool( m_lastToolID ); | ||||
1361 | } | ||||
1362 | | ||||
1363 | void PageViewAnnotator::setAnnotationInnerColor( QColor color ) | ||||
1364 | { | ||||
1365 | QDomElement annotationElement = currentAnnotationElement(); | ||||
1366 | QString annotType = annotationElement.attribute( QStringLiteral( "type" ) ); | ||||
1367 | if ( annotType == "FreeText" ) { | ||||
1368 | annotationElement.setAttribute( QStringLiteral( "color" ), color.name( QColor::HexRgb ) ); | ||||
1369 | } else { | ||||
1370 | annotationElement.setAttribute( QStringLiteral( "innerColor" ), color.name( QColor::HexRgb ) ); | ||||
1371 | } | ||||
1372 | saveAnnotationTools(); | ||||
1373 | selectTool( m_lastToolID ); | ||||
1374 | } | ||||
1375 | | ||||
1376 | void PageViewAnnotator::setAnnotationOpacity( double opacity ) | ||||
1377 | { | ||||
1378 | currentAnnotationElement().setAttribute( QStringLiteral( "opacity" ), opacity ); | ||||
1379 | saveAnnotationTools(); | ||||
1380 | selectTool( m_lastToolID ); | ||||
1381 | } | ||||
1382 | | ||||
1383 | void PageViewAnnotator::setAnnotationFont( QFont font ) | ||||
1384 | { | ||||
1385 | currentAnnotationElement().setAttribute( QStringLiteral( "font" ), font.toString() ); | ||||
1386 | saveAnnotationTools(); | ||||
1387 | selectTool( m_lastToolID ); | ||||
1388 | } | ||||
1389 | | ||||
1390 | void PageViewAnnotator::addToQuickAnnotations() | ||||
1391 | { | ||||
1392 | QDomElement sourceToolElement = m_toolsDefinition->tool( m_lastToolID ); | ||||
1393 | if( sourceToolElement.isNull() ) | ||||
1394 | return; | ||||
1395 | | ||||
1396 | // set custom name for quick annotation | ||||
1397 | bool ok = false; | ||||
1398 | QString itemText = QInputDialog::getText(nullptr, | ||||
1399 | i18n( "Add favorite annotation" ), | ||||
1400 | i18n( "Custom annotation name:" ), | ||||
1401 | QLineEdit::Normal, | ||||
1402 | defaultToolName( sourceToolElement ), | ||||
1403 | &ok ); | ||||
1404 | if( !ok ) | ||||
1405 | return; | ||||
1406 | | ||||
1407 | QDomElement toolElement = sourceToolElement.cloneNode().toElement(); | ||||
1408 | // store name attribute only if the user specified a customized name | ||||
1409 | if ( !itemText.isEmpty() ) | ||||
1410 | toolElement.setAttribute( QStringLiteral("name"), itemText ); | ||||
1411 | toolElement.setAttribute( QStringLiteral("sourceId"), sourceToolElement.attribute( QStringLiteral("id") ) ); | ||||
1412 | m_quickToolsDefinition->appendTool( toolElement ); | ||||
1413 | saveAnnotationTools(); | ||||
1414 | } | ||||
1415 | | ||||
1416 | void PageViewAnnotator::slotAdvancedSettings() | ||||
1417 | { | ||||
1418 | QDomElement toolElement = m_toolsDefinition->tool( m_lastToolID ); | ||||
1419 | | ||||
1420 | EditAnnotToolDialog t( nullptr, toolElement, true ); | ||||
1421 | if ( t.exec() != QDialog::Accepted ) | ||||
1422 | return; | ||||
1423 | | ||||
1424 | QDomElement toolElementUpdated = t.toolXml().documentElement(); | ||||
1425 | int toolID = toolElement.attribute( QStringLiteral("id") ).toInt(); | ||||
1426 | m_toolsDefinition->updateTool( toolElementUpdated, toolID ); | ||||
1427 | saveAnnotationTools(); | ||||
1428 | selectTool( m_lastToolID ); | ||||
1429 | } | ||||
1430 | | ||||
1281 | #include "moc_pageviewannotator.cpp" | 1431 | #include "moc_pageviewannotator.cpp" | ||
1282 | 1432 | | |||
1283 | /* kate: replace-tabs on; indent-width 4; */ | 1433 | /* kate: replace-tabs on; indent-width 4; */ |