From d77c8180051bde6b751ba67e9d3aa9ee6023e91c Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Fri, 24 Feb 2023 10:35:09 +0100 Subject: [PATCH] New Feature : Pdf viewer --- CHANGELOG.md | 2 +- CMakeLists.txt | 2 + README.md | 1 + linphone-app/CMakeLists.txt | 47 +- .../assets/images/rotation_custom.svg | 57 ++ linphone-app/assets/images/zoom_in_custom.svg | 47 ++ .../assets/images/zoom_out_custom.svg | 47 ++ linphone-app/assets/languages/da.ts | 107 ++++ linphone-app/assets/languages/de.ts | 107 ++++ linphone-app/assets/languages/en.ts | 108 ++++ linphone-app/assets/languages/es.ts | 107 ++++ linphone-app/assets/languages/fr_FR.ts | 129 ++++- linphone-app/assets/languages/hu.ts | 107 ++++ linphone-app/assets/languages/it.ts | 107 ++++ linphone-app/assets/languages/ja.ts | 113 +++- linphone-app/assets/languages/lt.ts | 107 ++++ linphone-app/assets/languages/pt_BR.ts | 107 ++++ linphone-app/assets/languages/ru.ts | 107 ++++ linphone-app/assets/languages/sv.ts | 107 ++++ linphone-app/assets/languages/tr.ts | 107 ++++ linphone-app/assets/languages/uk.ts | 107 ++++ linphone-app/assets/languages/zh_CN.ts | 107 ++++ linphone-app/resources.qrc | 3 + linphone-app/src/app/App.cpp | 18 +- linphone-app/src/app/App.hpp | 4 + .../src/app/providers/ImageProvider.cpp | 13 +- .../src/app/providers/ImageProvider.hpp | 7 +- linphone-app/src/components/pdf/PdfWidget.cpp | 297 ++++++++++ linphone-app/src/components/pdf/PdfWidget.hpp | 106 ++++ linphone-app/src/components/pdf/PdfWidget.ui | 540 ++++++++++++++++++ linphone-app/src/utils/Utils.cpp | 51 +- linphone-app/src/utils/Utils.hpp | 10 + .../modules/Common/Dialog/FileViewDialog.qml | 7 + .../modules/Linphone/Chat/ChatTextMessage.qml | 2 +- 34 files changed, 2855 insertions(+), 40 deletions(-) create mode 100644 linphone-app/assets/images/rotation_custom.svg create mode 100644 linphone-app/assets/images/zoom_in_custom.svg create mode 100644 linphone-app/assets/images/zoom_out_custom.svg create mode 100644 linphone-app/src/components/pdf/PdfWidget.cpp create mode 100644 linphone-app/src/components/pdf/PdfWidget.hpp create mode 100644 linphone-app/src/components/pdf/PdfWidget.ui diff --git a/CHANGELOG.md b/CHANGELOG.md index f75b4482c..2443c6ae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - VFS Encryption -- File viewer in chats (Image/Animated Image/Video/Texts) with the option to export the file. +- File viewer in chats (Image/Animated Image/Video/Texts/Pdf) with the option to export the file. - Accept/decline CLI commands. - Colored Emojis with its own font family. - OAuth2 connection to retrieve remote provisioning (Experimental and not usable without configuration). diff --git a/CMakeLists.txt b/CMakeLists.txt index b3c983d4c..221f3abef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ option(ENABLE_APP_LICENSE "Enable the license in packages." YES) option(ENABLE_APP_OAUTH2 "Build with OAuth2 support for remote provisioning." OFF) #Experimental. option(ENABLE_APP_PACKAGING "Enable packaging" NO) option(ENABLE_APP_PACKAGE_ROOTCA "Embed the rootca file into the package" YES) +option(ENABLE_APP_PDF_VIEWER "Enable Pdf viewer" YES) option(ENABLE_APP_WEBVIEW "Enable webviews." NO) #Webview is not fully supported because of deployments. Used for subscription. option(ENABLE_BUILD_APP_PLUGINS "Enable the build of plugins" YES) option(ENABLE_BUILD_EXAMPLES "Enable the build of examples" NO) @@ -145,6 +146,7 @@ list(APPEND APP_OPTIONS "-DENABLE_APP_LICENSE=${ENABLE_APP_LICENSE}") list(APPEND APP_OPTIONS "-DENABLE_APP_OAUTH2=${ENABLE_APP_OAUTH2}") list(APPEND APP_OPTIONS "-DENABLE_APP_PACKAGING=${ENABLE_APP_PACKAGING}") list(APPEND APP_OPTIONS "-DENABLE_APP_PACKAGE_ROOTCA=${ENABLE_APP_PACKAGE_ROOTCA}") +list(APPEND APP_OPTIONS "-DENABLE_APP_PDF_VIEWER=${ENABLE_APP_PDF_VIEWER}") list(APPEND APP_OPTIONS "-DENABLE_APP_WEBVIEW=${ENABLE_APP_WEBVIEW}") list(APPEND APP_OPTIONS "-DENABLE_BUILD_EXAMPLES=${ENABLE_BUILD_EXAMPLES}") list(APPEND APP_OPTIONS "-DENABLE_BUILD_VERBOSE=${ENABLE_BUILD_VERBOSE}") diff --git a/README.md b/README.md index a5dc1fd38..11d8a785a 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,7 @@ Also, more configurations are available in the docker-files folder of linphone-s | :--- | :---: | ---: | | ENABLE_APP_LICENSE | Enable the license in packages. | YES | | ENABLE_APP_PACKAGING | Enable packaging. Package will be deployed in `OUTPUT/packages` | NO | +| ENABLE_APP_PDF_VIEWER | Enable PDF viewer. Need Qt PDF module. | YES | | ENABLE_APP_WEBVIEW | Enable webview for accounts. The Webview engine must be deployed, it takes a large size. | NO | | ENABLE_APP_PACKAGE_ROOTCA | Embed the rootca file (concatenation of all root certificates published by mozilla) into the package | YES | | ENABLE_BUILD_APP_PLUGINS | Enable the build of plugins | YES | diff --git a/linphone-app/CMakeLists.txt b/linphone-app/CMakeLists.txt index c1f9247d6..f00f19a18 100644 --- a/linphone-app/CMakeLists.txt +++ b/linphone-app/CMakeLists.txt @@ -153,12 +153,30 @@ if (UNIX AND NOT APPLE) list(APPEND QT5_PACKAGES DBus) endif () set(QT5_PACKAGES_OPTIONAL TextToSpeech QmlModels) +if(ENABLE_APP_PDF_VIEWER) + list(APPEND QT5_PACKAGES_OPTIONAL Pdf PdfWidgets) +endif() set(CMAKE_AUTOMOC ON) +SET(CMAKE_AUTOUIC ON) find_package(Qt5 COMPONENTS ${QT5_PACKAGES} REQUIRED) find_package(Qt5 COMPONENTS ${QT5_PACKAGES_OPTIONAL} QUIET) +set(LIBRARIES) +set(INCLUDED_DIRECTORIES) +foreach (package ${QT5_PACKAGES_OPTIONAL}) + if ("${Qt5${package}_FOUND}") + message("Optional package ${package} found.") + list(APPEND INCLUDED_DIRECTORIES "${Qt5${package}_INCLUDE_DIRS}") + list(APPEND LIBRARIES ${Qt5${package}_LIBRARIES}) + string(TOUPPER "${package}" INCLUDE_NAME) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${INCLUDE_NAME}_ENABLED") + else () + message("Optional package ${package} not found.") + endif () +endforeach () + bc_git_version(${TARGET_NAME} ${PROJECT_VERSION}) #------------------------------------------------- @@ -439,6 +457,8 @@ set(PLUGIN_HEADERS include/LinphoneApp/PluginNetworkHelper.hpp include/LinphoneApp/LinphonePlugin.hpp) +set( UIS) + list(APPEND SOURCES include/LinphoneApp/PluginExample.json) set(MAIN_FILE src/app/main.cpp) @@ -494,6 +514,11 @@ if(ENABLE_APP_OAUTH2) list(APPEND SOURCES src/components/authentication/OAuth2Model.cpp) endif() +if(Qt5Pdf_FOUND) + list(APPEND HEADERS src/components/pdf/PdfWidget.hpp) + list(APPEND SOURCES src/components/pdf/PdfWidget.cpp) +endif() + set(QRC_RESOURCES resources.qrc) if(ENABLE_APP_WEBVIEW) @@ -524,6 +549,10 @@ PREPEND(HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/") PREPEND(PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/") PREPEND(PLUGIN_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/") +if(Qt5Pdf_FOUND) + qt5_wrap_ui(SOURCES src/components/pdf/PdfWidget.ui) +endif() + # ------------------------------------------------------------------------------ # Compute QML files list. # ------------------------------------------------------------------------------ @@ -653,7 +682,7 @@ endif() target_compile_definitions(${APP_PLUGIN} PUBLIC "-DENABLE_APP_EXPORT_PLUGIN") set_target_properties(${APP_PLUGIN} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) -set(INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" "${MEDIASTREAMER2_INCLUDE_DIRS}") +list(APPEND INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" "${MEDIASTREAMER2_INCLUDE_DIRS}") list(APPEND INCLUDED_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/include") set(LIBRARIES_LIST ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONE_LIBRARIES} ${LINPHONECXX_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${OPUS_LIBRARIES}) @@ -664,7 +693,6 @@ set(LIBRARIES_LIST ${BCTOOLBOX_CORE_LIBRARIES} ${BELCARD_LIBRARIES} ${LINPHONE_ #endif() if(WIN32) - set(LIBRARIES) foreach(LIBRARY ${LIBRARIES_LIST})# Search for lib full path find_library(FIND_LIBRARY_ITEM_${LIBRARY} NAMES ${LIBRARY} lib${LIBRARY} REQUIRED)#find_library need a specific variable name each time if(FIND_LIBRARY_ITEM_${LIBRARY}) @@ -674,7 +702,7 @@ if(WIN32) endif() endforeach() else() - set(LIBRARIES ${LIBRARIES_LIST}) + list(APPEND LIBRARIES ${LIBRARIES_LIST}) endif() if(ENABLE_BUILD_VERBOSE) @@ -692,18 +720,7 @@ foreach (package ${QT5_PACKAGES}) endif () endforeach () -foreach (package ${QT5_PACKAGES_OPTIONAL}) - if ("${Qt5${package}_FOUND}") - message("Optional package ${package} found.") - list(APPEND INCLUDED_DIRECTORIES "${Qt5${package}_INCLUDE_DIRS}") - list(APPEND LIBRARIES ${Qt5${package}_LIBRARIES}) - - string(TOUPPER "${package}" INCLUDE_NAME) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${INCLUDE_NAME}_ENABLED") - else () - message("Optional package ${package} not found.") - endif () -endforeach () + if(ENABLE_QT_KEYCHAIN) target_link_libraries(${APP_LIBRARY} ${QTKEYCHAIN_TARGET_NAME}) diff --git a/linphone-app/assets/images/rotation_custom.svg b/linphone-app/assets/images/rotation_custom.svg new file mode 100644 index 000000000..7f625d16d --- /dev/null +++ b/linphone-app/assets/images/rotation_custom.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + diff --git a/linphone-app/assets/images/zoom_in_custom.svg b/linphone-app/assets/images/zoom_in_custom.svg new file mode 100644 index 000000000..08c6cbe17 --- /dev/null +++ b/linphone-app/assets/images/zoom_in_custom.svg @@ -0,0 +1,47 @@ + + + + + + + diff --git a/linphone-app/assets/images/zoom_out_custom.svg b/linphone-app/assets/images/zoom_out_custom.svg new file mode 100644 index 000000000..fc41ed69f --- /dev/null +++ b/linphone-app/assets/images/zoom_out_custom.svg @@ -0,0 +1,47 @@ + + + + + + + diff --git a/linphone-app/assets/languages/da.ts b/linphone-app/assets/languages/da.ts index 7e04c9639..48a6a5131 100644 --- a/linphone-app/assets/languages/da.ts +++ b/linphone-app/assets/languages/da.ts @@ -2286,6 +2286,113 @@ Klik her: <a href="%1">%1</a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/de.ts b/linphone-app/assets/languages/de.ts index 9223919d9..ead09e45f 100644 --- a/linphone-app/assets/languages/de.ts +++ b/linphone-app/assets/languages/de.ts @@ -2286,6 +2286,113 @@ Klicken Sie hier: <a href="%1">%1</a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts index 8af08363b..e3ac80b71 100644 --- a/linphone-app/assets/languages/en.ts +++ b/linphone-app/assets/languages/en.ts @@ -2286,6 +2286,114 @@ Click here: <a href="%1">%1</a> Me + + PdfWidget + + PDF Viewer + Title for the PDF viewer + PDF Viewer + + + View + View + + + Zoom In + Zoom In + + + Ctrl+= + Ctr+= + + + Zoom Out + Zoom Out + + + Ctrl+- + Ctrl+- + + + Previous Page + Previous Page + + + PgUp + PgUp + + + Next Page + Next Page + + + PgDown + PgDown + + + Continuous + Continuous + + + Zoom... + Zoom… + + + Fit Width + Fit Width + + + Fit Page + Fit Page + + + 25% + 25% + + + 50% + 50% + + + 70% + 70% + + + 85% + 85% + + + 100% + 100% + + + 125% + 125% + + + 150% + 150% + + + 175% + 175% + + + 200% + 200% + + + 300% + 300% + + + 400% + 400% + + + Export as... + Export as… + + Presence diff --git a/linphone-app/assets/languages/es.ts b/linphone-app/assets/languages/es.ts index 621113025..c67ab4cac 100644 --- a/linphone-app/assets/languages/es.ts +++ b/linphone-app/assets/languages/es.ts @@ -2286,6 +2286,113 @@ Haga clic aquí: <a href="%1">%1 </a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts index 636760377..48d197e00 100644 --- a/linphone-app/assets/languages/fr_FR.ts +++ b/linphone-app/assets/languages/fr_FR.ts @@ -173,7 +173,7 @@ usernameStatusInvalidCharacters - Caractères invalides détectés (regex : `%1`). + Caractères invalides détectés (regex : `%1`). usernameStatusInvalid @@ -189,7 +189,7 @@ passwordStatusInvalidCharacters - Caractères invalides détectés (regex : `%1`). + Caractères invalides détectés (regex : `%1`). passwordStatusMissingCharacters @@ -1249,7 +1249,7 @@ URL du serveur non configurée. ephemeralNotInConference! 'Ephemeral message is only supported in conference based chat room!' - Les messages éphémères ne sont disponibles que pour une conversation définie en mode conférence ! + Les messages éphémères ne sont disponibles que pour une conversation définie en mode conférence ! Warning about not being in conference based chat room. @@ -2056,7 +2056,7 @@ Cliquez ici : <a href="%1">%1</a> newConferenceScheduleTitle 'Would you like to schedule your meeting?' : Ask about setting the meeting as scheduled. - Voulez-vous programmer cette réunion ? + Voulez-vous programmer cette réunion ? newConferenceDate @@ -2286,6 +2286,113 @@ Cliquez ici : <a href="%1">%1</a> Moi + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence @@ -2418,12 +2525,12 @@ Cliquez ici : <a href="%1">%1</a> vfsDeactivation 'Are you sure to deactivate the encryption? The application will exit and all your data will be lost. You must delete them before using the application.' : Explanation to deactivate the VFS encryption. - Êtes-vous certain de désactiver le chiffrement de l'application ? Elle redémarrera et toutes vos données seront perdues. Vous devez les supprimer avant d'utiliser l'application. + Êtes-vous certain de désactiver le chiffrement de l'application ? Elle redémarrera et toutes vos données seront perdues. Vous devez les supprimer avant d'utiliser l'application. vfsActivation 'Are you sure to activate the encryption? You cannot revert without deleting ALL your data' : Explanation to activate the VFS encryption. - Êtes-vous certain d'activer le chiffrement ? Cette action est irréversible sans perdre TOUTES vos données. + Êtes-vous certain d'activer le chiffrement ? Cette action est irréversible sans perdre TOUTES vos données. cancel @@ -2692,7 +2799,7 @@ Cliquez ici : <a href="%1">%1</a> serverTooltip - Serveur LDAP. ie : ldap:// pour un serveur local ou ldap://ldap.example.org/ + Serveur LDAP. ie : ldap:// pour un serveur local ou ldap://ldap.example.org/ bindDNLabel @@ -3638,7 +3745,7 @@ Cliquez ici : <a href="%1">%1</a> deleteTimeline 'Are you sure you want to delete and leave this timeline?' - Êtes-vous certain de vouloir tout effacer et de quitter cette conversation ? + Êtes-vous certain de vouloir tout effacer et de quitter cette conversation ? deleteTimelineTooltip @@ -3760,15 +3867,15 @@ Cliquez ici : <a href="%1">%1</a> VfsUtils Delete key failed: %1 - Échec lors de la suppression de la clef : %1 + Échec lors de la suppression de la clef : %1 Read key failed: %1 - Échec lors de la lecture de la clef : %1 + Échec lors de la lecture de la clef : %1 Write key failed: %1 - Échec lors de l'écriture de la clef : %1 + Échec lors de l'écriture de la clef : %1 diff --git a/linphone-app/assets/languages/hu.ts b/linphone-app/assets/languages/hu.ts index ac77084df..0f6bb8a14 100644 --- a/linphone-app/assets/languages/hu.ts +++ b/linphone-app/assets/languages/hu.ts @@ -2273,6 +2273,113 @@ Kattintson ide: <a href="%1">%1</a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/it.ts b/linphone-app/assets/languages/it.ts index 6f5ddef3b..e15f5e616 100644 --- a/linphone-app/assets/languages/it.ts +++ b/linphone-app/assets/languages/it.ts @@ -2286,6 +2286,113 @@ Clicca: <a href="%1">%1</a> Me + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/ja.ts b/linphone-app/assets/languages/ja.ts index b0bc072f3..9549aad97 100644 --- a/linphone-app/assets/languages/ja.ts +++ b/linphone-app/assets/languages/ja.ts @@ -579,7 +579,7 @@ icsDescription 'Description' : Title for the meeting description. - + 概要 icsJoinButton @@ -1801,7 +1801,7 @@ checkForUpdates 'Check for updates' : Item menu for checking updates - + アップデートを確認する recordings @@ -1826,7 +1826,7 @@ checkForUpdates 'Check for updates' : Item menu for checking updates - + アップデートを確認する recordings @@ -2273,6 +2273,113 @@ + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/lt.ts b/linphone-app/assets/languages/lt.ts index b13939615..d6c057619 100644 --- a/linphone-app/assets/languages/lt.ts +++ b/linphone-app/assets/languages/lt.ts @@ -2299,6 +2299,113 @@ Spustelėkite čia: <a href="%1">%1</a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/pt_BR.ts b/linphone-app/assets/languages/pt_BR.ts index cbcf9f645..bcf555efa 100644 --- a/linphone-app/assets/languages/pt_BR.ts +++ b/linphone-app/assets/languages/pt_BR.ts @@ -2286,6 +2286,113 @@ Clique aqui: <a href="%1">%1 </a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/ru.ts b/linphone-app/assets/languages/ru.ts index f6113c13d..70e3aba2f 100644 --- a/linphone-app/assets/languages/ru.ts +++ b/linphone-app/assets/languages/ru.ts @@ -2299,6 +2299,113 @@ Я + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/sv.ts b/linphone-app/assets/languages/sv.ts index c08cfaa65..52ddf97d6 100644 --- a/linphone-app/assets/languages/sv.ts +++ b/linphone-app/assets/languages/sv.ts @@ -2286,6 +2286,113 @@ Klicka här: <a href="%1">%1</a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/tr.ts b/linphone-app/assets/languages/tr.ts index a7c2d008c..390a86688 100644 --- a/linphone-app/assets/languages/tr.ts +++ b/linphone-app/assets/languages/tr.ts @@ -2273,6 +2273,113 @@ Buraya tıklayın: <a href="%1">%1</a> + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/uk.ts b/linphone-app/assets/languages/uk.ts index 3a93d6823..7e0fcc580 100644 --- a/linphone-app/assets/languages/uk.ts +++ b/linphone-app/assets/languages/uk.ts @@ -2299,6 +2299,113 @@ + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/assets/languages/zh_CN.ts b/linphone-app/assets/languages/zh_CN.ts index 838ba8d1a..a31af7584 100644 --- a/linphone-app/assets/languages/zh_CN.ts +++ b/linphone-app/assets/languages/zh_CN.ts @@ -2273,6 +2273,113 @@ + + PdfWidget + + PDF Viewer + + + + View + + + + Zoom In + + + + Ctrl+= + + + + Zoom Out + + + + Ctrl+- + + + + Previous Page + + + + PgUp + + + + Next Page + + + + PgDown + + + + Continuous + + + + Zoom... + + + + Fit Width + + + + Fit Page + + + + 25% + + + + 50% + + + + 70% + + + + 85% + + + + 100% + + + + 125% + + + + 150% + + + + 175% + + + + 200% + + + + 300% + + + + 400% + + + + Export as... + + + Presence diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc index 741e38b83..044f44a3f 100644 --- a/linphone-app/resources.qrc +++ b/linphone-app/resources.qrc @@ -136,6 +136,7 @@ assets/images/recording_sign.svg assets/images/record_custom.svg assets/images/recordings_custom.svg + assets/images/rotation_custom.svg assets/images/remove_participant_custom.svg assets/images/screen_sharing_custom.svg assets/images/screenshot_custom.svg @@ -169,6 +170,8 @@ assets/images/video_call_accept_custom.svg assets/images/video_call_custom.svg assets/images/warning.svg + assets/images/zoom_in_custom.svg + assets/images/zoom_out_custom.svg ui/modules/Common/Animations/BusyIndicator.qml ui/modules/Common/Constants/Constants.qml ui/modules/Common/Dialog/ConfirmDialog.qml diff --git a/linphone-app/src/app/App.cpp b/linphone-app/src/app/App.cpp index faaa81f08..b89685a5a 100644 --- a/linphone-app/src/app/App.cpp +++ b/linphone-app/src/app/App.cpp @@ -439,6 +439,7 @@ void App::initContentApp () { registerSharedTypes(); registerToolTypes(); registerSharedToolTypes(); + registerUninstalledModules(); // Enable notifications. mNotifier = new Notifier(mEngine); @@ -623,8 +624,8 @@ static inline void registerType (const char *name) { } template -static inline void registerToolType (const char *name) { - qmlRegisterSingletonType(name, 1, 0, name, [](QQmlEngine *engine, QJSEngine *) -> QObject *{ +static inline void registerToolType (const char *name, const int &major_version = 1 , const int &minor_version = 0) { + qmlRegisterSingletonType(name, major_version, minor_version, name, [](QQmlEngine *engine, QJSEngine *) -> QObject *{ return new T(engine); }); } @@ -774,6 +775,11 @@ void App::registerSharedToolTypes () { registerSharedToolType("ColorsList"); } +void App::registerUninstalledModules() { + if(!isPdfAvailable()) + qmlRegisterModule("QtQuick.Pdf",5,15); +} + // ----------------------------------------------------------------------------- void App::setTrayIcon () { @@ -1117,3 +1123,11 @@ void App::checkForUpdates(bool force) { Utils::appStringToCoreString(applicationVersion()) ); } + +bool App::isPdfAvailable(){ +#ifdef PDF_ENABLED + return true; +#else + return false; +#endif +} diff --git a/linphone-app/src/app/App.hpp b/linphone-app/src/app/App.hpp index db6368311..7e48b935f 100644 --- a/linphone-app/src/app/App.hpp +++ b/linphone-app/src/app/App.hpp @@ -118,6 +118,9 @@ public: Q_INVOKABLE static void smartShowWindow (QQuickWindow *window); Q_INVOKABLE static void checkForUpdates(bool force = false); + +// Check module availability when no dependencies are needed (else use SettingsModel) + Q_INVOKABLE static bool isPdfAvailable(); public slots: void stateChanged(Qt::ApplicationState); @@ -136,6 +139,7 @@ private: void registerSharedTypes (); void registerToolTypes (); void registerSharedToolTypes (); + void registerUninstalledModules (); void setTrayIcon (); void createNotifier (); diff --git a/linphone-app/src/app/providers/ImageProvider.cpp b/linphone-app/src/app/providers/ImageProvider.cpp index 0d72ba599..7e82e0403 100644 --- a/linphone-app/src/app/providers/ImageProvider.cpp +++ b/linphone-app/src/app/providers/ImageProvider.cpp @@ -244,7 +244,7 @@ ImageProvider::ImageProvider () : QQuickImageProvider( // ----------------------------------------------------------------------------- -QImage ImageProvider::requestImage (const QString &id, QSize *size, const QSize &requestedSize) { +QImage ImageProvider::computeImage (const QString &id, QSize *size, const QSize &requestedSize) { ImageModel * model = App::getInstance()->getImageListModel()->getImageModel(id); if(!model) return QImage(); @@ -313,6 +313,13 @@ QImage ImageProvider::requestImage (const QString &id, QSize *size, const QSize return image; } -QPixmap ImageProvider::requestPixmap (const QString &id, QSize *size, const QSize &requestedSize) { - return QPixmap::fromImage(requestImage(id, size, requestedSize)); +QPixmap ImageProvider::computePixmap (const QString &id, QSize *size, const QSize &requestedSize) { + return QPixmap::fromImage(computeImage(id, size, requestedSize)); +} + +QPixmap ImageProvider::requestPixmap (const QString &id, QSize *size, const QSize &requestedSize){ + return computePixmap(id, size, requestedSize); +} +QImage ImageProvider::requestImage (const QString &id, QSize *size, const QSize &requestedSize){ + return computeImage(id, size, requestedSize); } diff --git a/linphone-app/src/app/providers/ImageProvider.hpp b/linphone-app/src/app/providers/ImageProvider.hpp index 05d3af083..b0b245212 100644 --- a/linphone-app/src/app/providers/ImageProvider.hpp +++ b/linphone-app/src/app/providers/ImageProvider.hpp @@ -29,9 +29,10 @@ class ImageProvider : public QQuickImageProvider { public: ImageProvider (); - QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override; - QPixmap requestPixmap (const QString &id, QSize *size, const QSize &requestedSize) override; - + virtual QImage requestImage (const QString &id, QSize *size, const QSize &requestedSize) override; + virtual QPixmap requestPixmap (const QString &id, QSize *size, const QSize &requestedSize) override; + static QPixmap computePixmap (const QString &id, QSize *size, const QSize &requestedSize = QSize()); + static QImage computeImage (const QString &id, QSize *size, const QSize &requestedSize = QSize()); static const QString ProviderId; }; diff --git a/linphone-app/src/components/pdf/PdfWidget.cpp b/linphone-app/src/components/pdf/PdfWidget.cpp new file mode 100644 index 000000000..59d1ff1ba --- /dev/null +++ b/linphone-app/src/components/pdf/PdfWidget.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "PdfWidget.hpp" +#include "ui_PdfWidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "components/content/ContentModel.hpp" +#include "components/core/CoreManager.hpp" +#include "components/settings/SettingsModel.hpp" +#include "utils/Constants.hpp" +#include "utils/Utils.hpp" + +const qreal zoomMultiplier = qSqrt(2.0); + +PageSelector::PageSelector(QWidget *parent) + : QWidget(parent) + , mPageNavigation(nullptr){ + QHBoxLayout *layout = new QHBoxLayout(this); + + mPageNumberEdit = new QLineEdit(this); + mPageNumberEdit->setAlignment(Qt::AlignRight); + mPageNumberEdit->setStyleSheet("QLineEdit { border-radius: 5px; }"); + mPageCountLabel = new QLabel(this); + mPageCountLabel->setText("0"); + layout->addWidget(mPageNumberEdit); + layout->addWidget(mPageCountLabel); +} + +void PageSelector::setPageNavigation(QPdfPageNavigation *pageNavigation){ + mPageNavigation = pageNavigation; + + connect(mPageNavigation, &QPdfPageNavigation::currentPageChanged, this, &PageSelector::onCurrentPageChanged); + connect(mPageNavigation, &QPdfPageNavigation::pageCountChanged, this, [this](int pageCount){ + if(mPageNavigation->currentPage() == 0) + mPageNumberEdit->setText("1"); + mPageCountLabel->setText(QString::fromLatin1("/ %1").arg(pageCount)); + }); + connect(mPageNumberEdit, &QLineEdit::editingFinished, this, &PageSelector::pageNumberEdited); + + onCurrentPageChanged(mPageNavigation->currentPage()); +} + +void PageSelector::onCurrentPageChanged(int page) { + if (mPageNavigation->pageCount() == 0) + mPageNumberEdit->setText(QString::number(0)); + else + mPageNumberEdit->setText(QString::number(page + 1)); +} + +void PageSelector::pageNumberEdited() { + if (!mPageNavigation) + return; + + bool ok = false; + const int pageNumber = mPageNumberEdit->text().toInt(&ok); + + if (!ok) + onCurrentPageChanged(mPageNavigation->currentPage()); + else + mPageNavigation->setCurrentPage(qBound(0, pageNumber - 1, mPageNavigation->pageCount() - 1)); +} + +void PageSelector::setFamilyFont(const QString& family){ + Utils::setFamilyFont(this, family); + Utils::setFamilyFont(mPageNumberEdit, family); + Utils::setFamilyFont(mPageCountLabel, family); +} +//------------------------------------------------------------------------------------------------------------------ + + +PdfWidget::PdfWidget(ContentModel * contentModel, QWidget *parent) + : QMainWindow(parent) + , mContentModel(contentModel) + , mUi(new Ui::PdfWidget) + , mPageSelector(new PageSelector(this)) + , mDocument(new QPdfDocument(this)) { + QSize size; + mUi->setupUi(this); + +// Icons + mUi->downloadToolButton->setIcon(Utils::getMaskedPixmap("download_custom", "#CBCBCB")); + mUi->fullscreenToolButton->setIcon(Utils::getMaskedPixmap("fullscreen_custom", "#CBCBCB")); + mUi->rotationToolButton->setIcon(Utils::getMaskedPixmap("rotation_custom", "#CBCBCB")); + mUi->zoomInToolButton->setIcon(Utils::getMaskedPixmap("zoom_in_custom", "#CBCBCB")); + mUi->zoomOutToolButton->setIcon(Utils::getMaskedPixmap("zoom_out_custom", "#CBCBCB")); + + mUi->rotationToolButton->setVisible(false);// Rotation is not available. + +// Fonts + QString family; + if(CoreManager::getInstance() && CoreManager::getInstance()->getSettingsModel()) + family = CoreManager::getInstance()->getSettingsModel()->getTextMessageFont().family(); + else + family = Constants::DefaultFont; + Utils::setFamilyFont(mUi->menuBar, family); + Utils::setFamilyFont(mUi->menuView, family); + Utils::setFamilyFont(mUi->menuZoom, family); + Utils::setFamilyFont(mUi->actionZoom_In, family); + Utils::setFamilyFont(mUi->actionZoom_Out, family); + Utils::setFamilyFont(mUi->actionZoomFit_Width, family); + Utils::setFamilyFont(mUi->actionZoomFit_Page, family); + Utils::setFamilyFont(mUi->actionZoom25, family); + Utils::setFamilyFont(mUi->actionZoom50, family); + Utils::setFamilyFont(mUi->actionZoom70, family); + Utils::setFamilyFont(mUi->actionZoom85, family); + Utils::setFamilyFont(mUi->actionZoom100, family); + Utils::setFamilyFont(mUi->actionZoom125, family); + Utils::setFamilyFont(mUi->actionZoom150, family); + Utils::setFamilyFont(mUi->actionZoom175, family); + Utils::setFamilyFont(mUi->actionZoom200, family); + Utils::setFamilyFont(mUi->actionZoom300, family); + Utils::setFamilyFont(mUi->actionZoom400, family); + Utils::setFamilyFont(mUi->actionPrevious_Page, family); + Utils::setFamilyFont(mUi->actionNext_Page, family); + Utils::setFamilyFont(mUi->actionContinuous, family); + + mPageSelector->setFamilyFont(family); + + mPageSelector->setMaximumWidth(150); + mUi->statusBar->addPermanentWidget(mPageSelector); + mPageSelector->setPageNavigation(mUi->pdfView->pageNavigation()); + + //------- + // SEARCH + // QWidget * searchBox = new QWidget(this); + // QHBoxLayout * hbox = new QHBoxLayout(searchBox); + // QLineEdit *search = new QLineEdit(this); + // search->setPlaceholderText("Search..."); + // search->setFrame(false); + // connect(search, &QLineEdit::textChanged, [](const QString &text){ + // + // }); + // hbox->addWidget(search); + // QLabel * searchIcon = new QLabel(this); + // + // searchIcon->setScaledContents(true); + // searchIcon->setPixmap(QPixmap("://assets/images/search_custom.svg")); + // hbox->addWidget(searchIcon); + // hbox->setSpacing(0); + // hbox->setContentsMargins(0,0,0,0); + // searchBox->setStyleSheet("QWidget { background-color : white}"); + // searchBox->setContentsMargins(0,0,0,0); + // + // mUi->mainToolBar->addWidget(searchBox); + + // SEARCH + // searchBox->setMaximumHeight(fullscreen->height()); + // searchIcon->setMaximumHeight(search->height()); + // searchIcon->setMaximumWidth(searchIcon->height()); + + mUi->pdfView->setDocument(mDocument); + mUi->pdfView->setZoomMode(QPdfView::FitInView); +} + +PdfWidget::PdfWidget(QWidget *parent) : PdfWidget(nullptr, parent){ +} + +PdfWidget::~PdfWidget(){ + delete mUi; +} + +void PdfWidget::open(const QString &filePath) { + mDocument->load(filePath); + const auto documentTitle = mDocument->metaData(QPdfDocument::Title).toString(); + setWindowTitle(!documentTitle.isEmpty() ? documentTitle : tr("PDF Viewer")); +} + +// Tools + +void PdfWidget::on_fullscreenToolButton_toggled(bool checked){ + if(checked) + this->showFullScreen(); + else + this->showNormal(); +} + +void PdfWidget::on_downloadToolButton_clicked(){ + if(mContentModel){ + auto fileName = QFileDialog::getSaveFileName(this, tr("Export as...")); + if(!fileName.isEmpty()){ + mContentModel->saveAs(fileName); + } + } +} + +// Page + +void PdfWidget::on_actionPrevious_Page_triggered(){ + mUi->pdfView->pageNavigation()->goToPreviousPage(); +} + +void PdfWidget::on_actionNext_Page_triggered(){ + mUi->pdfView->pageNavigation()->goToNextPage(); +} + +void PdfWidget::on_actionContinuous_triggered(){ + mUi->pdfView->setPageMode(mUi->actionContinuous->isChecked() ? QPdfView::MultiPage : QPdfView::SinglePage); +} + +// Zoom + +void PdfWidget::on_actionZoom_In_triggered(){ + mUi->pdfView->setZoomMode(QPdfView::CustomZoom); + mUi->pdfView->setZoomFactor(mUi->pdfView->zoomFactor() * zoomMultiplier); +} + +void PdfWidget::on_actionZoom_Out_triggered(){ + mUi->pdfView->setZoomMode(QPdfView::CustomZoom); + mUi->pdfView->setZoomFactor(mUi->pdfView->zoomFactor() / zoomMultiplier); +} + +void PdfWidget::setZoom(const double& percent){ + mUi->actionZoomFit_Width->setChecked(false); + mUi->actionZoomFit_Page->setChecked(false); + mUi->pdfView->setZoomMode(QPdfView::CustomZoom); + mUi->pdfView->setZoomFactor(percent/100.0); +} + +void PdfWidget::on_actionZoomFit_Width_triggered(){ + mUi->actionZoomFit_Page->setChecked(false); + mUi->pdfView->setZoomMode(QPdfView::FitToWidth); +} + +void PdfWidget::on_actionZoomFit_Page_triggered(){ + mUi->actionZoomFit_Width->setChecked(false); + mUi->pdfView->setZoomMode(QPdfView::FitInView); +} + +void PdfWidget::on_actionZoom25_triggered(){ + setZoom(25); +} + +void PdfWidget::on_actionZoom50_triggered(){ + setZoom(50); +} + +void PdfWidget::on_actionZoom70_triggered(){ + setZoom(70); +} + +void PdfWidget::on_actionZoom85_triggered(){ + setZoom(85); +} + +void PdfWidget::on_actionZoom100_triggered(){ + setZoom(100); +} + +void PdfWidget::on_actionZoom125_triggered(){ + setZoom(125); +} + +void PdfWidget::on_actionZoom150_triggered(){ + setZoom(150); +} + +void PdfWidget::on_actionZoom175_triggered(){ + setZoom(175); +} + +void PdfWidget::on_actionZoom200_triggered(){ + setZoom(200); +} + +void PdfWidget::on_actionZoom300_triggered(){ + setZoom(300); +} + +void PdfWidget::on_actionZoom400_triggered(){ + setZoom(400); +} diff --git a/linphone-app/src/components/pdf/PdfWidget.hpp b/linphone-app/src/components/pdf/PdfWidget.hpp new file mode 100644 index 000000000..ce0c38546 --- /dev/null +++ b/linphone-app/src/components/pdf/PdfWidget.hpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * 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 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +// Open a Widnow to display a PDF. + +#ifndef PDF_WIDGET_H_ +#define PDF_WIDGET_H_ + +#include +#include + +namespace Ui { + class PdfWidget; +} + +class ContentModel; +class PageSelector; +class QLabel; +class QLineEdit; +class QPdfDocument; +class QPdfPageNavigation; + +class PdfWidget : public QMainWindow{ + Q_OBJECT + +public: + explicit PdfWidget(QWidget *parent = nullptr); + explicit PdfWidget(ContentModel * contentModel, QWidget *parent = nullptr); + ~PdfWidget(); + +public slots: + void open(const QString &filePath); + void setZoom(const double& percent); + +private slots: + + // Tools + void on_downloadToolButton_clicked(); + void on_fullscreenToolButton_toggled(bool checked); + + // Page + void on_actionPrevious_Page_triggered(); + void on_actionNext_Page_triggered(); + void on_actionContinuous_triggered(); + + // Zoom + void on_actionZoom_In_triggered(); + void on_actionZoom_Out_triggered(); + void on_actionZoomFit_Width_triggered(); + void on_actionZoomFit_Page_triggered(); + void on_actionZoom25_triggered(); + void on_actionZoom50_triggered(); + void on_actionZoom70_triggered(); + void on_actionZoom85_triggered(); + void on_actionZoom100_triggered(); + void on_actionZoom125_triggered(); + void on_actionZoom150_triggered(); + void on_actionZoom175_triggered(); + void on_actionZoom200_triggered(); + void on_actionZoom300_triggered(); + void on_actionZoom400_triggered(); + +private: + Ui::PdfWidget *mUi; + PageSelector *mPageSelector; + + QPdfDocument *mDocument; + ContentModel * mContentModel; +}; + +class PageSelector : public QWidget { + Q_OBJECT +public: + explicit PageSelector(QWidget *parent = nullptr); + + void setPageNavigation(QPdfPageNavigation *pageNavigation); + void setFamilyFont(const QString& family); + +private slots: + void onCurrentPageChanged(int page); + void pageNumberEdited(); + +private: + QLabel *mPageCountLabel; + QPdfPageNavigation *mPageNavigation; + QLineEdit *mPageNumberEdit; +}; + +#endif diff --git a/linphone-app/src/components/pdf/PdfWidget.ui b/linphone-app/src/components/pdf/PdfWidget.ui new file mode 100644 index 000000000..a02bad268 --- /dev/null +++ b/linphone-app/src/components/pdf/PdfWidget.ui @@ -0,0 +1,540 @@ + + + PdfWidget + + + + 0 + 0 + 700 + 600 + + + + PDF Viewer + + + true + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 0 + + + + + + 33 + 27 + + + + + 33 + 27 + + + + + 0 + 0 + + + + PointingHandCursor + + + background-color:white; +border-radius:5px; +border-width:1px + + + + + + + .. + + + + 27 + 27 + + + + + + + + Qt::Horizontal + + + + 304 + 20 + + + + + + + + true + + + QLabel{background-color:white} + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 33 + 27 + + + + + 33 + 27 + + + + PointingHandCursor + + + background-color:white; +border-radius:5px; +border-width:1px + + + + + + + .. + + + + 27 + 27 + + + + true + + + + + + + + + + + + 0 + + + + + + 0 + + + + + Qt::Vertical + + + + 20 + 376 + + + + + + + + + 33 + 33 + + + + + 33 + 33 + + + + PointingHandCursor + + + false + + + background-color:white; +border-radius:5px; +border-width:1px + + + + + + + .. + + + + 33 + 33 + + + + + + + + + 33 + 33 + + + + + 33 + 33 + + + + PointingHandCursor + + + background-color:white; +border-radius:5px; +border-width:1px + + + + + + + .. + + + + 33 + 33 + + + + + + + + + 33 + 33 + + + + + 33 + 33 + + + + PointingHandCursor + + + background-color:white; +border-radius:5px; +border-width:1px + + + + + + + .. + + + + 33 + 33 + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + 0 + 0 + 700 + 21 + + + + + View + + + + Zoom... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :/icons/images/zoom-in-24.png:/icons/images/zoom-in-24.png + + + Zoom In + + + Ctrl+= + + + + + + :/icons/images/zoom-out-24.png:/icons/images/zoom-out-24.png + + + Zoom Out + + + Ctrl+- + + + + + Previous Page + + + PgUp + + + + + Next Page + + + PgDown + + + + + true + + + Continuous + + + + + true + + + Fit Width + + + + + true + + + Fit Page + + + + + 25% + + + + + 50% + + + + + 70% + + + + + 85% + + + + + 100% + + + + + 125% + + + + + 150% + + + + + 175% + + + + + 200% + + + + + 300% + + + + + 400% + + + + + + + QPdfView + QWidget +
qpdfview.h
+ 1 +
+
+ + + + zoomInToolButton + clicked() + actionZoom_In + trigger() + + + 27 + 519 + + + -1 + -1 + + + + + zoomOutToolButton + clicked() + actionZoom_Out + trigger() + + + 27 + 552 + + + -1 + -1 + + + + +
diff --git a/linphone-app/src/utils/Utils.cpp b/linphone-app/src/utils/Utils.cpp index 82cbedfa0..a2d963991 100644 --- a/linphone-app/src/utils/Utils.cpp +++ b/linphone-app/src/utils/Utils.cpp @@ -18,6 +18,8 @@ * along with this program. If not, see . */ +#include +#include #include #include #include @@ -30,17 +32,25 @@ #include #include +#ifdef PDF_ENABLED +#include +#include +#include "components/pdf/PdfWidget.hpp" +#endif + #include "config.h" #include "Utils.hpp" #include "UriTools.hpp" #include "app/App.hpp" +#include "app/paths/Paths.hpp" +#include "app/providers/ImageProvider.hpp" #include "components/core/CoreManager.hpp" #include "components/contacts/ContactsListModel.hpp" #include "components/contact/ContactModel.hpp" #include "components/contact/VcardModel.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" -#include "app/paths/Paths.hpp" + #ifdef _WIN32 #include @@ -616,6 +626,10 @@ bool Utils::isVideo(const QString& path){ return QMimeDatabase().mimeTypeForFile(path).name().contains("video"); } +bool Utils::isPdf(const QString& path){ + return QMimeDatabase().mimeTypeForFile(path).name().contains("application/pdf"); +} + bool Utils::isSupportedForDisplay(const QString& path){ return !QMimeDatabase().mimeTypeForFile(path).name().contains("application");// "for pdf : "application/pdf". Note : Make an exception when supported. } @@ -769,4 +783,39 @@ void Utils::deleteAllUserDataOffline(){ QDir dir(gDbPaths[i]); qWarning() << "Deleting " << gDbPaths[i] << " : " << (dir.removeRecursively() ? "Successfully" : "Failed"); } +} + +//------------------------------------------------------------------------------------------------------- +// WIDGETS +//------------------------------------------------------------------------------------------------------- + +bool Utils::openWithPdfViewer(ContentModel * contentModel, const QString& filePath, const int& width, const int& height) { +#ifdef PDF_ENABLED + PdfWidget *view = new PdfWidget(contentModel); + view->setMinimumSize(QSize(width, height)); + view->show(); + view->open(filePath); + return true; +#else + return false; +#endif +} + +void Utils::setFamilyFont(QAction * dest, const QString& family){ + QFont font(dest->font()); + font.setFamily(family); + dest->setFont(font); +} +void Utils::setFamilyFont(QWidget * dest, const QString& family){ + QFont font(dest->font()); + font.setFamily(family); + dest->setFont(font); +} +QPixmap Utils::getMaskedPixmap(const QString& name, const QColor& color){ + QSize size; + QPixmap img = ImageProvider::computePixmap(name, &size); + QPixmap pxr( img.size() ); + pxr.fill( color ); + pxr.setMask( img.createMaskFromColor( Qt::transparent ) ); + return pxr; } \ No newline at end of file diff --git a/linphone-app/src/utils/Utils.hpp b/linphone-app/src/utils/Utils.hpp index 908330c50..4c82dfc67 100644 --- a/linphone-app/src/utils/Utils.hpp +++ b/linphone-app/src/utils/Utils.hpp @@ -32,6 +32,9 @@ #include "LinphoneEnums.hpp" #include "Constants.hpp" +class QAction; +class QWidget; + // ============================================================================= /* @@ -46,6 +49,7 @@ #endif // if defined(__GNUC__) && __GNUC__ >= 7 #endif // ifndef UTILS_NO_BREAK +class ContentModel; class Utils : public QObject{ Q_OBJECT @@ -65,6 +69,7 @@ public: Q_INVOKABLE static bool isAnimatedImage(const QString& path); Q_INVOKABLE static bool isImage(const QString& path); Q_INVOKABLE static bool isVideo(const QString& path); + Q_INVOKABLE static bool isPdf(const QString& path); Q_INVOKABLE static bool isSupportedForDisplay(const QString& path); Q_INVOKABLE static bool isPhoneNumber(const QString& txt); Q_INVOKABLE QSize getImageSize(const QString& url); @@ -76,6 +81,8 @@ public: Q_INVOKABLE static QString encodeTextToQmlRichFormat(const QString& text, const QVariantMap& options = QVariantMap()); Q_INVOKABLE static QString getFileContent(const QString& filePath); + Q_INVOKABLE static bool openWithPdfViewer(ContentModel *contentModel, const QString& filePath, const int& width, const int& height); // return true if PDF is enabled + //---------------------------------------------------------------------------------- static inline QString coreStringToAppString (const std::string &str) { @@ -159,6 +166,9 @@ public: static void deleteAllUserData(); static void deleteAllUserDataOffline();// When we are out of all events and core is not running (aka in main()) + static void setFamilyFont(QAction * dest, const QString& family); + static void setFamilyFont(QWidget * dest, const QString& family); + static QPixmap getMaskedPixmap(const QString& name, const QColor& color); }; #endif // UTILS_H_ diff --git a/linphone-app/ui/modules/Common/Dialog/FileViewDialog.qml b/linphone-app/ui/modules/Common/Dialog/FileViewDialog.qml index f671f86d9..3b08624bc 100644 --- a/linphone-app/ui/modules/Common/Dialog/FileViewDialog.qml +++ b/linphone-app/ui/modules/Common/Dialog/FileViewDialog.qml @@ -25,6 +25,7 @@ DialogPlus{ property bool isAnimatedImage : filePath && UtilsCpp.isAnimatedImage(filePath) property bool isVideo: filePath && UtilsCpp.isVideo(filePath) property bool isImage: filePath && UtilsCpp.isImage(filePath) + property bool isPdf: filePath && UtilsCpp.isPdf(filePath) property bool isSupportedForDisplay: filePath && tempFile.isReadable && UtilsCpp.isSupportedForDisplay(filePath) showCloseCross: true @@ -61,6 +62,12 @@ DialogPlus{ tempFile.createFileFromContentModel(contentModel, false); } onExitStatus: if(loader.sourceComponent == videoComponent) loader.item.stop(); + Component.onCompleted:{ + if(mainItem.isPdf){ + if(UtilsCpp.openWithPdfViewer(contentModel, mainItem.filePath, 800,800)) + Qt.callLater(mainItem.exit) + } + } TemporaryFile { id: tempFile diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml index 561434079..2db19344d 100644 --- a/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml +++ b/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml @@ -40,7 +40,7 @@ TextEdit { readOnly: true selectByMouse: true font.family: customFont.family - font.pointSize: Units.dp * customFont.pointSize * (UtilsCpp.isOnlyEmojis(contentModel.text) ? 4 : 1 ) + font.pointSize: Units.dp * customFont.pointSize * (contentModel && UtilsCpp.isOnlyEmojis(contentModel.text) ? 4 : 1 ) text: visible ? UtilsCpp.encodeTextToQmlRichFormat(contentModel.text, { imagesHeight: ChatStyle.entry.message.images.height,