Compare commits
62 Commits
beta/20231
...
beta/20231
| Author | SHA1 | Date | |
|---|---|---|---|
| cb68ee560c | |||
| 517f87826d | |||
| 0725683727 | |||
| 52f95ac8ed | |||
| 8d41ab6eb9 | |||
| b4b1cda9e6 | |||
| e46a123609 | |||
| 8e33a6125f | |||
| 3e17a9b247 | |||
| 38e5d0967a | |||
| 5ed836f34e | |||
| 7b55954245 | |||
| 8c75ac8a1f | |||
| 92546c7358 | |||
| 855b023349 | |||
| a0f0dd132a | |||
| 428756e568 | |||
| 04a8dfa468 | |||
| cbef11a9ca | |||
| 122628239c | |||
| 8922387217 | |||
| be85034d78 | |||
| 885f05ba12 | |||
| 60cfc8938f | |||
| 31c5cead63 | |||
| 1c576a7a3a | |||
| 92be4fa7dc | |||
| 6360e52eb5 | |||
| d38858c1f3 | |||
| 088c367485 | |||
| fc7109950b | |||
| 5776ab7c7d | |||
| d4d34ad4fc | |||
| 86d55fa985 | |||
| 303acbda64 | |||
| a433974340 | |||
| 7a759dab7a | |||
| d2e87150b4 | |||
| ec60458dbe | |||
| 8a9aea2f28 | |||
| ae86464658 | |||
| 5f0163df05 | |||
| 493addcbd8 | |||
| f144b27db8 | |||
| 861c42e3d5 | |||
| 873c4c72b9 | |||
| 3e012c32d5 | |||
| 6bff3c54f1 | |||
| e55eaa5d8e | |||
| 1a17735d55 | |||
| 4e5f153230 | |||
| 15351a5aae | |||
| e89aa95673 | |||
| 3609dae584 | |||
| 8b21b0fda9 | |||
| 811a93cc27 | |||
| baeb90bced | |||
| 439fea530d | |||
| 55415d6062 | |||
| 9d3b5cd0c5 | |||
| 4e549d123e | |||
| 77193b26d9 |
2
.gitmodules
vendored
@ -1,6 +1,6 @@
|
||||
[submodule "3rdparty/qrencode-win32"]
|
||||
path = 3rdparty/qrencode-win32
|
||||
url = https://github.com/BlueDragon747/qrencode-win32.git
|
||||
url = https://github.com/blizzard4591/qrencode-win32.git
|
||||
ignore = dirty
|
||||
[submodule "3rdparty/libqrencode"]
|
||||
url = https://github.com/fukuchi/libqrencode.git
|
||||
|
||||
102
CMakeLists.txt
@ -29,12 +29,40 @@ else()
|
||||
project(jami)
|
||||
endif()
|
||||
|
||||
option(WITH_DAEMON_SUBMODULE "Build with daemon submodule" OFF)
|
||||
option(WITH_DAEMON_SUBMODULE "Build with daemon submodule" ON)
|
||||
option(JAMICORE_AS_SUBDIR "Build Jami-core as a subdir dependency" OFF)
|
||||
option(ENABLE_TESTS "Build with tests" OFF)
|
||||
option(WITH_WEBENGINE "Build with WebEngine" ON)
|
||||
if(WITH_WEBENGINE)
|
||||
add_definitions(-DWITH_WEBENGINE)
|
||||
endif()
|
||||
option(ENABLE_LIBWRAP "Enable libwrap (single process mode)" ON)
|
||||
if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
OR ENABLE_LIBWRAP
|
||||
# because mocks use the same interface present in qtwrapper/
|
||||
OR ENABLE_TEST)
|
||||
set(ENABLE_LIBWRAP true)
|
||||
endif()
|
||||
option(ENABLE_ASAN "Enable address sanitization" OFF)
|
||||
if(ENABLE_ASAN AND NOT MSVC)
|
||||
message(STATUS "Address sanitization enabled for client")
|
||||
# Add AddressSanitizer flags for both compiler and linker
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
endif()
|
||||
|
||||
# jami-core
|
||||
if(NOT WITH_DAEMON_SUBMODULE)
|
||||
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/../daemon)
|
||||
else()
|
||||
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/daemon)
|
||||
endif()
|
||||
|
||||
# For now only MSVC is supported for building Jami-core within the
|
||||
# client cmake.
|
||||
if(JAMICORE_AS_SUBDIR)
|
||||
add_subdirectory(${DAEMON_DIR})
|
||||
endif()
|
||||
|
||||
# init some variables for includes, libs, etc.
|
||||
set(CLIENT_INCLUDE_DIRS, "")
|
||||
@ -43,21 +71,16 @@ set(CLIENT_LIBS, "")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb")
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb")
|
||||
endif()
|
||||
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
# Main project directories:
|
||||
|
||||
# jami-daemon
|
||||
if(NOT WITH_DAEMON_SUBMODULE)
|
||||
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/../daemon)
|
||||
else()
|
||||
set(DAEMON_DIR ${PROJECT_SOURCE_DIR}/daemon)
|
||||
endif()
|
||||
# src
|
||||
set(LIBCLIENT_SRC_DIR ${PROJECT_SOURCE_DIR}/src/libclient)
|
||||
set(APP_SRC_DIR ${PROJECT_SOURCE_DIR}/src/app)
|
||||
@ -89,16 +112,6 @@ else()
|
||||
message(FATAL_ERROR "Qt 6.4 or higher is required. Found ${QT_VERSION}")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(DEFAULT_BUILD_TYPE "Debug")
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
|
||||
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE
|
||||
STRING "Choose the type of build." FORCE)
|
||||
endif()
|
||||
set(OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/x64/${CMAKE_BUILD_TYPE}")
|
||||
endif()
|
||||
|
||||
# libjamiclient
|
||||
add_subdirectory(${LIBCLIENT_SRC_DIR})
|
||||
|
||||
@ -244,6 +257,8 @@ set(COMMON_SOURCES
|
||||
${APP_SRC_DIR}/messageparser.cpp
|
||||
${APP_SRC_DIR}/previewengine.cpp
|
||||
${APP_SRC_DIR}/imagedownloader.cpp
|
||||
${APP_SRC_DIR}/pluginversionmanager.cpp
|
||||
${APP_SRC_DIR}/connectioninfolistmodel.cpp
|
||||
${APP_SRC_DIR}/pluginversionmanager.cpp)
|
||||
|
||||
set(COMMON_HEADERS
|
||||
@ -310,8 +325,9 @@ set(COMMON_HEADERS
|
||||
${APP_SRC_DIR}/messageparser.h
|
||||
${APP_SRC_DIR}/htmlparser.h
|
||||
${APP_SRC_DIR}/imagedownloader.h
|
||||
${APP_SRC_DIR}/pluginversionmanager.h)
|
||||
|
||||
${APP_SRC_DIR}/pluginversionmanager.h
|
||||
${APP_SRC_DIR}/connectioninfolistmodel.h
|
||||
${APP_SRC_DIR}/pttlistener.h)
|
||||
|
||||
# For libavutil/avframe.
|
||||
set(LIBJAMI_CONTRIB_DIR "${DAEMON_DIR}/contrib")
|
||||
@ -347,10 +363,6 @@ if(MSVC)
|
||||
# preprocessor defines
|
||||
add_definitions(-DUNICODE -DQT_NO_DEBUG -DNDEBUG)
|
||||
|
||||
# dependencies
|
||||
set(QRENCODE_DIR
|
||||
${PROJECT_SOURCE_DIR}/3rdparty/qrencode-win32/qrencode-win32)
|
||||
|
||||
# compiler options
|
||||
add_compile_options(
|
||||
/wd4068 /wd4099 /wd4189 /wd4267 /wd4577 /wd4467 /wd4715 /wd4828)
|
||||
@ -368,12 +380,13 @@ if(MSVC)
|
||||
"/NODEFAULTLIB:LIBCMT")
|
||||
|
||||
# client deps
|
||||
set(QRENCODE_LIB
|
||||
${QRENCODE_DIR}/vc8/qrcodelib/x64/Release-Lib/qrcodelib.lib)
|
||||
set(QRENCODE_DIR ${PROJECT_SOURCE_DIR}/3rdparty/qrencode-win32/qrencode-win32)
|
||||
file(GLOB_RECURSE QRENCODE_LIB ${QRENCODE_DIR}/qrcodelib.lib)
|
||||
file(GLOB_RECURSE QRENCODE_INCLUDE ${QRENCODE_DIR}/qrencode.h)
|
||||
get_filename_component(QRENCODE_INCLUDE_DIR ${QRENCODE_INCLUDE} DIRECTORY)
|
||||
|
||||
# daemon
|
||||
set(JAMID_SRC_PATH ${DAEMON_DIR}/contrib/msvc/include)
|
||||
set(JAMID_LIB ${DAEMON_DIR}/build/x64/ReleaseLib_win32/bin/libjami.lib)
|
||||
set(GNUTLS_LIB ${DAEMON_DIR}/contrib/msvc/lib/x64/libgnutls.lib)
|
||||
|
||||
# Beta config
|
||||
@ -389,7 +402,7 @@ if(MSVC)
|
||||
include_directories(
|
||||
${JAMID_SRC_PATH}
|
||||
${LIBCLIENT_SRC_DIR}
|
||||
${QRENCODE_DIR})
|
||||
${QRENCODE_INCLUDE_DIR})
|
||||
elseif (NOT APPLE)
|
||||
list(APPEND COMMON_SOURCES
|
||||
${APP_SRC_DIR}/xrectsel.c
|
||||
@ -493,6 +506,29 @@ else()
|
||||
OPTIONAL_COMPONENTS LinguistTools)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
if (DEFINED ENV{XDG_SESSION_TYPE})
|
||||
if ($ENV{XDG_SESSION_TYPE} STREQUAL "x11")
|
||||
set(PTT_PLATFORM "x11")
|
||||
list(APPEND COMMON_HEADER ${APP_SRC_DIR}/platform/X11/xcbkeyboard.H)
|
||||
# TODO: add Wayland support
|
||||
endif ()
|
||||
endif ()
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(PTT_PLATFORM "windows")
|
||||
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(PTT_PLATFORM "macos")
|
||||
endif ()
|
||||
|
||||
if (NOT ${PTT_PLATFORM} STREQUAL "")
|
||||
message(STATUS "Platform: ${PTT_PLATFORM}")
|
||||
add_definitions(-DHAVE_GLOBAL_PTT)
|
||||
list(APPEND COMMON_SOURCES ${APP_SRC_DIR}/platform/${PTT_PLATFORM}/pttlistener.cpp)
|
||||
else ()
|
||||
message(WARNING "Global push-to-talk not supported.")
|
||||
list(APPEND COMMON_SOURCES ${APP_SRC_DIR}/platform/local/pttlistener.cpp)
|
||||
endif ()
|
||||
|
||||
# common includes
|
||||
include_directories(
|
||||
${PROJECT_SOURCE_DIR}
|
||||
@ -546,7 +582,7 @@ if(MSVC)
|
||||
WIN32_EXECUTABLE TRUE)
|
||||
|
||||
list(APPEND CLIENT_LIBS
|
||||
${JAMID_LIB}
|
||||
${LIBJAMI_LIB}
|
||||
${GNUTLS_LIB}
|
||||
${LIBCLIENT_NAME}
|
||||
${QT_LIBS}
|
||||
@ -593,7 +629,6 @@ elseif (NOT APPLE)
|
||||
${GLIB_LIBRARIES}
|
||||
${GIO_LIBRARIES})
|
||||
|
||||
# Installation rules
|
||||
install(
|
||||
TARGETS ${PROJECT_NAME}
|
||||
RUNTIME DESTINATION bin)
|
||||
@ -724,7 +759,7 @@ else()
|
||||
list(APPEND CLIENT_LIBS
|
||||
"-framework AVFoundation"
|
||||
"-framework CoreAudio -framework CoreMedia -framework CoreVideo"
|
||||
"-framework VideoToolbox -framework AudioUnit"
|
||||
"-framework VideoToolbox -framework AudioUnit -framework Carbon"
|
||||
"-framework Security"
|
||||
compression
|
||||
resolv
|
||||
@ -763,6 +798,7 @@ else()
|
||||
MACOSX_BUNDLE_COPYRIGHT "${PROJ_COPYRIGHT}")
|
||||
if(APPSTORE)
|
||||
message(STATUS "app store version")
|
||||
add_definitions(-DAPPSTORE)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/appstore/Jami.entitlements")
|
||||
else()
|
||||
|
||||
110
build.py
@ -28,6 +28,7 @@ import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import re
|
||||
|
||||
OSX_DISTRIBUTION_NAME = "osx"
|
||||
WIN32_DISTRIBUTION_NAME = "win32"
|
||||
@ -363,10 +364,10 @@ def cwd(path):
|
||||
def run_install(args):
|
||||
# Platforms with special compilation scripts
|
||||
if args.distribution == WIN32_DISTRIBUTION_NAME:
|
||||
with cwd('daemon/compat/msvc'):
|
||||
execute_script(
|
||||
['python winmake.py -iv '
|
||||
f'-s {args.sdk} -b daemon'])
|
||||
if not args.pywinmake:
|
||||
with cwd('daemon/compat/msvc'):
|
||||
execute_script([f'python winmake.py -iv -s {args.sdk} -b daemon'])
|
||||
|
||||
build_windows = 'extras/scripts/build-windows.py'
|
||||
execute_script([f'python {build_windows} --init'])
|
||||
execute_script([f'python {build_windows} --qt={args.qt}'])
|
||||
@ -386,6 +387,8 @@ def run_install(args):
|
||||
install_args.append('-u')
|
||||
if args.debug:
|
||||
install_args.append('-d')
|
||||
if args.asan:
|
||||
install_args.append('-A')
|
||||
if args.no_libwrap:
|
||||
install_args.append('-W')
|
||||
if args.no_webengine:
|
||||
@ -458,6 +461,93 @@ def run_clean():
|
||||
'git submodule foreach git clean -xfd'])
|
||||
|
||||
|
||||
def clean_contribs(contribs):
|
||||
"""
|
||||
Helper to clean one or more of the libjami contribs.
|
||||
|
||||
Takes a list of contrib names(space separated) to clean, or 'all' to clean all contribs.
|
||||
|
||||
Contribs are assumed to be in the contrib_dir: daemon/contrib
|
||||
Artifacts to remove include:
|
||||
- build directory: <contrib_dir>/<native_dir>/<contrib_name>
|
||||
- build stamp: <contrib_dir>/<native_dir>/.<contrib_name>
|
||||
- tarball: <contrib_dir>/tarballs/<contrib_name>*.tar.*
|
||||
- build artifacts (we don't care about the contents of share):
|
||||
- <contrib_dir>/<abi_triplet>/bin/<contrib_name>
|
||||
- <contrib_dir>/<abi_triplet>/lib/<contrib_name>*
|
||||
- <contrib_dir>/<abi_triplet>/include/<contrib_name>*
|
||||
"""
|
||||
|
||||
# Not supported on Windows
|
||||
if platform.system() == 'Windows':
|
||||
print('Cleaning contribs is not supported on Windows. Exiting.')
|
||||
sys.exit(1)
|
||||
|
||||
# Assume we are using the submodule here.
|
||||
contrib_dir = 'daemon/contrib'
|
||||
sub_dirs = os.listdir(contrib_dir)
|
||||
|
||||
# Let's find the abi triplet:
|
||||
# The abi_triplet is 3 parts: <arch>-<vendor>-<sys> and should be the only directory
|
||||
# named like that in the contrib directory. We can use a regex to find it.
|
||||
triplet_pattern = re.compile(r'^[a-zA-Z0-9_]+-[a-zA-Z0-9_]+-[a-zA-Z0-9_]+$')
|
||||
def is_triplet(s):
|
||||
return bool(triplet_pattern.match(s))
|
||||
abi_triplet = ''
|
||||
for sub_dir in sub_dirs:
|
||||
if is_triplet(sub_dir):
|
||||
abi_triplet = sub_dir
|
||||
break
|
||||
|
||||
# If we didn't find the abi triplet, we need to stop.
|
||||
if abi_triplet == '':
|
||||
print('Could not find the abi triplet for the contribs. Exiting.')
|
||||
sys.exit(1)
|
||||
|
||||
# Let's find the native build source directory (native-*)
|
||||
native_dir = ''
|
||||
for sub_dir in sub_dirs:
|
||||
if sub_dir.startswith('native'):
|
||||
native_dir = os.path.join(contrib_dir, sub_dir)
|
||||
break
|
||||
|
||||
# If we didn't find the native build source directory, we need to stop.
|
||||
if native_dir == '':
|
||||
print('Could not find the native build source directory. Exiting.')
|
||||
sys.exit(1)
|
||||
|
||||
# If contribs is 'all', construct the list of all contribs from the contrib native directory
|
||||
# list of directories only
|
||||
if contribs == ['all']:
|
||||
contribs = [d for d in os.listdir(native_dir) if os.path.isdir(os.path.join(native_dir, d))]
|
||||
|
||||
# Clean each contrib
|
||||
for contrib in contribs:
|
||||
print(f'Cleaning contrib: {contrib} for {abi_triplet} in {native_dir}')
|
||||
build_dir = os.path.join(native_dir, contrib, '*')
|
||||
build_stamp = os.path.join(native_dir, f'.{contrib}*')
|
||||
tarball = os.path.join(contrib_dir, 'tarballs', f'{contrib}*.tar.*')
|
||||
bins = os.path.join(contrib_dir, abi_triplet, 'bin', contrib)
|
||||
libs = os.path.join(contrib_dir, abi_triplet, 'lib', f'lib{contrib}*')
|
||||
includes = os.path.join(contrib_dir, abi_triplet, 'include', f'{contrib}*')
|
||||
|
||||
# EXCEPTIONS: pjproject and ffmpeg
|
||||
if contrib == 'pjproject':
|
||||
libs = f' {os.path.join(contrib_dir, abi_triplet, "lib", "libpj*")}' \
|
||||
f' {os.path.join(contrib_dir, abi_triplet, "lib", "libsrtp*")}'
|
||||
includes = os.path.join(contrib_dir, abi_triplet, 'include', 'pj*')
|
||||
elif contrib == 'ffmpeg':
|
||||
libs = f' {os.path.join(contrib_dir, abi_triplet, "lib", "libav*")}' \
|
||||
f' {os.path.join(contrib_dir, abi_triplet, "lib", "libsw*")}'
|
||||
includes = f' {os.path.join(contrib_dir, abi_triplet, "include", "libav*")}' \
|
||||
f' {os.path.join(contrib_dir, abi_triplet, "include", "libsw*")}'
|
||||
|
||||
# For a dry run:
|
||||
# execute_script([f'find {build_dir} {build_stamp} {tarball} {bins} {libs} {includes}'], fail=False)
|
||||
|
||||
execute_script([f'rm -rf {build_dir} {build_stamp} {tarball} {bins} {libs} {includes}'], fail=False)
|
||||
|
||||
|
||||
def run_run(args):
|
||||
run_env = os.environ
|
||||
|
||||
@ -626,6 +716,8 @@ def parse_args():
|
||||
ap.add_argument('--global-install', default=False, action='store_true')
|
||||
ap.add_argument('--debug', default=False, action='store_true',
|
||||
help='Build with debug support; run in GDB')
|
||||
ap.add_argument('--asan', default=False, action='store_true',
|
||||
help='Build both daemon and client with ASAN')
|
||||
ap.add_argument('--background', default=False, action='store_true')
|
||||
ap.add_argument('--no-priv-install', dest='priv_install',
|
||||
default=True, action='store_false')
|
||||
@ -640,6 +732,12 @@ def parse_args():
|
||||
default=False, action='store_true',
|
||||
help='Do not use Qt WebEngine.')
|
||||
ap.add_argument('--arch')
|
||||
ap.add_argument('--clean-contribs', nargs='+',
|
||||
help='Clean the specified contribs (space separated) or \
|
||||
"all" to clean all contribs before building.')
|
||||
ap.add_argument('--pywinmake', dest='pywinmake',
|
||||
default=False, action='store_true',
|
||||
help='Build Jami for Windows using pywinmake')
|
||||
|
||||
dist = choose_distribution()
|
||||
|
||||
@ -686,6 +784,10 @@ def choose_distribution():
|
||||
def main():
|
||||
parsed_args = parse_args()
|
||||
|
||||
# Clean contribs if specified first.
|
||||
if parsed_args.clean_contribs:
|
||||
clean_contribs(parsed_args.clean_contribs)
|
||||
|
||||
if parsed_args.dependencies:
|
||||
run_dependencies(parsed_args)
|
||||
|
||||
|
||||
2
daemon
@ -53,33 +53,36 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES_orig ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib;.so;.dll")
|
||||
|
||||
# Add the lib prefix for Windows checks.
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
set(CMAKE_FIND_LIBRARY_PREFIXES "lib;")
|
||||
endif()
|
||||
set(LIBJAMI_NAMES
|
||||
jami-core
|
||||
jami
|
||||
ring
|
||||
)
|
||||
|
||||
if(WITH_DAEMON_SUBMODULE)
|
||||
find_library(LIBJAMI_LIB NAMES jami ring
|
||||
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
|
||||
PATHS ${DAEMON_DIR}/src/.libs
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/bin
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/bin
|
||||
NO_DEFAULT_PATH)
|
||||
else()
|
||||
# Search only in these given PATHS.
|
||||
find_library(LIBJAMI_LIB NAMES jami ring
|
||||
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
|
||||
PATHS ${LIBJAMI_BUILD_DIR}/.libs
|
||||
PATHS ${RING_BUILD_DIR}/.libs
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/bin
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/bin
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
# Search elsewhere as well (e.g. system-wide).
|
||||
if(NOT LIBJAMI_LIB)
|
||||
find_library(LIBJAMI_LIB NAMES jami ring)
|
||||
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -88,27 +91,29 @@ if(NOT LIBJAMI_LIB)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.lib")
|
||||
|
||||
if(WITH_DAEMON_SUBMODULE)
|
||||
find_library(LIBJAMI_LIB NAMES jami ring
|
||||
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
|
||||
PATHS ${DAEMON_DIR}/src/.libs
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/lib
|
||||
NO_DEFAULT_PATH)
|
||||
else()
|
||||
# Search only in these given PATHS.
|
||||
find_library(LIBJAMI_LIB NAMES jami ring
|
||||
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES}
|
||||
PATHS ${LIBJAMI_BUILD_DIR}/.libs
|
||||
PATHS ${RING_BUILD_DIR}/.libs
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/lib
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/libexec
|
||||
PATHS ${CMAKE_INSTALL_PREFIX}/daemon/build/lib
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
# Search elsewhere as well (e.g. system-wide).
|
||||
if(NOT LIBJAMI_LIB)
|
||||
find_library(LIBJAMI_LIB NAMES jami ring)
|
||||
find_library(LIBJAMI_LIB NAMES ${LIBJAMI_NAMES})
|
||||
endif()
|
||||
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
|
||||
@ -49,7 +49,7 @@ QT_MAJOR := 6
|
||||
QT_MINOR := 4
|
||||
QT_PATCH := 3
|
||||
QT_TARBALL_CHECKSUM := 29a7eebdbba0ea57978dea6083709c93593a60f0f3133a3de08b9571ee8eaab4
|
||||
DEBIAN_QT_VERSION := $(QT_MAJOR).$(QT_MINOR).$(QT_PATCH)-2
|
||||
DEBIAN_QT_VERSION := $(QT_MAJOR).$(QT_MINOR).$(QT_PATCH)-3
|
||||
DEBIAN_QT_DSC_FILENAME := libqt-jami_$(DEBIAN_QT_VERSION).dsc
|
||||
QT_JAMI_PREFIX := /usr/lib/libqt-jami
|
||||
|
||||
@ -167,8 +167,10 @@ DISTRIBUTIONS := \
|
||||
ubuntu_20.04 \
|
||||
ubuntu_22.04 \
|
||||
ubuntu_23.04 \
|
||||
ubuntu_23.10 \
|
||||
fedora_37 \
|
||||
fedora_38 \
|
||||
fedora_39 \
|
||||
opensuse-leap_15.4 \
|
||||
snap
|
||||
|
||||
|
||||
104
extras/packaging/gnu-linux/docker/Dockerfile_fedora_39
Normal file
@ -0,0 +1,104 @@
|
||||
FROM fedora:39
|
||||
|
||||
RUN dnf clean all
|
||||
RUN dnf update -y
|
||||
|
||||
RUN dnf install -y dnf-command\(builddep\) rpmdevtools && \
|
||||
dnf install -y mock
|
||||
|
||||
RUN dnf groupinstall -y "X Software Development"
|
||||
|
||||
RUN dnf install -y \
|
||||
git \
|
||||
rpm-build \
|
||||
tar \
|
||||
make \
|
||||
autoconf \
|
||||
automake \
|
||||
nasm \
|
||||
speexdsp-devel \
|
||||
pulseaudio-libs-devel \
|
||||
libcanberra-devel \
|
||||
libcurl-devel \
|
||||
libtool \
|
||||
mesa-libgbm-devel \
|
||||
mesa-dri-drivers \
|
||||
dbus-devel \
|
||||
expat-devel \
|
||||
pcre-devel \
|
||||
yaml-cpp-devel \
|
||||
libXext-devel \
|
||||
libXfixes-devel \
|
||||
yasm \
|
||||
speex-devel \
|
||||
gsm-devel \
|
||||
chrpath \
|
||||
check \
|
||||
astyle \
|
||||
uuid-c++-devel \
|
||||
gettext-devel \
|
||||
gcc-c++ \
|
||||
which \
|
||||
alsa-lib-devel \
|
||||
systemd-devel \
|
||||
libuuid-devel \
|
||||
uuid-devel \
|
||||
gnutls-devel \
|
||||
nettle-devel \
|
||||
opus-devel \
|
||||
patch \
|
||||
jsoncpp-devel \
|
||||
libnatpmp-devel \
|
||||
webkitgtk4-devel \
|
||||
cryptopp-devel \
|
||||
libva-devel \
|
||||
libvdpau-devel \
|
||||
msgpack-devel \
|
||||
NetworkManager-libnm-devel \
|
||||
openssl-devel \
|
||||
clutter-devel \
|
||||
clutter-gtk-devel \
|
||||
libappindicator-gtk3-devel \
|
||||
libnotify-devel \
|
||||
libupnp-devel \
|
||||
qrencode-devel \
|
||||
libargon2-devel \
|
||||
libsndfile-devel \
|
||||
libdrm \
|
||||
gperf \
|
||||
bison \
|
||||
clang \
|
||||
clang-devel \
|
||||
llvm-devel \
|
||||
nodejs \
|
||||
flex \
|
||||
gstreamer1 gstreamer1-devel \
|
||||
gstreamer1-plugins-base-devel \
|
||||
gstreamer1-plugins-good \
|
||||
gstreamer1-plugins-bad-free-devel \
|
||||
nss-devel \
|
||||
libxcb* \
|
||||
libxkb* \
|
||||
libX11-devel \
|
||||
vulkan-devel \
|
||||
libXrender-devel \
|
||||
xcb-util-* \
|
||||
xz \
|
||||
xkeyboard-config \
|
||||
libnotify \
|
||||
wget \
|
||||
libstdc++-static \
|
||||
sqlite-devel \
|
||||
perl-generators \
|
||||
perl-English \
|
||||
libxshmfence-devel \
|
||||
ninja-build \
|
||||
clang \
|
||||
cmake \
|
||||
fmt-devel \
|
||||
python3.10 \
|
||||
cups-devel
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
|
||||
|
||||
CMD ["/opt/build-package-rpm.sh"]
|
||||
@ -70,6 +70,7 @@ RUN zypper --non-interactive install -y \
|
||||
nodejs12 \
|
||||
mozilla-nss-devel \
|
||||
python-xml \
|
||||
python-six \
|
||||
libxcb* \
|
||||
libxkb* \
|
||||
libX11-devel \
|
||||
|
||||
22
extras/packaging/gnu-linux/docker/Dockerfile_ubuntu_23.10
Normal file
@ -0,0 +1,22 @@
|
||||
FROM ubuntu:23.10
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get clean
|
||||
RUN apt-get update && \
|
||||
apt-get install -y -o Acquire::Retries=10 \
|
||||
devscripts \
|
||||
equivs \
|
||||
python-is-python3 \
|
||||
wget
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/prebuild-package-debian.sh /opt/prebuild-package-debian.sh
|
||||
|
||||
COPY extras/packaging/gnu-linux/rules/debian-qt/control /tmp/builddeps/debian/control
|
||||
RUN /opt/prebuild-package-debian.sh qt-deps
|
||||
|
||||
COPY extras/packaging/gnu-linux/rules/debian/control /tmp/builddeps/debian/control
|
||||
RUN /opt/prebuild-package-debian.sh jami-deps
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-debian.sh /opt/build-package-debian.sh
|
||||
CMD ["/opt/build-package-debian.sh"]
|
||||
@ -0,0 +1,81 @@
|
||||
From ecae5d93b0a89e2b8c16a2227b2d176f58579d04 Mon Sep 17 00:00:00 2001
|
||||
From: Rémi Denis-Courmont <remi@remlab.net>
|
||||
Date: Sun, 16 Jul 2023 18:18:02 +0300
|
||||
Subject: [PATCH] Fix ffmpeg assembly with newer binutil
|
||||
|
||||
avcodec/x86/mathops: clip constants used with shift instructions within inline assembly
|
||||
|
||||
Fixes assembling with binutil as >= 2.41
|
||||
|
||||
FFmpeg commit effadce6c756247ea8bae32dc13bb3e6f464f0eb.
|
||||
|
||||
Deals with: "Error: operand type mismatch for `shr'"
|
||||
|
||||
Fixes: QTBUG-116649
|
||||
Change-Id: I094e8c23fed4a61fba3f1e3a9c73c016d129d830
|
||||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/495990
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
|
||||
(cherry picked from commit 29354c7c7def7bdc66bcd25d401677fd9421f657)
|
||||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/509219
|
||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
||||
---
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
|
||||
index 6298f5e..ca7e2df 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
|
||||
@@ -35,12 +35,20 @@
|
||||
static av_always_inline av_const int MULL(int a, int b, unsigned shift)
|
||||
{
|
||||
int rt, dummy;
|
||||
+ if (__builtin_constant_p(shift))
|
||||
__asm__ (
|
||||
"imull %3 \n\t"
|
||||
"shrdl %4, %%edx, %%eax \n\t"
|
||||
:"=a"(rt), "=d"(dummy)
|
||||
- :"a"(a), "rm"(b), "ci"((uint8_t)shift)
|
||||
+ :"a"(a), "rm"(b), "i"(shift & 0x1F)
|
||||
);
|
||||
+ else
|
||||
+ __asm__ (
|
||||
+ "imull %3 \n\t"
|
||||
+ "shrdl %4, %%edx, %%eax \n\t"
|
||||
+ :"=a"(rt), "=d"(dummy)
|
||||
+ :"a"(a), "rm"(b), "c"((uint8_t)shift)
|
||||
+ );
|
||||
return rt;
|
||||
}
|
||||
|
||||
@@ -113,19 +121,31 @@
|
||||
// avoid +32 for shift optimization (gcc should do that ...)
|
||||
#define NEG_SSR32 NEG_SSR32
|
||||
static inline int32_t NEG_SSR32( int32_t a, int8_t s){
|
||||
+ if (__builtin_constant_p(s))
|
||||
__asm__ ("sarl %1, %0\n\t"
|
||||
: "+r" (a)
|
||||
- : "ic" ((uint8_t)(-s))
|
||||
+ : "i" (-s & 0x1F)
|
||||
);
|
||||
+ else
|
||||
+ __asm__ ("sarl %1, %0\n\t"
|
||||
+ : "+r" (a)
|
||||
+ : "c" ((uint8_t)(-s))
|
||||
+ );
|
||||
return a;
|
||||
}
|
||||
|
||||
#define NEG_USR32 NEG_USR32
|
||||
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
|
||||
+ if (__builtin_constant_p(s))
|
||||
__asm__ ("shrl %1, %0\n\t"
|
||||
: "+r" (a)
|
||||
- : "ic" ((uint8_t)(-s))
|
||||
+ : "i" (-s & 0x1F)
|
||||
);
|
||||
+ else
|
||||
+ __asm__ ("shrl %1, %0\n\t"
|
||||
+ : "+r" (a)
|
||||
+ : "c" ((uint8_t)(-s))
|
||||
+ );
|
||||
return a;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
index 3488120..120e47a 100644
|
||||
--- a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
+++ b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
@@ -472,7 +472,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
||||
}
|
||||
catch (const DeadlyImportError& e)
|
||||
{
|
||||
- if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
|
||||
+ if (!is64bits && (length > std::numeric_limits<uint32_t>::max())) {
|
||||
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
|
||||
}
|
||||
throw;
|
||||
@ -0,0 +1,433 @@
|
||||
qtbase/src/corelib/debug_script.py | 2 +-
|
||||
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py | 2 +-
|
||||
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py | 2 +-
|
||||
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py | 2 +-
|
||||
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py | 2 +-
|
||||
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py | 2 +-
|
||||
.../3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py | 2 +-
|
||||
31 files changed, 31 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/qtbase/src/corelib/debug_script.py b/qtbase/src/corelib/debug_script.py
|
||||
index f6207c6104..663c8e0ac1 100644
|
||||
--- a/qtbase/src/corelib/debug_script.py
|
||||
+++ b/qtbase/src/corelib/debug_script.py
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
|
||||
index 681039d34b..a1fe56fa05 100644
|
||||
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
|
||||
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
|
||||
@@ -16,7 +16,7 @@ import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
# from TestCasePackagerConfig import *
|
||||
|
||||
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
|
||||
index 92d4e6139b..7a18e12ced 100644
|
||||
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
|
||||
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
|
||||
@@ -7,7 +7,7 @@ import unittest
|
||||
|
||||
import os
|
||||
import yaml
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
# add parent dir to search path
|
||||
import sys
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
|
||||
index c7412927c8..ad2caff318 100755
|
||||
--- a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
-import imp
|
||||
+import importlib
|
||||
import tempfile
|
||||
import unittest
|
||||
import PRESUBMIT
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
index 5daee773ba..2d6b124162 100755
|
||||
--- a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
@@ -9,7 +9,7 @@
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import abc
|
||||
-import imp
|
||||
+import importlib
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
index bf626f5479..3fae129aaa 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
@@ -3,7 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import errno
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
index ff5753a291..04fc34f742 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import shutil
|
||||
import sys
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
index 32c884a8c0..e761faa54c 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
index 95a916db08..4331e2fbfa 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
index 62798631db..28e9dbf705 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
index cba249b0f3..5a4051827a 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
index 4a2fefc712..11a9879cb7 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
index cc17ae0253..bcc944f06b 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
index bd72830e54..f2fdc9ae28 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
|
||||
index 1feb303a48..8428de61bb 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
|
||||
@@ -6,7 +6,7 @@
|
||||
angle_presubmit_utils_unittest.py: Top-level unittest script for ANGLE presubmit checks.
|
||||
"""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os
|
||||
import unittest
|
||||
from angle_presubmit_utils import *
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
|
||||
index ed4f38c67b..cac734cefa 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
|
||||
@@ -7,7 +7,7 @@ See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
|
||||
for more details about the presubmit API built into gcl.
|
||||
"""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
|
||||
index 0244c9787e..f535afe99c 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
|
||||
@@ -32,7 +32,7 @@ if PY3:
|
||||
memoryview_type = memoryview
|
||||
struct_bool_decl = "?"
|
||||
else:
|
||||
- import imp
|
||||
+ import importlib
|
||||
string_types = (unicode,)
|
||||
if PY26 or PY27:
|
||||
binary_types = (str,bytearray)
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
|
||||
index 8430390eea..29212205bc 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
|
||||
@@ -732,7 +732,7 @@ class Environment(object):
|
||||
)
|
||||
py_compile = False
|
||||
else:
|
||||
- import imp
|
||||
+ import importlib
|
||||
import marshal
|
||||
|
||||
py_header = imp.get_magic() + u"\xff\xff\xff\xff".encode("iso-8859-15")
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
|
||||
index 06bb8d99f5..05089dc982 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
|
||||
@@ -115,7 +115,7 @@ if py3k:
|
||||
return module
|
||||
|
||||
else:
|
||||
- import imp
|
||||
+ import importlib
|
||||
|
||||
def load_module(module_id, path):
|
||||
fp = open(path, "rb")
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
|
||||
index a7dc683365..68b6804c78 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for call_trees module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from tensorflow.python.autograph.converters import call_trees
|
||||
from tensorflow.python.autograph.converters import functions
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
|
||||
index 81a7fde808..1370f900fd 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for converter module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from tensorflow.python.autograph.core import converter
|
||||
from tensorflow.python.autograph.core import converter_testing
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
|
||||
index b93cbb627b..452ec71f5b 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
|
||||
@@ -15,7 +15,7 @@
|
||||
"""Base class for tests in this module."""
|
||||
|
||||
import contextlib
|
||||
-import imp
|
||||
+import importlib
|
||||
import inspect
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
|
||||
index 9a62d7c0d2..7ec4fa6dca 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
|
||||
@@ -19,7 +19,7 @@ import collections
|
||||
import contextlib
|
||||
import functools
|
||||
import gc
|
||||
-import imp
|
||||
+import importlib
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
|
||||
index 852af3efe7..6456c50446 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for conversion module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import sys
|
||||
import types
|
||||
import weakref
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
|
||||
index a50a64534a..ba0f31afa2 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
|
||||
@@ -17,7 +17,7 @@
|
||||
import abc
|
||||
import collections
|
||||
import functools
|
||||
-import imp
|
||||
+import importlib
|
||||
import textwrap
|
||||
|
||||
import six
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
|
||||
index 29f38d853a..7ca88fa371 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for templates module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from absl.testing import parameterized
|
||||
import gast
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
|
||||
index e46460574b..a40fea6568 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# =============================================================================
|
||||
"""Tests for create_python_api."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import sys
|
||||
|
||||
from tensorflow.python.platform import test
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
|
||||
index 73d1742714..ea77dd7647 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
|
||||
@@ -1,5 +1,5 @@
|
||||
import importlib
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from .browsers import product_list
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
|
||||
index 6a744472b5..9175cb5d34 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
|
||||
@@ -1,6 +1,6 @@
|
||||
import copy
|
||||
import functools
|
||||
-import imp
|
||||
+import importlib
|
||||
import io
|
||||
import os
|
||||
from collections import OrderedDict, defaultdict
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
|
||||
index 6912b6f3c0..7d851f7f76 100755
|
||||
--- a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import optparse
|
||||
import os
|
||||
import pipes
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
|
||||
index 1c2aba80af..55260d697e 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
|
||||
@@ -10,7 +10,7 @@ from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from _monkeyYaml import load as yamlLoad
|
||||
|
||||
@ -1,2 +1,5 @@
|
||||
0001-fix-gcc13.patch
|
||||
0002-OpenFile-portal-do-not-use-O_PATH-fds.patch
|
||||
0002-OpenFile-portal-do-not-use-O_PATH-fds.patch
|
||||
0003-fix-mathops.patch
|
||||
0004-fix-binary-tokenizer.patch
|
||||
0005-importlib.patch
|
||||
@ -101,6 +101,8 @@ if [ -f /etc/os-release ]; then
|
||||
ENDTAG="ubuntu_22.04"
|
||||
elif [ "${UBUNTU_CODENAME}" = "lunar" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_23.04" ]; then
|
||||
ENDTAG="ubuntu_23.04"
|
||||
elif [ "${UBUNTU_CODENAME}" = "mantic" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_23.10" ]; then
|
||||
ENDTAG="ubuntu_23.10"
|
||||
elif [ "${ID}" = "debian" ] && \
|
||||
[ "$(command -v lsb_release)" ] && \
|
||||
[ "$(lsb_release -rs)" = "testing" ]; then
|
||||
|
||||
@ -28,6 +28,9 @@ URL: https://jami.net/
|
||||
Source: jami-libqt-%{version}.tar.xz
|
||||
Patch0: 0001-fix-gcc13.patch
|
||||
Patch1: 0002-OpenFile-portal-do-not-use-O_PATH-fds.patch
|
||||
Patch2: 0003-fix-mathops.patch
|
||||
Patch3: 0004-fix-binary-tokenizer.patch
|
||||
Patch4: 0005-importlib.patch
|
||||
|
||||
%global gst 0.10
|
||||
%if 0%{?fedora} || 0%{?rhel} > 7
|
||||
@ -42,6 +45,7 @@ BuildRequires: bison
|
||||
BuildRequires: gperf
|
||||
BuildRequires: flex
|
||||
BuildRequires: vulkan-devel
|
||||
BuildRequires: python-six
|
||||
%if %{defined suse_version}
|
||||
BuildRequires: ffmpeg-devel
|
||||
BuildRequires: ffmpeg
|
||||
@ -64,6 +68,9 @@ This package contains Qt libraries for Jami.
|
||||
%setup -n qt-everywhere-src-%{version}
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
|
||||
%build
|
||||
echo "Building Qt using %{job_count} parallel jobs"
|
||||
@ -84,6 +91,15 @@ cat qtbase/src/corelib/global/qendian.h
|
||||
sed -i 's,#include <string.h>,#include <string.h>\n#include <limits>,g' qtbase/src/corelib/global/qfloat16.h
|
||||
sed -i 's,#include <QtCore/qbytearray.h>,#include <QtCore/qbytearray.h>\n#include <limits>,g' qtbase/src/corelib/text/qbytearraymatcher.h
|
||||
cat qtwebengine/configure.cmake
|
||||
|
||||
#https://bugreports.qt.io/browse/QTBUG-117979
|
||||
if test -f "/usr/bin/python3.10"; then
|
||||
/usr/bin/python3.10 -m venv env
|
||||
source env/bin/activate
|
||||
python -m pip install html5lib
|
||||
python -m pip install six
|
||||
fi
|
||||
|
||||
# recent gcc version do not like lto from qt
|
||||
CXXFLAGS="${CXXFLAGS} -fno-lto" CFLAGS="${CFLAGS} -fno-lto" LDFLAGS="$(CFLAGS) ${LDFLAGS}" ./configure \
|
||||
-opensource \
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
From ecae5d93b0a89e2b8c16a2227b2d176f58579d04 Mon Sep 17 00:00:00 2001
|
||||
From: Rémi Denis-Courmont <remi@remlab.net>
|
||||
Date: Sun, 16 Jul 2023 18:18:02 +0300
|
||||
Subject: [PATCH] Fix ffmpeg assembly with newer binutil
|
||||
|
||||
avcodec/x86/mathops: clip constants used with shift instructions within inline assembly
|
||||
|
||||
Fixes assembling with binutil as >= 2.41
|
||||
|
||||
FFmpeg commit effadce6c756247ea8bae32dc13bb3e6f464f0eb.
|
||||
|
||||
Deals with: "Error: operand type mismatch for `shr'"
|
||||
|
||||
Fixes: QTBUG-116649
|
||||
Change-Id: I094e8c23fed4a61fba3f1e3a9c73c016d129d830
|
||||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/495990
|
||||
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
|
||||
(cherry picked from commit 29354c7c7def7bdc66bcd25d401677fd9421f657)
|
||||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/509219
|
||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
||||
---
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
|
||||
index 6298f5e..ca7e2df 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h
|
||||
@@ -35,12 +35,20 @@
|
||||
static av_always_inline av_const int MULL(int a, int b, unsigned shift)
|
||||
{
|
||||
int rt, dummy;
|
||||
+ if (__builtin_constant_p(shift))
|
||||
__asm__ (
|
||||
"imull %3 \n\t"
|
||||
"shrdl %4, %%edx, %%eax \n\t"
|
||||
:"=a"(rt), "=d"(dummy)
|
||||
- :"a"(a), "rm"(b), "ci"((uint8_t)shift)
|
||||
+ :"a"(a), "rm"(b), "i"(shift & 0x1F)
|
||||
);
|
||||
+ else
|
||||
+ __asm__ (
|
||||
+ "imull %3 \n\t"
|
||||
+ "shrdl %4, %%edx, %%eax \n\t"
|
||||
+ :"=a"(rt), "=d"(dummy)
|
||||
+ :"a"(a), "rm"(b), "c"((uint8_t)shift)
|
||||
+ );
|
||||
return rt;
|
||||
}
|
||||
|
||||
@@ -113,19 +121,31 @@
|
||||
// avoid +32 for shift optimization (gcc should do that ...)
|
||||
#define NEG_SSR32 NEG_SSR32
|
||||
static inline int32_t NEG_SSR32( int32_t a, int8_t s){
|
||||
+ if (__builtin_constant_p(s))
|
||||
__asm__ ("sarl %1, %0\n\t"
|
||||
: "+r" (a)
|
||||
- : "ic" ((uint8_t)(-s))
|
||||
+ : "i" (-s & 0x1F)
|
||||
);
|
||||
+ else
|
||||
+ __asm__ ("sarl %1, %0\n\t"
|
||||
+ : "+r" (a)
|
||||
+ : "c" ((uint8_t)(-s))
|
||||
+ );
|
||||
return a;
|
||||
}
|
||||
|
||||
#define NEG_USR32 NEG_USR32
|
||||
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
|
||||
+ if (__builtin_constant_p(s))
|
||||
__asm__ ("shrl %1, %0\n\t"
|
||||
: "+r" (a)
|
||||
- : "ic" ((uint8_t)(-s))
|
||||
+ : "i" (-s & 0x1F)
|
||||
);
|
||||
+ else
|
||||
+ __asm__ ("shrl %1, %0\n\t"
|
||||
+ : "+r" (a)
|
||||
+ : "c" ((uint8_t)(-s))
|
||||
+ );
|
||||
return a;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
index 3488120..120e47a 100644
|
||||
--- a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
+++ b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
@@ -472,7 +472,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
||||
}
|
||||
catch (const DeadlyImportError& e)
|
||||
{
|
||||
- if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
|
||||
+ if (!is64bits && (length > std::numeric_limits<uint32_t>::max())) {
|
||||
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
|
||||
}
|
||||
throw;
|
||||
@ -0,0 +1,433 @@
|
||||
qtbase/src/corelib/debug_script.py | 2 +-
|
||||
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py | 2 +-
|
||||
qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py | 2 +-
|
||||
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py | 2 +-
|
||||
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py | 2 +-
|
||||
.../src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py | 2 +-
|
||||
.../3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py | 2 +-
|
||||
qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py | 2 +-
|
||||
31 files changed, 31 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/qtbase/src/corelib/debug_script.py b/qtbase/src/corelib/debug_script.py
|
||||
index f6207c6104..663c8e0ac1 100644
|
||||
--- a/qtbase/src/corelib/debug_script.py
|
||||
+++ b/qtbase/src/corelib/debug_script.py
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
|
||||
index 681039d34b..a1fe56fa05 100644
|
||||
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
|
||||
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/parseTestRecord.py
|
||||
@@ -16,7 +16,7 @@ import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
# from TestCasePackagerConfig import *
|
||||
|
||||
diff --git a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
|
||||
index 92d4e6139b..7a18e12ced 100644
|
||||
--- a/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
|
||||
+++ b/qtdeclarative/tests/auto/qml/ecmascripttests/test262/tools/packaging/test/test_monkeyYaml.py
|
||||
@@ -7,7 +7,7 @@ import unittest
|
||||
|
||||
import os
|
||||
import yaml
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
# add parent dir to search path
|
||||
import sys
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
|
||||
index c7412927c8..ad2caff318 100755
|
||||
--- a/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/chrome/browser/resources/PRESUBMIT_test.py
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
-import imp
|
||||
+import importlib
|
||||
import tempfile
|
||||
import unittest
|
||||
import PRESUBMIT
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
index 5daee773ba..2d6b124162 100755
|
||||
--- a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
@@ -9,7 +9,7 @@
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import abc
|
||||
-import imp
|
||||
+import importlib
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
index bf626f5479..3fae129aaa 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
@@ -3,7 +3,7 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import errno
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
index ff5753a291..04fc34f742 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import shutil
|
||||
import sys
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
index 32c884a8c0..e761faa54c 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
index 95a916db08..4331e2fbfa 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
index 62798631db..28e9dbf705 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
index cba249b0f3..5a4051827a 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
index 4a2fefc712..11a9879cb7 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
index cc17ae0253..bcc944f06b 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
index bd72830e54..f2fdc9ae28 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
@@ -2,7 +2,7 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
|
||||
index 1feb303a48..8428de61bb 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/angle/scripts/angle_presubmit_utils_unittest.py
|
||||
@@ -6,7 +6,7 @@
|
||||
angle_presubmit_utils_unittest.py: Top-level unittest script for ANGLE presubmit checks.
|
||||
"""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import os
|
||||
import unittest
|
||||
from angle_presubmit_utils import *
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
|
||||
index ed4f38c67b..cac734cefa 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/blink/PRESUBMIT.py
|
||||
@@ -7,7 +7,7 @@ See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
|
||||
for more details about the presubmit API built into gcl.
|
||||
"""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
|
||||
index 0244c9787e..f535afe99c 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/flatbuffers/src/python/flatbuffers/compat.py
|
||||
@@ -32,7 +32,7 @@ if PY3:
|
||||
memoryview_type = memoryview
|
||||
struct_bool_decl = "?"
|
||||
else:
|
||||
- import imp
|
||||
+ import importlib
|
||||
string_types = (unicode,)
|
||||
if PY26 or PY27:
|
||||
binary_types = (str,bytearray)
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
|
||||
index 8430390eea..29212205bc 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/jinja2/environment.py
|
||||
@@ -732,7 +732,7 @@ class Environment(object):
|
||||
)
|
||||
py_compile = False
|
||||
else:
|
||||
- import imp
|
||||
+ import importlib
|
||||
import marshal
|
||||
|
||||
py_header = imp.get_magic() + u"\xff\xff\xff\xff".encode("iso-8859-15")
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
|
||||
index 06bb8d99f5..05089dc982 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/mako/mako/compat.py
|
||||
@@ -115,7 +115,7 @@ if py3k:
|
||||
return module
|
||||
|
||||
else:
|
||||
- import imp
|
||||
+ import importlib
|
||||
|
||||
def load_module(module_id, path):
|
||||
fp = open(path, "rb")
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
|
||||
index a7dc683365..68b6804c78 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/converters/call_trees_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for call_trees module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from tensorflow.python.autograph.converters import call_trees
|
||||
from tensorflow.python.autograph.converters import functions
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
|
||||
index 81a7fde808..1370f900fd 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for converter module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from tensorflow.python.autograph.core import converter
|
||||
from tensorflow.python.autograph.core import converter_testing
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
|
||||
index b93cbb627b..452ec71f5b 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/core/converter_testing.py
|
||||
@@ -15,7 +15,7 @@
|
||||
"""Base class for tests in this module."""
|
||||
|
||||
import contextlib
|
||||
-import imp
|
||||
+import importlib
|
||||
import inspect
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
|
||||
index 9a62d7c0d2..7ec4fa6dca 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/api_test.py
|
||||
@@ -19,7 +19,7 @@ import collections
|
||||
import contextlib
|
||||
import functools
|
||||
import gc
|
||||
-import imp
|
||||
+import importlib
|
||||
import inspect
|
||||
import os
|
||||
import re
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
|
||||
index 852af3efe7..6456c50446 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/impl/conversion_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for conversion module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import sys
|
||||
import types
|
||||
import weakref
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
|
||||
index a50a64534a..ba0f31afa2 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/inspect_utils_test.py
|
||||
@@ -17,7 +17,7 @@
|
||||
import abc
|
||||
import collections
|
||||
import functools
|
||||
-import imp
|
||||
+import importlib
|
||||
import textwrap
|
||||
|
||||
import six
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
|
||||
index 29f38d853a..7ca88fa371 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/autograph/pyct/templates_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# ==============================================================================
|
||||
"""Tests for templates module."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from absl.testing import parameterized
|
||||
import gast
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
|
||||
index e46460574b..a40fea6568 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/tflite/src/tensorflow/python/tools/api/generator/create_python_api_test.py
|
||||
@@ -14,7 +14,7 @@
|
||||
# =============================================================================
|
||||
"""Tests for create_python_api."""
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import sys
|
||||
|
||||
from tensorflow.python.platform import test
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
|
||||
index 73d1742714..ea77dd7647 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/products.py
|
||||
@@ -1,5 +1,5 @@
|
||||
import importlib
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from .browsers import product_list
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
|
||||
index 6a744472b5..9175cb5d34 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/stability.py
|
||||
@@ -1,6 +1,6 @@
|
||||
import copy
|
||||
import functools
|
||||
-import imp
|
||||
+import importlib
|
||||
import io
|
||||
import os
|
||||
from collections import OrderedDict, defaultdict
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
|
||||
index 6912b6f3c0..7d851f7f76 100755
|
||||
--- a/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/tools/sublime/ninja_options_script.py
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
-import imp
|
||||
+import importlib
|
||||
import optparse
|
||||
import os
|
||||
import pipes
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
|
||||
index 1c2aba80af..55260d697e 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/v8/third_party/test262-harness/src/parseTestRecord.py
|
||||
@@ -10,7 +10,7 @@ from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
-import imp
|
||||
+import importlib
|
||||
|
||||
from _monkeyYaml import load as yamlLoad
|
||||
|
||||
@ -46,7 +46,7 @@ CMAKE_PREFIX_PATH="${QT_JAMI_PREFIX}/lib/cmake:${CMAKE_PREFIX_PATH}"
|
||||
QT_MAJOR=6
|
||||
QT_MINOR=4
|
||||
QT_PATCH=3
|
||||
QT_RELEASE_PATCH=2
|
||||
QT_RELEASE_PATCH=3
|
||||
|
||||
QT_MAJOR_MINOR=${QT_MAJOR}.${QT_MINOR}
|
||||
QT_MAJOR_MINOR_PATCH=${QT_MAJOR}.${QT_MINOR}.${QT_PATCH}
|
||||
@ -105,18 +105,14 @@ if [ ! -f "${RPM_PATH}" ]; then
|
||||
# Cache the built Qt RPM package.
|
||||
if [[ "${DISTRIBUTION:0:4}" == "rhel" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.el8.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_33" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc33.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_34" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc34.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_35" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc35.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_36" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc36.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_37" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc37.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_38" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc38.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_39" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc39.x86_64.rpm "${RPM_PATH}"
|
||||
else
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-*.rpm "${RPM_PATH}"
|
||||
fi
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Build, test, and package the project.
|
||||
|
||||
@ -65,6 +65,15 @@ this_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
repo_root_dir = os.path.abspath(os.path.join(this_dir, os.pardir, os.pardir))
|
||||
build_dir = os.path.join(repo_root_dir, "build")
|
||||
|
||||
def get_latest_toolset_version():
|
||||
"""Get the latest toolset version."""
|
||||
# Get the visual studio version. Use only the major version number.
|
||||
# Then: toolset = 2022 ? "v143" : 2019 ? "v142" : 2017 ? "v141" : "v140"
|
||||
vs_ver = get_vs_prop("installationVersion")
|
||||
if vs_ver is None:
|
||||
return None
|
||||
vs_ver = int(vs_ver.split(".")[0])
|
||||
return "v143" if vs_ver >= 16 else "v142" if vs_ver >= 15 else "v141"
|
||||
|
||||
def find_latest_qt_path():
|
||||
"""Find the latest Qt installation path."""
|
||||
@ -190,40 +199,31 @@ def init_submodules():
|
||||
"""Initialize any git submodules in the project."""
|
||||
print("Initializing submodules...")
|
||||
|
||||
if execute_cmd(["git", "submodule", "update", "--init"], False):
|
||||
# Init the client submodules for Windows other than the daemon.
|
||||
submodules = [
|
||||
"3rdparty/qrencode-win32",
|
||||
"3rdparty/SortFilterProxyModel",
|
||||
"3rdparty/md4c",
|
||||
"3rdparty/tidy-html5",
|
||||
]
|
||||
if execute_cmd(["git", "submodule", "update", "--init" ] + submodules,
|
||||
False):
|
||||
print("Submodule initialization error.")
|
||||
else:
|
||||
if execute_cmd(["git", "submodule", "update", "--recursive"], False):
|
||||
print("Submodule recursive checkout error.")
|
||||
else:
|
||||
print("Submodule recursive checkout finished.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def build_deps():
|
||||
"""Build the dependencies for the project."""
|
||||
print('Patching and building qrencode')
|
||||
apply_cmd = [
|
||||
'git',
|
||||
'apply',
|
||||
'--reject',
|
||||
'--ignore-whitespace',
|
||||
'--whitespace=fix'
|
||||
]
|
||||
print('Building qrencode')
|
||||
qrencode_dir = os.path.join(repo_root_dir, '3rdparty', 'qrencode-win32')
|
||||
patch_file = os.path.join(repo_root_dir, 'qrencode-win32.patch')
|
||||
apply_cmd.append(patch_file)
|
||||
if execute_cmd(apply_cmd, False, None, qrencode_dir):
|
||||
print("Couldn't patch qrencode-win32.")
|
||||
|
||||
vs_env_vars = {}
|
||||
vs_env_vars.update(get_vs_env())
|
||||
|
||||
msbuild_args = get_ms_build_args("x64", "Release-Lib")
|
||||
|
||||
toolset = get_latest_toolset_version()
|
||||
print(f'Using toolset {toolset}')
|
||||
msbuild_args = get_ms_build_args("x64", "Release-Lib", toolset)
|
||||
proj_path = os.path.join(
|
||||
qrencode_dir, "qrencode-win32", "vc8", "qrcodelib", "qrcodelib.vcxproj"
|
||||
qrencode_dir, "qrencode-win32", "vc15", "qrcodelib", "qrcodelib.vcxproj"
|
||||
)
|
||||
|
||||
build_project(msbuild_args, proj_path, vs_env_vars)
|
||||
|
||||
|
||||
@ -264,17 +264,15 @@ def build(config_str, qt_dir, tests):
|
||||
|
||||
# Get the daemon bin/include directories.
|
||||
daemon_dir = os.path.join(repo_root_dir, "daemon")
|
||||
daemon_bin_dir = os.path.join(
|
||||
daemon_dir, "build", "x64", "ReleaseLib_win32", "bin")
|
||||
daemon_bin_dir = os.path.join(daemon_dir, "build", "lib")
|
||||
|
||||
# We need to update the minimum SDK version to be able to
|
||||
# build with system theme support
|
||||
cmake_options = [
|
||||
"-DWITH_DAEMON_SUBMODULE=ON",
|
||||
"-DJAMICORE_AS_SUBDIR=ON",
|
||||
"-DCMAKE_PREFIX_PATH=" + qt_dir,
|
||||
"-DCMAKE_MSVCIDE_RUN_PATH=" + qt_dir + "\\bin",
|
||||
"-DCMAKE_INSTALL_PREFIX=" + daemon_bin_dir,
|
||||
"-DLIBJAMI_INCLUDE_DIR=" + daemon_dir + "\\src\\jami",
|
||||
"-DCMAKE_INSTALL_PREFIX=" + os.getcwd(),
|
||||
"-DCMAKE_SYSTEM_VERSION=" + WIN_SDK_VERSION,
|
||||
"-DCMAKE_BUILD_TYPE=" + "Release",
|
||||
"-DENABLE_TESTS=" + str(tests).lower(),
|
||||
|
||||
@ -43,9 +43,10 @@ proc='1'
|
||||
priv_install=true
|
||||
enable_libwrap=true
|
||||
enable_webengine=true
|
||||
asan=
|
||||
arch=''
|
||||
|
||||
while getopts gsc:dQ:P:p:uWwa: OPT; do
|
||||
while getopts gsc:dQ:P:p:uWwa:A OPT; do
|
||||
case "$OPT" in
|
||||
g)
|
||||
global='true'
|
||||
@ -77,6 +78,9 @@ while getopts gsc:dQ:P:p:uWwa: OPT; do
|
||||
a)
|
||||
arch="${OPTARG}"
|
||||
;;
|
||||
A)
|
||||
asan='true'
|
||||
;;
|
||||
\?)
|
||||
exit 1
|
||||
;;
|
||||
@ -116,7 +120,7 @@ else
|
||||
mkdir -p contrib/native
|
||||
(
|
||||
cd contrib/native
|
||||
../bootstrap ${prefix:+"--prefix=$prefix"}
|
||||
../bootstrap ${prefix:+"--prefix=$prefix"} ${asan:+"--enable-asan"}
|
||||
make -j"${proc}"
|
||||
)
|
||||
|
||||
@ -135,6 +139,10 @@ else
|
||||
CONFIGURE_FLAGS+=" --enable-debug"
|
||||
fi
|
||||
|
||||
if [ "${asan}" = "true" ]; then
|
||||
CONFIGURE_FLAGS+=" --enable-asan"
|
||||
fi
|
||||
|
||||
# Build the daemon itself.
|
||||
test -f configure || ./autogen.sh
|
||||
|
||||
@ -183,6 +191,11 @@ client_cmake_flags=(-DCMAKE_BUILD_TYPE="${BUILD_TYPE}"
|
||||
-DCMAKE_PREFIX_PATH="${qtpath}"
|
||||
-DENABLE_LIBWRAP="${enable_libwrap}"
|
||||
-DWITH_WEBENGINE="${enable_webengine}")
|
||||
|
||||
if [ "${asan}" = "true" ]; then
|
||||
client_cmake_flags+=(-DENABLE_ASAN=true)
|
||||
fi
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
#detect arch for macos
|
||||
CMAKE_OSX_ARCHITECTURES="arm64"
|
||||
|
||||
@ -1,243 +0,0 @@
|
||||
From 261d830b9b4126d76519db0e6b6b51b5a730eb40 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
Date: Tue, 4 Dec 2018 17:42:43 -0500
|
||||
Subject: [PATCH] b
|
||||
|
||||
---
|
||||
.../vc8/qrcodelib/qrcodelib.vcxproj | 129 +++++++++++++++++-
|
||||
1 file changed, 125 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj b/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj
|
||||
index aabc6b6..8d8293b 100644
|
||||
--- a/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj
|
||||
+++ b/qrencode-win32/vc8/qrcodelib/qrcodelib.vcxproj
|
||||
@@ -5,45 +5,84 @@
|
||||
<Configuration>Debug-Dll</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Debug-Dll|x64">
|
||||
+ <Configuration>Debug-Dll</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug-Lib|Win32">
|
||||
<Configuration>Debug-Lib</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Debug-Lib|x64">
|
||||
+ <Configuration>Debug-Lib</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release-Dll|Win32">
|
||||
<Configuration>Release-Dll</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release-Dll|x64">
|
||||
+ <Configuration>Release-Dll</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release-Lib|Win32">
|
||||
<Configuration>Release-Lib</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
+ <ProjectConfiguration Include="Release-Lib|x64">
|
||||
+ <Configuration>Release-Lib</Configuration>
|
||||
+ <Platform>x64</Platform>
|
||||
+ </ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9A90BF5C-84B0-41F6-B83C-C20EADC1F46C}</ProjectGuid>
|
||||
<RootNamespace>qrcodelib</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
+ <WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
- <PlatformToolset>v110_xp</PlatformToolset>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
+ <CharacterSet>MultiByte</CharacterSet>
|
||||
+ <WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
- <PlatformToolset>v110_xp</PlatformToolset>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
+ <CharacterSet>MultiByte</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
- <PlatformToolset>v110_xp</PlatformToolset>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
+ <CharacterSet>MultiByte</CharacterSet>
|
||||
+ <WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
- <PlatformToolset>v110_xp</PlatformToolset>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
+ <CharacterSet>MultiByte</CharacterSet>
|
||||
+ </PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'" Label="Configuration">
|
||||
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
+ <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
@@ -52,15 +91,27 @@
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'" Label="PropertySheets">
|
||||
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
+ </ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>
|
||||
@@ -70,11 +121,17 @@
|
||||
<IntDir>../.build/$(ProjectName)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'">
|
||||
+ <LinkIncremental>true</LinkIncremental>
|
||||
+ </PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'">
|
||||
<OutDir>../.build/$(Configuration)\</OutDir>
|
||||
<IntDir>../.build/$(ProjectName)/$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'">
|
||||
+ <LinkIncremental>false</LinkIncremental>
|
||||
+ </PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
|
||||
<OutDir>../.build/$(Configuration)\</OutDir>
|
||||
<IntDir>../.build/$(ProjectName)/$(Configuration)\</IntDir>
|
||||
@@ -104,6 +161,26 @@
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Link>
|
||||
+ <AdditionalDependencies>libpng15d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
+ <AdditionalLibraryDirectories>..\qrcode\png;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
+ <ModuleDefinitionFile>qrcodelib.def</ModuleDefinitionFile>
|
||||
+ <GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
+ <SubSystem>Windows</SubSystem>
|
||||
+ </Link>
|
||||
+ </ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
@@ -124,6 +201,26 @@
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ <Link>
|
||||
+ <AdditionalDependencies>libpng15.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
+ <AdditionalLibraryDirectories>..\qrcode\png;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
+ <ModuleDefinitionFile>qrcodelib.def</ModuleDefinitionFile>
|
||||
+ <GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
+ <SubSystem>Windows</SubSystem>
|
||||
+ <OptimizeReferences>true</OptimizeReferences>
|
||||
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
+ </Link>
|
||||
+ </ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
@@ -137,6 +234,19 @@
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'">
|
||||
+ <ClCompile>
|
||||
+ <Optimization>Disabled</Optimization>
|
||||
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ </ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
@@ -147,6 +257,17 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'">
|
||||
+ <ClCompile>
|
||||
+ <AdditionalIncludeDirectories>.\;..\qrcode;..\qrcode\png;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;QRCODELIB_EXPORTS;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
+ <PrecompiledHeader>
|
||||
+ </PrecompiledHeader>
|
||||
+ <WarningLevel>Level3</WarningLevel>
|
||||
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
+ </ClCompile>
|
||||
+ </ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="qrcodelib.cpp" />
|
||||
<ClCompile Include="..\..\bitstream.c" />
|
||||
--
|
||||
2.19.0.windows.1
|
||||
|
||||
@ -36,5 +36,7 @@
|
||||
<string>Jami requires to access your microphone to make calls and record audio</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<true/>
|
||||
<key>NSAppleEventsUsageDescription</key>
|
||||
<string>Jami requires to monitor global key events for push-to-talk functionality.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
12
resources/icons/Connected_Black_24dp.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||
<path id="noun-connection-5025318" d="M18,6.3c1.2,0,2.2-1,2.2-2.1C20.1,3,19.2,2,18,2c-1.2,0-2.2,1-2.2,2.1c0,0.5,0.2,1.1,0.6,1.5
|
||||
l-3.3,3.8c-0.8-0.6-2-0.5-2.7,0.2L7.3,7.1c0.5-0.8,0.2-1.9-0.6-2.4C5.9,4.2,4.8,4.5,4.3,5.3C3.8,6.1,4,7.2,4.9,7.7
|
||||
C5.6,8.1,6.4,8,7,7.5l3.1,2.5c-0.5,0.8-0.4,1.9,0.3,2.6l-2.9,2.9c-1.1-0.7-2.5-0.4-3.2,0.7c-0.7,1.1-0.4,2.5,0.7,3.2
|
||||
c1.1,0.7,2.5,0.4,3.2-0.7c0.6-0.9,0.5-2.1-0.3-2.9l2.9-2.9c0.3,0.2,0.7,0.3,1.2,0.3c0,0,0.1,0,0.1,0l0.8,4.8
|
||||
c-1.1,0.3-1.7,1.4-1.4,2.5c0.3,1.1,1.4,1.7,2.5,1.4c1.1-0.3,1.7-1.4,1.4-2.5c-0.3-0.9-1-1.4-1.9-1.4c0,0-0.1,0-0.1,0l-0.8-4.8
|
||||
c0.4-0.1,0.7-0.3,0.9-0.6l3.6,2.7c-0.4,0.8-0.2,1.8,0.6,2.2c0.8,0.4,1.8,0.2,2.2-0.6c0.4-0.8,0.2-1.8-0.6-2.2
|
||||
c-0.6-0.4-1.4-0.3-1.9,0.2l-3.6-2.7c0.2-0.3,0.3-0.7,0.3-1.1c0-0.5-0.2-1.1-0.6-1.5l3.3-3.8C17.1,6.2,17.5,6.3,18,6.3L18,6.3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
23
resources/icons/Connecting_Black_24dp.svg
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||
<g id="noun-waiting-3611673" transform="translate(-13.64 -30.48)">
|
||||
<path id="Path_278" d="M25.9,34.5c0.5,0,0.8-0.4,0.8-0.8c0-0.5-0.4-0.8-0.8-0.8c-0.5,0-0.8,0.4-0.8,0.8c0,0.2,0.1,0.4,0.2,0.6
|
||||
C25.4,34.4,25.6,34.5,25.9,34.5z"/>
|
||||
<path id="Path_279" d="M32.7,36.9c0.4-0.4,0.4-1.1,0-1.5c-0.4-0.4-1.1-0.4-1.5,0c-0.4,0.4-0.4,1.1,0,1.5c0.2,0.2,0.5,0.3,0.8,0.3
|
||||
C32.2,37.2,32.5,37.1,32.7,36.9z"/>
|
||||
<path id="Path_280" d="M34.5,41c-0.7,0-1.2,0.5-1.2,1.2s0.5,1.2,1.2,1.2c0.7,0,1.2-0.5,1.2-1.2c0-0.3-0.1-0.6-0.3-0.8
|
||||
C35.1,41.1,34.8,41,34.5,41z"/>
|
||||
<path id="Path_281" d="M31.9,47c-0.7,0-1.3,0.6-1.3,1.3c0,0.7,0.6,1.3,1.3,1.3c0.7,0,1.3-0.6,1.3-1.3c0-0.3-0.1-0.7-0.4-0.9
|
||||
C32.6,47.1,32.3,47,31.9,47z"/>
|
||||
<path id="Path_282" d="M25.9,49.4c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.8,0,1.4-0.6,1.4-1.4c0-0.4-0.1-0.7-0.4-1
|
||||
C26.6,49.5,26.2,49.4,25.9,49.4z"/>
|
||||
<path id="Path_283" d="M18.7,47.2L18.7,47.2c-0.6,0.6-0.6,1.6,0,2.2c0.6,0.6,1.6,0.6,2.2,0c0.6-0.6,0.6-1.6,0-2.2
|
||||
c-0.3-0.3-0.7-0.5-1.1-0.5C19.4,46.7,19,46.9,18.7,47.2z"/>
|
||||
<path id="Path_284" d="M18.9,42.2c0-0.9-0.7-1.7-1.6-1.7s-1.7,0.7-1.7,1.6c0,0.9,0.7,1.7,1.6,1.7c0.4,0,0.9-0.2,1.2-0.5
|
||||
C18.8,43,18.9,42.6,18.9,42.2z"/>
|
||||
<path id="Path_285" d="M21.1,34.9c-0.7-0.3-1.5-0.1-1.9,0.6c-0.3,0.7-0.1,1.5,0.6,1.9c0.7,0.3,1.5,0.1,1.9-0.6
|
||||
c0.1-0.2,0.2-0.5,0.1-0.7C21.8,35.5,21.5,35.1,21.1,34.9z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
4
resources/icons/assignment_ind_black_24dp.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg id="assignment_ind_black_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path id="Path_311" data-name="Path 311" d="M0,0H24V24H0Z" fill="none"/>
|
||||
<path id="Path_312" data-name="Path 312" d="M19,3H14.82A2.988,2.988,0,0,0,9.18,3H5A2.006,2.006,0,0,0,3,5V19a2.006,2.006,0,0,0,2,2H19a2.006,2.006,0,0,0,2-2V5A2.006,2.006,0,0,0,19,3Zm-7-.25a.767.767,0,1,1-.55.25A.749.749,0,0,1,12,2.75ZM19,19H5V5H19ZM12,6a3,3,0,1,0,3,3A3.009,3.009,0,0,0,12,6Zm0,4a1,1,0,1,1,1-1A1,1,0,0,1,12,10ZM6,16.47V18H18V16.47c0-2.5-3.97-3.58-6-3.58S6,13.96,6,16.47ZM8.31,16A7.011,7.011,0,0,1,12,14.88,6.982,6.982,0,0,1,15.69,16Z" fill="#005699"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 666 B |
@ -1,9 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||
<path d="M20.4,2.2H8.5c-0.9,0-1.6,0.7-1.6,1.6v2.9H3.6C2.7,6.7,2,7.4,2,8.3v11.9c0,0.9,0.7,1.6,1.6,1.6h11.9c0.9,0,1.6-0.7,1.6-1.6
|
||||
v-2.9h3.3c0.9,0,1.6-0.7,1.6-1.6V3.8C22,2.9,21.3,2.2,20.4,2.2z M15.8,20.2c0,0.2-0.1,0.3-0.3,0.3H3.6c-0.2,0-0.3-0.1-0.3-0.3V8.3
|
||||
C3.3,8.2,3.4,8,3.6,8h11.9c0.2,0,0.3,0.1,0.3,0.3V20.2z M20.7,15.7c0,0.2-0.1,0.3-0.3,0.3h-3.3V8.3c0-0.9-0.7-1.6-1.6-1.6H8.2V3.8
|
||||
c0-0.2,0.1-0.3,0.3-0.3h11.9c0.2,0,0.3,0.1,0.3,0.3V15.7z"/>
|
||||
</svg>
|
||||
<svg id="content_copy_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path id="Path_305" data-name="Path 305" d="M0,0H24V24H0Z" fill="none"/>
|
||||
<path id="Path_306" data-name="Path 306" d="M16,1H4A2.006,2.006,0,0,0,2,3V17H4V3H16Zm3,4H8A2.006,2.006,0,0,0,6,7V21a2.006,2.006,0,0,0,2,2H19a2.006,2.006,0,0,0,2-2V7A2.006,2.006,0,0,0,19,5Zm0,16H8V7H19Z" fill="#005699"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 793 B After Width: | Height: | Size: 411 B |
5
resources/icons/favorite_black_24dp.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="21.5" height="20.112" viewBox="0 0 21.5 20.112">
|
||||
<g id="favorite_black_24dp" transform="translate(-1.25 -2.25)">
|
||||
<path id="Path_270" data-name="Path 270" d="M12,21.35l-1.45-1.32C5.4,15.36,2,12.28,2,8.5A5.447,5.447,0,0,1,7.5,3,5.988,5.988,0,0,1,12,5.09,5.988,5.988,0,0,1,16.5,3,5.447,5.447,0,0,1,22,8.5c0,3.78-3.4,6.86-8.55,11.54Z" fill="none" stroke="#03b9e9" stroke-width="1.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 448 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M39 38v-8.7q0-2.7-1.9-4.6-1.9-1.9-4.6-1.9H11.7l7.7 7.7-2.1 2.1L6 21.3 17.3 10l2.1 2.1-7.7 7.7h20.8q3.9 0 6.7 2.775Q42 25.35 42 29.3V38Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 216 B |
4
resources/icons/reply_black_24dp.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg id="reply_black_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path id="Path_333" data-name="Path 333" d="M0,0H24V24H0Z" fill="none"/>
|
||||
<path id="Path_334" data-name="Path 334" d="M10,9V5L3,12l7,7V14.9c5,0,8.5,1.6,11,5.1C20,15,17,10,10,9Z" fill="none" stroke="#000" stroke-linecap="round" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 364 B |
@ -1,11 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Share</title>
|
||||
<g id="Icones" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Share" fill="#000000" stroke="#000000" stroke-width="0.75">
|
||||
<g id="SHARE" transform="translate(4.000000, 2.000000)">
|
||||
<path d="M13.5,15.00005 C14.6105,15.00005 15.5,15.88955 15.5,17.00005 C15.5,18.1103 14.6105,19.00005 13.5,19.00005 C12.3895,19.00005 11.5,18.1103 11.5,17.00005 C11.5,15.88955 12.3895,15.00005 13.5,15.00005 M3,8.00005 C4.1105,8.00005 5,8.88955 5,10.00005 C5,11.11055 4.1105,12.00005 3,12.00005 C1.8895,12.00005 1,11.11055 1,10.00005 C1,8.88955 1.8895,8.00005 3,8.00005 M13.5,1.00005 C14.6105,1.00005 15.5,1.88955 15.5,3.00005 C15.5,4.11055 14.6105,5.00005 13.5,5.00005 C12.3895,5.00005 11.5,4.11055 11.5,3.00005 C11.5,1.88955 12.3895,1.00005 13.5,1.00005 M13.5,5e-05 C11.849,5e-05 10.5,1.34905 10.5,3.00005 C10.5,3.47555 10.6135,3.92755 10.8125,4.32805 L5.086,7.85155 C4.545,7.3263 3.8095,7.00005 3,7.00005 C1.349,7.00005 0,8.34905 0,10.00005 C0,11.65105 1.349,13.00005 3,13.00005 C3.81525,13.00005 4.552,12.67255 5.09375,12.14055 L10.82025,15.66405 C10.6165,16.0683 10.5,16.51805 10.5,17.00005 C10.5,18.65105 11.849,20.00005 13.5,20.00005 C15.151,20.00005 16.5,18.65105 16.5,17.00005 C16.5,15.34905 15.151,14.00005 13.5,14.00005 C12.6905,14.00005 11.955,14.3263 11.414,14.85155 L5.6875,11.32805 C5.8865,10.92755 6,10.47555 6,10.00005 C6,9.51805 5.8835,9.06855 5.67975,8.66405 L11.40625,5.14055 C11.94825,5.67255 12.68475,6.00005 13.5,6.00005 C15.151,6.00005 16.5,4.65105 16.5,3.00005 C16.5,1.34905 15.151,5e-05 13.5,5e-05" id="Fill-1"></path>
|
||||
</g>
|
||||
</g>
|
||||
<svg id="share_24dp" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||
<g id="Group_66" data-name="Group 66">
|
||||
<rect id="Rectangle_305" data-name="Rectangle 305" width="24" height="24" fill="none"/>
|
||||
</g>
|
||||
<g id="Group_68" data-name="Group 68">
|
||||
<g id="Group_67" data-name="Group 67">
|
||||
<path id="Path_302" data-name="Path 302" d="M3,11h8V3H3ZM5,5H9V9H5Z" fill="#005699"/>
|
||||
<path id="Path_303" data-name="Path 303" d="M3,21h8V13H3Zm2-6H9v4H5Z" fill="#005699"/>
|
||||
<path id="Path_304" data-name="Path 304" d="M13,3v8h8V3Zm6,6H15V5h4Z" fill="#005699"/>
|
||||
<rect id="Rectangle_306" data-name="Rectangle 306" width="2" height="2" transform="translate(19 19)" fill="#005699"/>
|
||||
<rect id="Rectangle_307" data-name="Rectangle 307" width="2" height="2" transform="translate(13 13)" fill="#005699"/>
|
||||
<rect id="Rectangle_308" data-name="Rectangle 308" width="2" height="2" transform="translate(15 15)" fill="#005699"/>
|
||||
<rect id="Rectangle_309" data-name="Rectangle 309" width="2" height="2" transform="translate(13 17)" fill="#005699"/>
|
||||
<rect id="Rectangle_310" data-name="Rectangle 310" width="2" height="2" transform="translate(15 19)" fill="#005699"/>
|
||||
<rect id="Rectangle_311" data-name="Rectangle 311" width="2" height="2" transform="translate(17 17)" fill="#005699"/>
|
||||
<rect id="Rectangle_312" data-name="Rectangle 312" width="2" height="2" transform="translate(17 13)" fill="#005699"/>
|
||||
<rect id="Rectangle_313" data-name="Rectangle 313" width="2" height="2" transform="translate(19 15)" fill="#005699"/>
|
||||
</g>
|
||||
</svg>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.6 KiB |
BIN
resources/images/Background_Don_dark.jpg
Normal file
|
After Width: | Height: | Size: 779 KiB |
BIN
resources/images/Background_Don_white.jpg
Normal file
|
After Width: | Height: | Size: 653 KiB |
@ -33,6 +33,41 @@
|
||||
extern const QString defaultDownloadPath;
|
||||
|
||||
// clang-format off
|
||||
#ifdef APPSTORE
|
||||
#define KEYS \
|
||||
X(MinimizeOnClose, false) \
|
||||
X(DownloadPath, defaultDownloadPath) \
|
||||
X(ScreenshotPath, {}) \
|
||||
X(EnableNotifications, true) \
|
||||
X(EnableTypingIndicator, true) \
|
||||
X(EnableReadReceipt, true) \
|
||||
X(AcceptTransferBelow, 20) \
|
||||
X(AutoAcceptFiles, true) \
|
||||
X(DisplayHyperlinkPreviews, true) \
|
||||
X(AppTheme, "System") \
|
||||
X(BaseZoom, 1.0) \
|
||||
X(ParticipantsSide, false) \
|
||||
X(HideSelf, true) \
|
||||
X(HideSpectators, false) \
|
||||
X(AutoUpdate, true) \
|
||||
X(PluginAutoUpdate, false) \
|
||||
X(StartMinimized, false) \
|
||||
X(ShowChatviewHorizontally, true) \
|
||||
X(NeverShowMeAgain, false) \
|
||||
X(WindowGeometry, QRectF(qQNaN(), qQNaN(), 0., 0.)) \
|
||||
X(WindowState, QWindow::AutomaticVisibility) \
|
||||
X(EnableExperimentalSwarm, false) \
|
||||
X(LANG, "SYSTEM") \
|
||||
X(PluginStoreEndpoint, "https://plugins.jami.net") \
|
||||
X(PositionShareDuration, 15) \
|
||||
X(PositionShareLimit, true) \
|
||||
X(FlipSelf, true) \
|
||||
X(ShowMardownOption, false) \
|
||||
X(ChatViewEnterIsNewLine, false) \
|
||||
X(ShowSendOption, false) \
|
||||
X(EnablePtt, false) \
|
||||
X(pttKey, 36)
|
||||
#else
|
||||
#define KEYS \
|
||||
X(MinimizeOnClose, false) \
|
||||
X(DownloadPath, defaultDownloadPath) \
|
||||
@ -64,7 +99,13 @@ extern const QString defaultDownloadPath;
|
||||
X(ShowMardownOption, false) \
|
||||
X(ChatViewEnterIsNewLine, false) \
|
||||
X(ShowSendOption, false) \
|
||||
X(DonateVisibleDate, "2999-02-01 05:00")
|
||||
X(DonationVisibleDate, "2023-11-01 05:00") \
|
||||
X(IsDonationVisible, true) \
|
||||
X(DonationEndDate, "2024-01-01 00:00") \
|
||||
X(EnablePtt, false) \
|
||||
X(pttKey, 36)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A class to expose settings keys in both c++ and QML.
|
||||
* Note: this is using a non-constructable class instead of a
|
||||
|
||||
@ -195,8 +195,28 @@ AvAdapter::shareFile(const QString& filePath)
|
||||
auto callId = lrcInstance_->getCurrentCallId();
|
||||
if (!callId.isEmpty()) {
|
||||
muteCamera_ = !isCapturing();
|
||||
lrcInstance_->getCurrentCallModel()
|
||||
->addMedia(callId, filePath, lrc::api::CallModel::MediaRequestType::FILESHARING);
|
||||
auto resource = QString("%1%2%3")
|
||||
.arg(libjami::Media::VideoProtocolPrefix::FILE)
|
||||
.arg(libjami::Media::VideoProtocolPrefix::SEPARATOR)
|
||||
.arg(QUrl(filePath).toLocalFile());
|
||||
|
||||
Utils::oneShotConnect(&lrcInstance_->avModel(),
|
||||
&lrc::api::AVModel::fileOpened,
|
||||
this,
|
||||
[this, callId, filePath, resource](bool hasAudio, bool hasVideo) {
|
||||
// TODO: allow audio only sharing
|
||||
if (hasVideo) { // only start sharing if video is available
|
||||
lrcInstance_->avModel().pausePlayer(resource, false);
|
||||
lrcInstance_->avModel().setAutoRestart(resource, true);
|
||||
lrcInstance_->getCurrentCallModel()
|
||||
->addMedia(callId, filePath, lrc::api::CallModel::MediaRequestType::FILESHARING, false, hasAudio);
|
||||
} else {
|
||||
// Close media player because we are not going to start sharing
|
||||
lrcInstance_->avModel().closeMediaPlayer(resource);
|
||||
}
|
||||
});
|
||||
|
||||
lrcInstance_->avModel().createMediaPlayer(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,14 +320,16 @@ AvAdapter::stopSharing(const QString& source)
|
||||
->removeMedia(callId,
|
||||
libjami::Media::Details::MEDIA_TYPE_VIDEO,
|
||||
libjami::Media::VideoProtocolPrefix::DISPLAY,
|
||||
muteCamera_);
|
||||
muteCamera_,
|
||||
true);
|
||||
} else {
|
||||
qDebug() << "Stopping file: " << source;
|
||||
lrcInstance_->getCurrentCallModel()
|
||||
->removeMedia(callId,
|
||||
libjami::Media::Details::MEDIA_TYPE_VIDEO,
|
||||
libjami::Media::VideoProtocolPrefix::FILE,
|
||||
muteCamera_);
|
||||
muteCamera_,
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
* Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Author: Capucine Berthet <capucine.berthet@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -25,29 +26,36 @@
|
||||
#include "calladapter.h"
|
||||
|
||||
#include "systemtray.h"
|
||||
#include "utils.h"
|
||||
#include "qmlregister.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QJsonObject>
|
||||
#include "appsettingsmanager.h"
|
||||
|
||||
#include <api/callmodel.h>
|
||||
#include <api/callparticipantsmodel.h>
|
||||
|
||||
#include <media_const.h>
|
||||
|
||||
CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent)
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QJsonObject>
|
||||
|
||||
CallAdapter::CallAdapter(AppSettingsManager* settingsManager,
|
||||
SystemTray* systemTray,
|
||||
LRCInstance* instance,
|
||||
QObject* parent)
|
||||
: QmlAdapterBase(instance, parent)
|
||||
, systemTray_(systemTray)
|
||||
, callInformationListModel_(std::make_unique<CallInformationListModel>())
|
||||
, listener_(new PTTListener(settingsManager, this))
|
||||
{
|
||||
// Expose the Push-to-talk listener to QML as a singleton
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, listener_, "PttListener");
|
||||
|
||||
set_callInformationList(QVariant::fromValue(callInformationListModel_.get()));
|
||||
|
||||
timer = new QTimer(this);
|
||||
connect(timer, &QTimer::timeout, this, &CallAdapter::updateAdvancedInformation);
|
||||
|
||||
overlayModel_.reset(new CallOverlayModel(lrcInstance_, this));
|
||||
overlayModel_.reset(new CallOverlayModel(lrcInstance_, listener_, this));
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS, overlayModel_.get(), "CallOverlayModel");
|
||||
|
||||
accountId_ = lrcInstance_->get_currentAccountId();
|
||||
@ -97,6 +105,65 @@ CallAdapter::CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject*
|
||||
&LRCInstance::selectedConvUidChanged,
|
||||
this,
|
||||
&CallAdapter::saveConferenceSubcalls);
|
||||
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
connectPtt();
|
||||
#endif
|
||||
}
|
||||
|
||||
CallAdapter::~CallAdapter()
|
||||
{
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
disconnectPtt();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::connectPtt()
|
||||
{
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
if (listener_->getPttState()) {
|
||||
QObject::connect(
|
||||
listener_,
|
||||
&PTTListener::pttKeyPressed,
|
||||
this,
|
||||
[this]() {
|
||||
const auto callId
|
||||
= lrcInstance_->getCallIdForConversationUid(lrcInstance_->get_selectedConvUid(),
|
||||
accountId_);
|
||||
try {
|
||||
isMicrophoneMuted_ = isMuted(callId);
|
||||
if (isMicrophoneMuted_)
|
||||
muteAudioToggle();
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
|
||||
QObject::connect(
|
||||
listener_,
|
||||
&PTTListener::pttKeyReleased,
|
||||
this,
|
||||
[this]() {
|
||||
if (isMicrophoneMuted_) {
|
||||
muteAudioToggle();
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::disconnectPtt()
|
||||
{
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
if (listener_->getPttState()) {
|
||||
QObject::disconnect(listener_, &PTTListener::pttKeyPressed, this, nullptr);
|
||||
QObject::disconnect(listener_, &PTTListener::pttKeyReleased, this, nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -172,6 +239,12 @@ CallAdapter::onCallStarted(const QString& callId)
|
||||
// update call Information list by adding the new information related to the callId
|
||||
callInformationListModel_->addElement(
|
||||
qMakePair(callId, callModel->advancedInformationForCallId(callId)));
|
||||
if (listener_->getPttState()) {
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
listener_->startListening();
|
||||
toMute += callId;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -181,6 +254,10 @@ CallAdapter::onCallEnded(const QString& callId)
|
||||
return;
|
||||
// update call Information list by removing information related to the callId
|
||||
callInformationListModel_->removeElement(callId);
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
if (listener_->getPttState() && !hasCall_)
|
||||
listener_->stopListening();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -271,6 +348,15 @@ CallAdapter::onCallStatusChanged(const QString& callId, int code)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::onCallInfosChanged(const QString& accountId, const QString& callId)
|
||||
{
|
||||
Q_UNUSED(accountId)
|
||||
auto mute = toMute.remove(callId);
|
||||
if (mute && listener_->getPttState())
|
||||
muteAudioToggle();
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::onCallAddedToConference(const QString& callId, const QString& confId)
|
||||
{
|
||||
@ -494,6 +580,12 @@ CallAdapter::connectCallModel(const QString& accountId)
|
||||
QOverload<const QString&, int>::of(&CallAdapter::onCallStatusChanged),
|
||||
Qt::UniqueConnection);
|
||||
|
||||
connect(accInfo.callModel.get(),
|
||||
&CallModel::callInfosChanged,
|
||||
this,
|
||||
&CallAdapter::onCallInfosChanged,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
connect(accInfo.callModel.get(),
|
||||
&CallModel::callAddedToConference,
|
||||
this,
|
||||
@ -816,6 +908,23 @@ CallAdapter::holdThisCallToggle()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CallAdapter::isMuted(const QString& callId)
|
||||
{
|
||||
if (!(callId.isEmpty() || !lrcInstance_->getCurrentCallModel()->hasCall(callId))) {
|
||||
auto* callModel = lrcInstance_->getCurrentCallModel();
|
||||
if (callModel->hasCall(callId)) {
|
||||
const auto callInfo = lrcInstance_->getCurrentCallModel()->getCall(callId);
|
||||
auto mute = false;
|
||||
for (const auto& m : callInfo.mediaList)
|
||||
if (m[libjami::Media::MediaAttributeKey::LABEL] == "audio_0")
|
||||
mute = m[libjami::Media::MediaAttributeKey::MUTED] == TRUE_STR;
|
||||
return mute;
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("CallAdapter::isMuted: callId is empty or call does not exist");
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::muteAudioToggle()
|
||||
{
|
||||
@ -825,13 +934,10 @@ CallAdapter::muteAudioToggle()
|
||||
return;
|
||||
}
|
||||
auto* callModel = lrcInstance_->getCurrentCallModel();
|
||||
if (callModel->hasCall(callId)) {
|
||||
const auto callInfo = lrcInstance_->getCurrentCallModel()->getCall(callId);
|
||||
auto mute = false;
|
||||
for (const auto& m : callInfo.mediaList)
|
||||
if (m[libjami::Media::MediaAttributeKey::LABEL] == "audio_0")
|
||||
mute = m[libjami::Media::MediaAttributeKey::MUTED] == FALSE_STR;
|
||||
callModel->muteMedia(callId, "audio_0", mute);
|
||||
try {
|
||||
callModel->muteMedia(callId, "audio_0", !isMuted(callId));
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
@ -877,7 +983,8 @@ CallAdapter::muteCameraToggle()
|
||||
callModel->removeMedia(callId,
|
||||
libjami::Media::Details::MEDIA_TYPE_VIDEO,
|
||||
libjami::Media::VideoProtocolPrefix::CAMERA,
|
||||
mute);
|
||||
mute,
|
||||
false);
|
||||
else
|
||||
callModel->addMedia(callId,
|
||||
lrcInstance_->avModel().getCurrentVideoCaptureDevice(),
|
||||
|
||||
@ -25,6 +25,10 @@
|
||||
#include "screensaver.h"
|
||||
#include "calloverlaymodel.h"
|
||||
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
#include "pttlistener.h"
|
||||
#endif
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
@ -33,6 +37,7 @@
|
||||
#include "callInformationListModel.h"
|
||||
|
||||
class SystemTray;
|
||||
class AppSettingsManager;
|
||||
|
||||
class CallAdapter final : public QmlAdapterBase
|
||||
{
|
||||
@ -45,8 +50,11 @@ public:
|
||||
enum MuteStates { UNMUTED, LOCAL_MUTED, MODERATOR_MUTED, BOTH_MUTED };
|
||||
Q_ENUM(MuteStates)
|
||||
|
||||
explicit CallAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent = nullptr);
|
||||
~CallAdapter() = default;
|
||||
explicit CallAdapter(AppSettingsManager* settingsManager,
|
||||
SystemTray* systemTray,
|
||||
LRCInstance* instance,
|
||||
QObject* parent = nullptr);
|
||||
~CallAdapter();
|
||||
|
||||
public:
|
||||
Q_INVOKABLE void startTimerInformation();
|
||||
@ -76,6 +84,9 @@ public:
|
||||
Q_INVOKABLE void holdThisCallToggle();
|
||||
Q_INVOKABLE void recordThisCallToggle();
|
||||
Q_INVOKABLE void muteAudioToggle();
|
||||
Q_INVOKABLE bool isMuted(const QString& callId);
|
||||
Q_INVOKABLE void connectPtt();
|
||||
Q_INVOKABLE void disconnectPtt();
|
||||
Q_INVOKABLE void muteCameraToggle();
|
||||
Q_INVOKABLE bool isRecordingThisCall();
|
||||
Q_INVOKABLE void muteParticipant(const QString& accountUri,
|
||||
@ -109,6 +120,7 @@ public Q_SLOTS:
|
||||
void onCallAddedToConference(const QString& callId, const QString& confId);
|
||||
void onCallStarted(const QString& callId);
|
||||
void onCallEnded(const QString& callId);
|
||||
void onCallInfosChanged(const QString& accountId, const QString& callId);
|
||||
|
||||
private:
|
||||
void showNotification(const QString& accountId, const QString& convUid);
|
||||
@ -121,6 +133,9 @@ private:
|
||||
SystemTray* systemTray_;
|
||||
QScopedPointer<CallOverlayModel> overlayModel_;
|
||||
VectorString currentConfSubcalls_;
|
||||
|
||||
std::unique_ptr<CallInformationListModel> callInformationListModel_;
|
||||
|
||||
PTTListener* listener_;
|
||||
bool isMicrophoneMuted_ = true;
|
||||
QSet<QString> toMute;
|
||||
};
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QQuickWindow>
|
||||
#include <QKeyEvent>
|
||||
|
||||
IndexRangeFilterProxyModel::IndexRangeFilterProxyModel(QAbstractListModel* parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
@ -74,10 +75,10 @@ PendingConferenceesListModel::data(const QModelIndex& index, int role) const
|
||||
using namespace PendingConferences;
|
||||
|
||||
// WARNING: not swarm ready
|
||||
lrc::api::call::Status callStatus;
|
||||
QString pendingConferenceeCallId;
|
||||
QString pendingConferenceeContactUri;
|
||||
ContactModel* contactModel {nullptr};
|
||||
lrc::api::call::Status callStatus;
|
||||
try {
|
||||
auto callModel = lrcInstance_->getCurrentCallModel();
|
||||
auto currentPendingConferenceeInfo = callModel->getPendingConferencees().at(index.row());
|
||||
@ -268,7 +269,7 @@ CallControlListModel::clearData()
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
|
||||
CallOverlayModel::CallOverlayModel(LRCInstance* instance, PTTListener* listener, QObject* parent)
|
||||
: QObject(parent)
|
||||
, lrcInstance_(instance)
|
||||
, primaryModel_(new CallControlListModel(this))
|
||||
@ -283,6 +284,10 @@ CallOverlayModel::CallOverlayModel(LRCInstance* instance, QObject* parent)
|
||||
this,
|
||||
&CallOverlayModel::setControlRanges);
|
||||
overflowVisibleModel_->setFilterRole(CallControl::Role::UrgentCount);
|
||||
|
||||
#ifndef HAVE_GLOBAL_PTT
|
||||
listener_ = listener;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -386,6 +391,19 @@ CallOverlayModel::eventFilter(QObject* object, QEvent* event)
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef HAVE_GLOBAL_PTT
|
||||
else if (event->type() == QEvent::KeyPress && listener_->getPttState()) {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == listener_->getCurrentKey() && !keyEvent->isAutoRepeat()) {
|
||||
Q_EMIT pttKeyPressed();
|
||||
}
|
||||
} else if (event->type() == QEvent::KeyRelease && listener_->getPttState()) {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == listener_->getCurrentKey() && !keyEvent->isAutoRepeat()) {
|
||||
Q_EMIT pttKeyReleased();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return QObject::eventFilter(object, event);
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,9 @@
|
||||
|
||||
#include "lrcinstance.h"
|
||||
#include "qtutils.h"
|
||||
#include "mainapplication.h"
|
||||
|
||||
#include "pttlistener.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QObject>
|
||||
@ -36,7 +39,7 @@
|
||||
|
||||
namespace CallControl {
|
||||
Q_NAMESPACE
|
||||
enum Role { ItemAction = Qt::UserRole + 1, UrgentCount, Enabled};
|
||||
enum Role { ItemAction = Qt::UserRole + 1, UrgentCount, Enabled };
|
||||
Q_ENUM_NS(Role)
|
||||
|
||||
struct Item
|
||||
@ -121,7 +124,7 @@ class CallOverlayModel : public QObject
|
||||
QML_PROPERTY(int, overflowIndex)
|
||||
|
||||
public:
|
||||
CallOverlayModel(LRCInstance* instance, QObject* parent = nullptr);
|
||||
CallOverlayModel(LRCInstance* instance, PTTListener* listener, QObject* parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void addPrimaryControl(const QVariant& action, bool enabled);
|
||||
Q_INVOKABLE void addSecondaryControl(const QVariant& action, bool enabled);
|
||||
@ -142,6 +145,8 @@ public:
|
||||
|
||||
Q_SIGNALS:
|
||||
void mouseMoved(QQuickItem* item);
|
||||
void pttKeyPressed();
|
||||
void pttKeyReleased();
|
||||
|
||||
private Q_SLOTS:
|
||||
void setControlRanges();
|
||||
@ -157,4 +162,8 @@ private:
|
||||
PendingConferenceesListModel* pendingConferenceesModel_;
|
||||
|
||||
QList<QQuickItem*> watchedItems_;
|
||||
|
||||
#ifndef HAVE_GLOBAL_PTT
|
||||
PTTListener* listener_ {nullptr};
|
||||
#endif
|
||||
};
|
||||
|
||||
123
src/app/commoncomponents/ChangePttKeyPopup.qml
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
|
||||
BaseModalDialog {
|
||||
id: pttPage
|
||||
|
||||
property string bestName: ""
|
||||
property string accountId: ""
|
||||
property int pressedKey: Qt.Key_unknown
|
||||
|
||||
signal accepted
|
||||
signal choiceMade(int chosenKey)
|
||||
|
||||
title: JamiStrings.changeShortcut
|
||||
|
||||
popupContent: ColumnLayout {
|
||||
id: deleteAccountContentColumnLayout
|
||||
anchors.centerIn: parent
|
||||
spacing: JamiTheme.preferredMarginSize
|
||||
|
||||
Component.onCompleted: keyItem.forceActiveFocus()
|
||||
Label {
|
||||
id: instructionLabel
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: JamiTheme.preferredDialogWidth - 4*JamiTheme.preferredMarginSize
|
||||
color: JamiTheme.textColor
|
||||
text: JamiStrings.assignmentIndication
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
font.kerning: true
|
||||
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
|
||||
Label {
|
||||
id: keyLabel
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
color: JamiTheme.blackColor
|
||||
wrapMode: Text.WordWrap
|
||||
text: ""
|
||||
font.pointSize: JamiTheme.settingsFontSize
|
||||
font.kerning: true
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
background: Rectangle {
|
||||
id: backgroundRect
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
width: keyLabel.width + 2 * JamiTheme.preferredMarginSize
|
||||
height: keyLabel.height + JamiTheme.preferredMarginSize
|
||||
color: JamiTheme.lightGrey_
|
||||
border.color: JamiTheme.darkGreyColor
|
||||
radius: 4
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MaterialButton {
|
||||
id: btnAssign
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
preferredWidth: JamiTheme.preferredFieldWidth / 2 - 8
|
||||
buttontextHeightMargin: JamiTheme.buttontextHeightMargin
|
||||
|
||||
color: JamiTheme.buttonTintedBlack
|
||||
hoveredColor: JamiTheme.buttonTintedBlackHovered
|
||||
pressedColor: JamiTheme.buttonTintedBlackPressed
|
||||
secondary: true
|
||||
|
||||
text: JamiStrings.assign
|
||||
autoAccelerator: true
|
||||
|
||||
onClicked: {
|
||||
if (!(pressedKey === Qt.Key_unknown)){
|
||||
PttListener.setPttKey(pressedKey);
|
||||
choiceMade(pressedKey);
|
||||
}
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: keyItem
|
||||
|
||||
Keys.onPressed: (event)=>{
|
||||
keyLabel.text = PttListener.keyToString(event.key);
|
||||
pressedKey = event.key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -52,7 +52,7 @@ Item {
|
||||
|
||||
RoundedBorderRectangle {
|
||||
id: leftRect
|
||||
fillColor: jamiId.backgroundColor
|
||||
fillColor: JamiTheme.jamiIdBackgroundColor
|
||||
Layout.preferredWidth: childrenRect.width
|
||||
Layout.maximumWidth: jamiId.width - rightRect.width
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
@ -73,7 +73,7 @@ Item {
|
||||
containerWidth: 40
|
||||
Layout.leftMargin: JamiTheme.pushButtonMargins
|
||||
source: JamiResources.jami_id_logo_svg
|
||||
color: jamiId.contentColor
|
||||
color: JamiTheme.tintedBlue
|
||||
}
|
||||
|
||||
UsernameTextEdit {
|
||||
@ -81,7 +81,7 @@ Item {
|
||||
visible: !readOnly
|
||||
Layout.preferredHeight: 40
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
textColor: jamiId.contentColor
|
||||
textColor: JamiTheme.tintedBlue
|
||||
fontPixelSize: staticText.length > 16 || dynamicText.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
|
||||
editMode: false
|
||||
isPersistent: false
|
||||
@ -107,7 +107,7 @@ Item {
|
||||
Layout.rightMargin: JamiTheme.pushButtonMargins
|
||||
Layout.maximumWidth: leftRect.width - 50
|
||||
elide: Text.ElideRight
|
||||
color: jamiId.contentColor
|
||||
color: JamiTheme.tintedBlue
|
||||
font.pixelSize : text.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
|
||||
property string registeredName: CurrentAccount.registeredName
|
||||
property string infohash: CurrentAccount.uri
|
||||
@ -118,7 +118,7 @@ Item {
|
||||
|
||||
RoundedBorderRectangle {
|
||||
id: rightRect
|
||||
fillColor: jamiId.backgroundColor
|
||||
fillColor: JamiTheme.jamiIdBackgroundColor
|
||||
Layout.preferredWidth: childrenRect.width + 2 * JamiTheme.pushButtonMargins
|
||||
|
||||
Layout.preferredHeight: leftRect.height
|
||||
@ -142,8 +142,8 @@ Item {
|
||||
id: btnEdit
|
||||
anchors.leftMargin: JamiTheme.pushButtonMargins
|
||||
visible: CurrentAccount.registeredName === ""
|
||||
border.color: enabled ? jamiId.contentColor : JamiTheme.buttonTintedBlack
|
||||
imageColor: enabled ? jamiId.contentColor : JamiTheme.buttonTintedBlack
|
||||
imageColor: enabled ? JamiTheme.tintedBlue : JamiTheme.buttonTintedBlack
|
||||
border.color: usernameTextEdit.editMode ? jamiId.contentColor : "transparent"
|
||||
enabled: {
|
||||
if (!usernameTextEdit.editMode)
|
||||
return true;
|
||||
@ -157,7 +157,7 @@ Item {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
source: usernameTextEdit.editMode ? JamiResources.check_black_24dp_svg : JamiResources.round_edit_24dp_svg
|
||||
source: usernameTextEdit.editMode ? JamiResources.check_black_24dp_svg : JamiResources.assignment_ind_black_24dp_svg
|
||||
toolTipText: JamiStrings.chooseUsername
|
||||
onClicked: {
|
||||
if (usernameTextEdit.readOnly) {
|
||||
@ -167,6 +167,19 @@ Item {
|
||||
usernameTextEdit.accepted();
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 10
|
||||
height: 10
|
||||
visible: !usernameTextEdit.editMode
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
radius: width / 2
|
||||
color: JamiTheme.redDotColor
|
||||
border.color: JamiTheme.jamiIdBackgroundColor
|
||||
border.width: 2
|
||||
}
|
||||
}
|
||||
|
||||
JamiIdControlButton {
|
||||
@ -188,7 +201,7 @@ Item {
|
||||
|
||||
JamiIdControlButton {
|
||||
id: btnId
|
||||
source: JamiResources.key_black_24dp_svg
|
||||
source: JamiResources.outline_info_24dp_svg
|
||||
visible: CurrentAccount.registeredName !== ""
|
||||
border.color: "transparent"
|
||||
toolTipText: JamiStrings.identifierURI
|
||||
@ -217,7 +230,7 @@ Item {
|
||||
imageContainerWidth: JamiTheme.pushButtonSize
|
||||
imageContainerHeight: JamiTheme.pushButtonSize
|
||||
border.color: jamiId.contentColor
|
||||
imageColor: jamiId.contentColor
|
||||
imageColor: JamiTheme.tintedBlue
|
||||
duration: 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,6 +68,7 @@ SplitView {
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
visible: !isSinglePane
|
||||
implicitWidth: JamiTheme.splitViewHandlePreferredWidth
|
||||
implicitHeight: root.height
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
|
||||
@ -35,8 +35,10 @@ ContextMenuAutoLoader {
|
||||
GeneralMenuItem {
|
||||
id: copy
|
||||
|
||||
canTrigger: lineEditObj.selectedText.length
|
||||
canTrigger: true
|
||||
isActif: lineEditObj.selectedText.length
|
||||
itemName: JamiStrings.copy
|
||||
hasIcon: false
|
||||
onClicked: {
|
||||
lineEditObj.copy();
|
||||
}
|
||||
@ -44,9 +46,10 @@ ContextMenuAutoLoader {
|
||||
GeneralMenuItem {
|
||||
id: cut
|
||||
|
||||
canTrigger: lineEditObj.selectedText.length && !selectOnly
|
||||
canTrigger: true
|
||||
isActif: lineEditObj.selectedText.length && !selectOnly
|
||||
itemName: JamiStrings.cut
|
||||
|
||||
hasIcon: false
|
||||
onClicked: {
|
||||
lineEditObj.cut();
|
||||
}
|
||||
@ -56,6 +59,7 @@ ContextMenuAutoLoader {
|
||||
|
||||
canTrigger: !selectOnly
|
||||
itemName: JamiStrings.paste
|
||||
hasIcon: false
|
||||
onClicked: {
|
||||
if (customizePaste)
|
||||
root.contextMenuRequirePaste();
|
||||
@ -76,10 +80,6 @@ ContextMenuAutoLoader {
|
||||
lineEditObj.select(selectionStart, selectionEnd);
|
||||
}
|
||||
|
||||
contextMenuItemPreferredHeight: JamiTheme.lineEditContextMenuItemsHeight
|
||||
contextMenuItemPreferredWidth: JamiTheme.lineEditContextMenuItemsWidth
|
||||
contextMenuSeparatorPreferredHeight: JamiTheme.lineEditContextMenuSeparatorsHeight
|
||||
|
||||
Connections {
|
||||
target: root.item
|
||||
enabled: root.status === Loader.Ready
|
||||
|
||||
@ -36,6 +36,7 @@ TextField {
|
||||
}
|
||||
|
||||
signal keyPressed
|
||||
signal rejected
|
||||
|
||||
property bool inputIsValid: true
|
||||
|
||||
@ -87,6 +88,9 @@ TextField {
|
||||
root.accepted();
|
||||
}
|
||||
event.accepted = true;
|
||||
} else if (event.key === Qt.Key_Escape) {
|
||||
root.focus = false;
|
||||
root.rejected();
|
||||
} else {
|
||||
root.keyPressed();
|
||||
}
|
||||
|
||||
@ -1,309 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
|
||||
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Layouts
|
||||
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
|
||||
Popup {
|
||||
id: root
|
||||
|
||||
width: emojiColumn.width + JamiTheme.emojiMargins
|
||||
height: emojiColumn.height + JamiTheme.emojiMargins
|
||||
padding: 0
|
||||
background.visible: false
|
||||
|
||||
required property var emojiReactions
|
||||
property var emojiReplied: emojiReactions.ownEmojis
|
||||
|
||||
required property string msgId
|
||||
required property string msgBody
|
||||
required property bool isOutgoing
|
||||
required property int type
|
||||
required property string transferName
|
||||
required property Item msgBubble
|
||||
required property ListView listView
|
||||
|
||||
property string transferId: msgId
|
||||
property string location: msgBody
|
||||
property bool closeWithoutAnimation: false
|
||||
property var emojiPicker
|
||||
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
function xPositionProvider(width) {
|
||||
// Use the width at function scope to retrigger property evaluation.
|
||||
const listViewWidth = listView.width
|
||||
if (isOutgoing) {
|
||||
const leftMargin = msgBubble.mapToItem(listView, 0, 0).x
|
||||
return width > leftMargin ? -leftMargin : -width
|
||||
} else {
|
||||
const rightMargin = listViewWidth - (msgBubble.x + msgBubble.width)
|
||||
return width > rightMargin ? msgBubble.width - width : msgBubble.width
|
||||
}
|
||||
}
|
||||
function yPositionProvider(height) {
|
||||
const topOffset = msgBubble.mapToItem(listView, 0, 0).y
|
||||
if (topOffset < 0) return -topOffset
|
||||
const bottomOffset = topOffset + height - listView.height
|
||||
if (bottomOffset > 0) return -bottomOffset
|
||||
return 0
|
||||
}
|
||||
x: xPositionProvider(width)
|
||||
y: yPositionProvider(height)
|
||||
|
||||
signal addMoreEmoji
|
||||
onAddMoreEmoji: {
|
||||
JamiQmlUtils.updateMessageBarButtonsPoints()
|
||||
openEmojiPicker()
|
||||
}
|
||||
|
||||
function openEmojiPicker() {
|
||||
var component = WITH_WEBENGINE ?
|
||||
Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml") :
|
||||
Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
|
||||
emojiPicker = component.createObject(root.parent, { listView: listView })
|
||||
emojiPicker.emojiIsPicked.connect(function(content) {
|
||||
if (emojiReplied.includes(content)) {
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId)
|
||||
} else {
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId)
|
||||
}
|
||||
})
|
||||
if (emojiPicker !== null) {
|
||||
root.opacity = 0
|
||||
emojiPicker.closed.connect(() => close())
|
||||
emojiPicker.x = xPositionProvider(JamiTheme.emojiPickerWidth)
|
||||
emojiPicker.y = yPositionProvider(JamiTheme.emojiPickerHeight)
|
||||
emojiPicker.open()
|
||||
} else {
|
||||
console.log("Error creating emojiPicker from message options popup");
|
||||
}
|
||||
}
|
||||
|
||||
// Close the picker when listView vertical properties change.
|
||||
property real listViewHeight: listView.height
|
||||
onListViewHeightChanged: close()
|
||||
property bool isScrolling: listView.verticalScrollBar.active
|
||||
onIsScrollingChanged: close()
|
||||
|
||||
onOpened: root.closeWithoutAnimation = false
|
||||
onClosed: if (emojiPicker) emojiPicker.closeEmojiPicker()
|
||||
|
||||
function getModel() {
|
||||
const defaultModel = ["👍", "👎", "😂"]
|
||||
const reactedEmojis = Array.isArray(emojiReplied) ? emojiReplied.slice(0, defaultModel.length) : []
|
||||
const uniqueEmojis = Array.from(new Set(reactedEmojis))
|
||||
const missingEmojis = defaultModel.filter(emoji => !uniqueEmojis.includes(emoji))
|
||||
return uniqueEmojis.concat(missingEmojis)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: bubble
|
||||
|
||||
color: JamiTheme.chatviewBgColor
|
||||
anchors.fill: parent
|
||||
radius: JamiTheme.modalPopupRadius
|
||||
|
||||
ColumnLayout {
|
||||
id: emojiColumn
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
RowLayout {
|
||||
id: emojiRow
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
Repeater {
|
||||
model: root.getModel()
|
||||
|
||||
delegate: Button {
|
||||
id: emojiButton
|
||||
|
||||
height: 50
|
||||
width: 50
|
||||
text: modelData
|
||||
font.pointSize: JamiTheme.emojiBubbleSize
|
||||
|
||||
Text {
|
||||
visible: emojiButton.hovered
|
||||
anchors.centerIn: parent
|
||||
text: modelData
|
||||
font.pointSize: JamiTheme.emojiBubbleSizeBig
|
||||
z: 1
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
opacity: emojiReplied ? (emojiReplied.includes(modelData) ? 1 : 0) : 0
|
||||
color: JamiTheme.emojiReactPushButtonColor
|
||||
radius: 10
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (emojiReplied.includes(modelData))
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id,text,msgId)
|
||||
else
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id,text,msgId)
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
PushButton {
|
||||
toolTipText: JamiStrings.moreEmojis
|
||||
source: JamiResources.add_reaction_svg
|
||||
normalColor: JamiTheme.emojiReactBubbleBgColor
|
||||
imageColor: JamiTheme.emojiReactPushButtonColor
|
||||
visible: WITH_WEBENGINE
|
||||
onClicked: {
|
||||
root.closeWithoutAnimation = true
|
||||
root.addMoreEmoji()
|
||||
//close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.margins: 5
|
||||
color: JamiTheme.timestampColor
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
radius: width * 0.5
|
||||
opacity: 0.6
|
||||
}
|
||||
|
||||
MessageOptionButton {
|
||||
textButton: JamiStrings.copy
|
||||
iconSource: JamiResources.copy_svg
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 5
|
||||
onClicked: {
|
||||
UtilsAdapter.setClipboardText(msgBody)
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
MessageOptionButton {
|
||||
visible: type === Interaction.Type.DATA_TRANSFER
|
||||
textButton: JamiStrings.saveFile
|
||||
iconSource: JamiResources.save_file_svg
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 5
|
||||
onClicked: {
|
||||
MessagesAdapter.copyToDownloads(root.transferId, root.transferName)
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
MessageOptionButton {
|
||||
visible: type === Interaction.Type.DATA_TRANSFER
|
||||
textButton: JamiStrings.openLocation
|
||||
iconSource: JamiResources.round_folder_24dp_svg
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 5
|
||||
onClicked: {
|
||||
MessagesAdapter.openDirectory(root.location)
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
MessageOptionButton {
|
||||
visible: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
|
||||
textButton: JamiStrings.removeLocally
|
||||
iconSource: JamiResources.trash_black_24dp_svg
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 5
|
||||
onClicked: {
|
||||
MessagesAdapter.removeFile(msgId, root.location)
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
MessageOptionButton {
|
||||
id: buttonEdit
|
||||
|
||||
visible: root.isOutgoing && type === Interaction.Type.TEXT
|
||||
textButton: JamiStrings.editMessage
|
||||
iconSource: JamiResources.edit_svg
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 5
|
||||
|
||||
onClicked: {
|
||||
MessagesAdapter.replyToId = ""
|
||||
MessagesAdapter.editId = root.msgId
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
MessageOptionButton {
|
||||
visible: root.isOutgoing && type === Interaction.Type.TEXT
|
||||
textButton: JamiStrings.deleteMessage
|
||||
iconSource: JamiResources.delete_svg
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 5
|
||||
onClicked: {
|
||||
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId)
|
||||
close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Overlay.modal: Rectangle {
|
||||
color: JamiTheme.transparentColor
|
||||
// Color animation for overlay when pop up is shown.
|
||||
ColorAnimation on color {
|
||||
to: JamiTheme.popupOverlayColor
|
||||
duration: 500
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
z: -1
|
||||
|
||||
width: bubble.width
|
||||
height: bubble.height
|
||||
horizontalOffset: 3.0
|
||||
verticalOffset: 3.0
|
||||
radius: bubble.radius * 4
|
||||
color: JamiTheme.shadowColor
|
||||
source: bubble
|
||||
transparentBorder: true
|
||||
samples: radius + 1
|
||||
}
|
||||
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"; from: 0.0; to: 1.0
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
}
|
||||
}
|
||||
|
||||
exit: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"; from: 1.0; to: 0.0
|
||||
duration: root.closeWithoutAnimation ? 0 : JamiTheme.shortFadeDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,6 +122,10 @@ Loader {
|
||||
echoMode: root.echoMode
|
||||
placeholderText: root.placeholderText
|
||||
onAccepted: root.accepted()
|
||||
onRejected: {
|
||||
root.editMode = false;
|
||||
text = staticText;
|
||||
}
|
||||
onKeyPressed: root.keyPressed()
|
||||
onTextChanged: dynamicText = text
|
||||
text: staticText
|
||||
|
||||
@ -53,6 +53,7 @@ AbstractButton {
|
||||
property alias toolTipText: toolTip.text
|
||||
property alias hasShortcut: toolTip.hasShortcut
|
||||
property alias shortcutKey: toolTip.shortcutKey
|
||||
property int buttonTextFontSize: 12
|
||||
|
||||
// State colors
|
||||
property string pressedColor: JamiTheme.pressedButtonColor
|
||||
@ -143,7 +144,7 @@ AbstractButton {
|
||||
|
||||
color: JamiTheme.primaryForegroundColor
|
||||
font.kerning: true
|
||||
font.pixelSize: 12
|
||||
font.pixelSize: buttonTextFontSize
|
||||
elide: Qt.ElideRight
|
||||
}
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ ContextMenuAutoLoader {
|
||||
|
||||
canTrigger: root.transferId !== ""
|
||||
itemName: JamiStrings.saveFile
|
||||
iconSource: JamiResources.save_file_svg
|
||||
onClicked: MessagesAdapter.copyToDownloads(root.transferId, root.transferName)
|
||||
},
|
||||
GeneralMenuItem {
|
||||
@ -44,6 +45,7 @@ ContextMenuAutoLoader {
|
||||
|
||||
canTrigger: root.transferId !== ""
|
||||
itemName: JamiStrings.openLocation
|
||||
iconSource: JamiResources.round_folder_24dp_svg
|
||||
onClicked: {
|
||||
MessagesAdapter.openDirectory(root.location);
|
||||
}
|
||||
@ -52,6 +54,7 @@ ContextMenuAutoLoader {
|
||||
id: reply
|
||||
|
||||
itemName: JamiStrings.reply
|
||||
iconSource: JamiResources.reply_black_24dp_svg
|
||||
onClicked: {
|
||||
MessagesAdapter.editId = "";
|
||||
MessagesAdapter.replyToId = root.msgId;
|
||||
@ -62,6 +65,7 @@ ContextMenuAutoLoader {
|
||||
|
||||
canTrigger: transferId === "" && isOutgoing
|
||||
itemName: JamiStrings.edit
|
||||
iconSource: JamiResources.edit_svg
|
||||
onClicked: {
|
||||
MessagesAdapter.replyToId = "";
|
||||
MessagesAdapter.editId = root.msgId;
|
||||
@ -73,6 +77,7 @@ ContextMenuAutoLoader {
|
||||
|
||||
canTrigger: transferId === "" && isOutgoing
|
||||
itemName: JamiStrings.optionDelete
|
||||
iconSource: JamiResources.delete_svg
|
||||
onClicked: {
|
||||
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId);
|
||||
}
|
||||
|
||||
@ -243,6 +243,7 @@ Control {
|
||||
|
||||
anchors.fill: bubble
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: function (mouse) {
|
||||
if (root.hoveredLink) {
|
||||
MessagesAdapter.openUrl(root.hoveredLink);
|
||||
@ -277,8 +278,8 @@ Control {
|
||||
anchors.rightMargin: isOutgoing ? 10 : 0
|
||||
anchors.leftMargin: !isOutgoing ? 10 : 0
|
||||
|
||||
imageColor: JamiTheme.emojiReactPushButtonColor
|
||||
normalColor: JamiTheme.transparentColor
|
||||
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
toolTipText: JamiStrings.moreOptions
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: isOutgoing ? optionButtonItem.right : undefined
|
||||
@ -287,33 +288,54 @@ Control {
|
||||
source: JamiResources.more_vert_24dp_svg
|
||||
width: optionButtonItem.width / 2
|
||||
height: optionButtonItem.height
|
||||
circled: false
|
||||
property bool isOpen: false
|
||||
property var obj: undefined
|
||||
|
||||
function bind() {
|
||||
more.isOpen = false;
|
||||
visible = Qt.binding(() => CurrentAccount.type !== Profile.Type.SIP && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || bgHandler.hovered));
|
||||
imageColor = Qt.binding(() => hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor);
|
||||
normalColor = Qt.binding(() => JamiTheme.primaryBackgroundColor);
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
var component = Qt.createComponent("qrc:/commoncomponents/MessageOptionsPopup.qml");
|
||||
var obj = component.createObject(bubble, {
|
||||
"emojiReactions": emojiReactions,
|
||||
"isOutgoing": isOutgoing,
|
||||
"msgId": Id,
|
||||
"msgBody": Body,
|
||||
"type": Type,
|
||||
"transferName": TransferName,
|
||||
"msgBubble": bubble,
|
||||
"listView": listView
|
||||
});
|
||||
obj.open();
|
||||
if (more.isOpen) {
|
||||
more.bind();
|
||||
obj.close();
|
||||
} else {
|
||||
var component = Qt.createComponent("qrc:/commoncomponents/ShowMoreMenu.qml");
|
||||
obj = component.createObject(more, {
|
||||
"emojiReactions": emojiReactions,
|
||||
"isOutgoing": isOutgoing,
|
||||
"msgId": Id,
|
||||
"msgBody": Body,
|
||||
"type": Type,
|
||||
"transferName": TransferName,
|
||||
"msgBubble": bubble,
|
||||
"listView": listView
|
||||
});
|
||||
obj.open();
|
||||
more.isOpen = true;
|
||||
visible = true;
|
||||
imageColor = JamiTheme.chatViewFooterImgHoverColor;
|
||||
normalColor = JamiTheme.hoveredButtonColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: reply
|
||||
|
||||
imageColor: JamiTheme.emojiReactPushButtonColor
|
||||
normalColor: JamiTheme.transparentColor
|
||||
circled: false
|
||||
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
toolTipText: JamiStrings.reply
|
||||
source: JamiResources.reply_svg
|
||||
source: JamiResources.reply_black_24dp_svg
|
||||
width: optionButtonItem.width / 2
|
||||
height: optionButtonItem.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.rightMargin: 5
|
||||
anchors.right: isOutgoing ? more.left : undefined
|
||||
anchors.left: !isOutgoing ? more.right : undefined
|
||||
visible: CurrentAccount.type !== Profile.Type.SIP && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || bgHandler.hovered)
|
||||
|
||||
65
src/app/commoncomponents/ShareMenu.qml
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import net.jami.Constants 1.1
|
||||
import "contextmenu"
|
||||
|
||||
BaseContextMenu {
|
||||
id: root
|
||||
property var modelList
|
||||
signal audioRecordMessageButtonClicked
|
||||
signal videoRecordMessageButtonClicked
|
||||
signal showMapClicked
|
||||
|
||||
property list<GeneralMenuItem> menuItems: [
|
||||
GeneralMenuItem {
|
||||
id: audioMessage
|
||||
|
||||
canTrigger: true
|
||||
iconSource: JamiResources.message_audio_black_24dp_svg
|
||||
itemName: JamiStrings.leaveAudioMessage
|
||||
onClicked: {
|
||||
root.audioRecordMessageButtonClicked();
|
||||
}
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: videoMessage
|
||||
|
||||
canTrigger: true
|
||||
iconSource: JamiResources.message_video_black_24dp_svg
|
||||
itemName: JamiStrings.leaveVideoMessage
|
||||
|
||||
onClicked: {
|
||||
root.videoRecordMessageButtonClicked();
|
||||
}
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: shareLocation
|
||||
|
||||
canTrigger: true
|
||||
iconSource: JamiResources.localisation_sharing_send_pin_svg
|
||||
itemName: JamiStrings.shareLocation
|
||||
onClicked: {
|
||||
root.showMapClicked();
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Component.onCompleted: {
|
||||
root.loadMenuItems(menuItems);
|
||||
}
|
||||
}
|
||||
@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Qt.labs.platform
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import "../mainview/components"
|
||||
|
||||
Popup {
|
||||
id: root
|
||||
padding: 0
|
||||
property list<Action> menuMoreButton
|
||||
|
||||
height: childrenRect.height
|
||||
width: childrenRect.width
|
||||
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
|
||||
Rectangle {
|
||||
id: rect
|
||||
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
border.color: JamiTheme.chatViewFooterRectangleBorderColor
|
||||
border.width: 2
|
||||
radius: 5
|
||||
height: listViewMoreButton.childrenRect.height + 16
|
||||
width: listViewMoreButton.childrenRect.width + 16
|
||||
|
||||
ListView {
|
||||
id: listViewMoreButton
|
||||
|
||||
anchors.centerIn: parent
|
||||
orientation: ListView.Vertical
|
||||
|
||||
spacing: 0
|
||||
|
||||
width: contentItem.childrenRect.width
|
||||
height: contentHeight
|
||||
|
||||
model: menuMoreButton
|
||||
|
||||
Rectangle {
|
||||
z: -1
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
onCountChanged: {
|
||||
for (var i = 0; i < count; i++) {
|
||||
var item = listViewMoreButton.itemAtIndex(i);
|
||||
item.width = listViewMoreButton.width;
|
||||
}
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
id: control
|
||||
|
||||
text: modelData.toolTip
|
||||
|
||||
contentItem: RowLayout {
|
||||
Rectangle {
|
||||
id: image
|
||||
width: 26
|
||||
height: 26
|
||||
radius: 5
|
||||
color: JamiTheme.transparentColor
|
||||
ResponsiveImage {
|
||||
anchors.fill: parent
|
||||
source: modelData.iconSrc
|
||||
color: control.hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
|
||||
}
|
||||
}
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
text: control.text
|
||||
color: control.hovered ? JamiTheme.chatViewFooterImgHoverColor : "#7f7f7f"
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
color: control.hovered ? JamiTheme.showMoreButtonOpenColor : JamiTheme.transparentColor
|
||||
}
|
||||
|
||||
action: modelData
|
||||
|
||||
onClicked: {
|
||||
root.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: JamiTheme.transparentColor
|
||||
radius: 5
|
||||
z: -1
|
||||
}
|
||||
|
||||
enter: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
from: 0.0
|
||||
to: 1.0
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
}
|
||||
}
|
||||
exit: Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
from: 1.0
|
||||
to: 0.0
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
190
src/app/commoncomponents/ShowMoreMenu.qml
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import net.jami.Constants 1.1
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick.Controls
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import "contextmenu"
|
||||
|
||||
BaseContextMenu {
|
||||
id: root
|
||||
|
||||
required property var emojiReactions
|
||||
property var emojiReplied: emojiReactions.ownEmojis
|
||||
|
||||
required property string msgId
|
||||
required property string msgBody
|
||||
required property bool isOutgoing
|
||||
required property int type
|
||||
required property string transferName
|
||||
required property Item msgBubble
|
||||
required property ListView listView
|
||||
|
||||
property string location: msgBody
|
||||
property bool closeWithoutAnimation: false
|
||||
property var emojiPicker
|
||||
|
||||
function xPositionProvider(width) {
|
||||
// Use the width at function scope to retrigger property evaluation.
|
||||
const listViewWidth = listView.width;
|
||||
const parentX = parent.x;
|
||||
if (isOutgoing) {
|
||||
return parentX - width - 21;
|
||||
} else {
|
||||
return parentX + 21;
|
||||
}
|
||||
}
|
||||
|
||||
x: xPositionProvider(width)
|
||||
y: parent.y
|
||||
|
||||
signal addMoreEmoji
|
||||
onAddMoreEmoji: {
|
||||
JamiQmlUtils.updateMessageBarButtonsPoints();
|
||||
openEmojiPicker();
|
||||
}
|
||||
|
||||
function openEmojiPicker() {
|
||||
var component = WITH_WEBENGINE ? Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml") : Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml");
|
||||
emojiPicker = component.createObject(root.parent, {
|
||||
"listView": listView
|
||||
});
|
||||
emojiPicker.emojiIsPicked.connect(function (content) {
|
||||
if (emojiReplied.includes(content)) {
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId);
|
||||
} else {
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId);
|
||||
}
|
||||
});
|
||||
if (emojiPicker !== null) {
|
||||
root.opacity = 0;
|
||||
emojiPicker.closed.connect(() => close());
|
||||
emojiPicker.x = xPositionProvider(JamiTheme.emojiPickerWidth);
|
||||
emojiPicker.y = yPositionProvider(JamiTheme.emojiPickerHeight);
|
||||
emojiPicker.open();
|
||||
} else {
|
||||
console.log("Error creating emojiPicker from message options popup");
|
||||
}
|
||||
}
|
||||
|
||||
// Close the picker when listView vertical properties change.
|
||||
property real listViewHeight: listView.height
|
||||
onListViewHeightChanged: close()
|
||||
property bool isScrolling: listView.verticalScrollBar.active
|
||||
onIsScrollingChanged: close()
|
||||
|
||||
onOpened: root.closeWithoutAnimation = false
|
||||
onClosed: if (emojiPicker)
|
||||
emojiPicker.closeEmojiPicker()
|
||||
|
||||
function getModel() {
|
||||
const defaultModel = ["👍", "👎", "😂"];
|
||||
const reactedEmojis = Array.isArray(emojiReplied) ? emojiReplied.slice(0, defaultModel.length) : [];
|
||||
const uniqueEmojis = Array.from(new Set(reactedEmojis));
|
||||
const missingEmojis = defaultModel.filter(emoji => !uniqueEmojis.includes(emoji));
|
||||
return uniqueEmojis.concat(missingEmojis);
|
||||
}
|
||||
|
||||
property list<MenuItem> menuItems: [
|
||||
GeneralMenuItemList {
|
||||
id: audioMessage
|
||||
|
||||
modelList: getModel()
|
||||
canTrigger: true
|
||||
iconSource: JamiResources.add_reaction_svg
|
||||
itemName: JamiStrings.copy
|
||||
addMenuSeparatorAfter: true
|
||||
messageId: msgId
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: saveFile
|
||||
|
||||
canTrigger: type === Interaction.Type.DATA_TRANSFER
|
||||
iconSource: JamiResources.save_file_svg
|
||||
itemName: JamiStrings.saveFile
|
||||
onClicked: {
|
||||
MessagesAdapter.copyToDownloads(root.msgId, root.transferName);
|
||||
}
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: openLocation
|
||||
|
||||
canTrigger: type === Interaction.Type.DATA_TRANSFER
|
||||
iconSource: JamiResources.round_folder_24dp_svg
|
||||
itemName: JamiStrings.openLocation
|
||||
onClicked: {
|
||||
MessagesAdapter.openDirectory(root.location);
|
||||
}
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: removeLocally
|
||||
|
||||
canTrigger: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
|
||||
iconSource: JamiResources.trash_black_24dp_svg
|
||||
itemName: JamiStrings.removeLocally
|
||||
onClicked: {
|
||||
MessagesAdapter.removeFile(msgId, root.location);
|
||||
;
|
||||
}
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: editMessage
|
||||
|
||||
canTrigger: root.isOutgoing && type === Interaction.Type.TEXT
|
||||
iconSource: JamiResources.edit_svg
|
||||
itemName: JamiStrings.editMessage
|
||||
onClicked: {
|
||||
MessagesAdapter.replyToId = "";
|
||||
MessagesAdapter.editId = root.msgId;
|
||||
}
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: deleteMessage
|
||||
|
||||
canTrigger: root.isOutgoing && type === Interaction.Type.TEXT
|
||||
iconSource: JamiResources.delete_svg
|
||||
itemName: JamiStrings.deleteMessage
|
||||
onClicked: {
|
||||
MessagesAdapter.editMessage(CurrentConversation.id, "", root.msgId);
|
||||
}
|
||||
},
|
||||
GeneralMenuItem {
|
||||
id: copyMessage
|
||||
|
||||
canTrigger: true
|
||||
iconSource: JamiResources.copy_svg
|
||||
itemName: JamiStrings.copy
|
||||
onClicked: {
|
||||
UtilsAdapter.setClipboardText(msgBody);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Component.onCompleted: {
|
||||
root.loadMenuItems(menuItems);
|
||||
}
|
||||
|
||||
onAboutToHide: {
|
||||
root.destroy();
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
parent.bind();
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,8 @@ import net.jami.Constants 1.1
|
||||
Menu {
|
||||
id: root
|
||||
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside | Popup.CloseOnPressOutsideParent
|
||||
|
||||
property int menuPreferredWidth: 0
|
||||
property int menuItemsPreferredHeight: 0
|
||||
property int menuSeparatorPreferredHeight: 0
|
||||
@ -43,11 +45,9 @@ Menu {
|
||||
|
||||
function loadMenuItems(menuItems) {
|
||||
root.addItem(menuTopBorder);
|
||||
|
||||
// use the maximum text width as the preferred width for menu
|
||||
for (var j = 0; j < menuItems.length; ++j) {
|
||||
var currentItemWidth = menuItems[j].itemPreferredWidth;
|
||||
if (currentItemWidth !== JamiTheme.menuItemsPreferredWidth && currentItemWidth > menuPreferredWidth)
|
||||
if (currentItemWidth !== JamiTheme.menuItemsPreferredWidth && currentItemWidth > menuPreferredWidth && menuItems[j].canTrigger)
|
||||
menuPreferredWidth = currentItemWidth;
|
||||
}
|
||||
for (var i = 0; i < menuItems.length; ++i) {
|
||||
@ -55,17 +55,28 @@ Menu {
|
||||
menuItems[i].parentMenu = root;
|
||||
root.addItem(menuItems[i]);
|
||||
if (menuPreferredWidth)
|
||||
menuItems[i].itemPreferredWidth = menuPreferredWidth;
|
||||
menuItems[i].itemRealWidth = menuPreferredWidth;
|
||||
if (menuItemsPreferredHeight)
|
||||
menuItems[i].itemPreferredHeight = menuItemsPreferredHeight;
|
||||
}
|
||||
if (menuItems[i].addMenuSeparatorAfter) {
|
||||
// If the QML file to be loaded is a local file,
|
||||
// you could omit the finishCreation() function
|
||||
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
|
||||
var menuSeparatorComponentObj = menuSeparatorComponent.createObject();
|
||||
generalMenuSeparatorList.push(menuSeparatorComponentObj);
|
||||
root.addItem(menuSeparatorComponentObj);
|
||||
if (i !== menuItems.length - 1) {
|
||||
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
|
||||
var menuSeparatorComponentObj = menuSeparatorComponent.createObject();
|
||||
generalMenuSeparatorList.push(menuSeparatorComponentObj);
|
||||
root.addItem(menuSeparatorComponentObj);
|
||||
}
|
||||
if (menuItems[i].addMenuSeparatorAfter) {
|
||||
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
|
||||
var menuSeparatorComponentObj = menuSeparatorComponent.createObject(root, {
|
||||
"separatorColor": "#DEDEDE",
|
||||
"separatorPreferredHeight": 0
|
||||
});
|
||||
generalMenuSeparatorList.push(menuSeparatorComponentObj);
|
||||
root.addItem(menuSeparatorComponentObj);
|
||||
var menuSeparatorComponent = Qt.createComponent("GeneralMenuSeparator.qml", Component.PreferSynchronous, root);
|
||||
var menuSeparatorComponentObj = menuSeparatorComponent.createObject();
|
||||
generalMenuSeparatorList.push(menuSeparatorComponentObj);
|
||||
root.addItem(menuSeparatorComponentObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
root.addItem(menuBottomBorder);
|
||||
@ -77,28 +88,22 @@ Menu {
|
||||
root.close();
|
||||
}
|
||||
|
||||
modal: true
|
||||
Overlay.modal: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
font.pointSize: JamiTheme.menuFontSize
|
||||
|
||||
background: Rectangle {
|
||||
id: container
|
||||
|
||||
implicitWidth: menuPreferredWidth ? menuPreferredWidth : JamiTheme.menuItemsPreferredWidth
|
||||
|
||||
border.width: JamiTheme.menuItemsCommonBorderWidth
|
||||
border.color: JamiTheme.tabbarBorderColor
|
||||
color: JamiTheme.backgroundColor
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
radius: 5
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
z: -1
|
||||
horizontalOffset: 3.0
|
||||
horizontalOffset: 0.0
|
||||
verticalOffset: 3.0
|
||||
radius: 16.0
|
||||
color: JamiTheme.shadowColor
|
||||
radius: 6
|
||||
color: "#29000000"
|
||||
transparentBorder: true
|
||||
samples: radius + 1
|
||||
}
|
||||
|
||||
@ -30,6 +30,8 @@ Loader {
|
||||
|
||||
active: false
|
||||
|
||||
visible: false
|
||||
|
||||
function openMenu() {
|
||||
root.active = true;
|
||||
root.sourceComponent = menuComponent;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -32,34 +31,41 @@ MenuItem {
|
||||
property alias iconSource: contextMenuItemImage.source
|
||||
property string iconColor: ""
|
||||
property bool canTrigger: true
|
||||
property bool hasIcon: true
|
||||
property bool addMenuSeparatorAfter: false
|
||||
property bool autoTextSizeAdjustment: true
|
||||
property bool dangerous: false
|
||||
property BaseContextMenu parentMenu
|
||||
property bool isActif: true
|
||||
|
||||
property int itemPreferredWidth: JamiTheme.menuItemsPreferredWidth
|
||||
property int itemPreferredWidth: hasIcon ? 50 + contextMenuItemText.contentWidth + contextMenuItemImage.width : 35 + contextMenuItemText.contentWidth
|
||||
property int itemRealWidth: itemPreferredWidth
|
||||
property int itemPreferredHeight: JamiTheme.menuItemsPreferredHeight
|
||||
property int leftBorderWidth: JamiTheme.menuItemsCommonBorderWidth
|
||||
property int rightBorderWidth: JamiTheme.menuItemsCommonBorderWidth
|
||||
|
||||
property int itemImageLeftMargin: 24
|
||||
property int itemTextMargin: 20
|
||||
property int itemImageLeftMargin: 10
|
||||
property int itemTextMargin: 10
|
||||
|
||||
signal clicked
|
||||
property bool itemHovered: menuItemContentRect.hovered
|
||||
|
||||
contentItem: AbstractButton {
|
||||
width: itemRealWidth
|
||||
|
||||
contentItem: PushButton {
|
||||
id: menuItemContentRect
|
||||
|
||||
background: Rectangle {
|
||||
id: background
|
||||
enabled: isActif
|
||||
hoverEnabled: isActif
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 1
|
||||
anchors.rightMargin: 1
|
||||
hoveredColor: JamiTheme.hoverColor
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
circled: false
|
||||
radius: 5
|
||||
|
||||
color: menuItemContentRect.hovered ? JamiTheme.hoverColor : JamiTheme.backgroundColor
|
||||
}
|
||||
//duration: 1000
|
||||
anchors.leftMargin: 6
|
||||
anchors.rightMargin: 6
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
@ -76,41 +82,25 @@ MenuItem {
|
||||
|
||||
visible: status === Image.Ready
|
||||
|
||||
color: iconColor !== "" ? iconColor : JamiTheme.textColor
|
||||
opacity: 0.7
|
||||
color: menuItemContentRect.hovered ? JamiTheme.textColor : JamiTheme.chatViewFooterImgColor
|
||||
}
|
||||
|
||||
Text {
|
||||
id: contextMenuItemText
|
||||
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: contextMenuItemImage.status === Image.Ready ? itemTextMargin : itemTextMargin / 2
|
||||
Layout.rightMargin: contextMenuItemImage.status === Image.Ready ? itemTextMargin : itemTextMargin / 2
|
||||
Layout.leftMargin: contextMenuItemImage.status === Image.Ready ? itemTextMargin : itemTextMargin
|
||||
Layout.rightMargin: contextMenuItemImage.status === Image.Ready ? itemImageLeftMargin : itemTextMargin
|
||||
Layout.preferredHeight: itemPreferredHeight
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: itemName
|
||||
color: dangerous ? JamiTheme.redColor : JamiTheme.textColor
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
TextMetrics {
|
||||
id: contextMenuItemTextMetrics
|
||||
|
||||
font: contextMenuItemText.font
|
||||
text: contextMenuItemText.text
|
||||
|
||||
onBoundingRectChanged: {
|
||||
var sizeToCompare = itemPreferredWidth - (contextMenuItemImage.source.toString().length > 0 ? itemTextMargin + itemImageLeftMargin + contextMenuItemImage.width : itemTextMargin / 2);
|
||||
if (autoTextSizeAdjustment && boundingRect.width > sizeToCompare) {
|
||||
if (boundingRect.width > JamiTheme.contextMenuItemTextMaxWidth) {
|
||||
itemPreferredWidth += JamiTheme.contextMenuItemTextMaxWidth - JamiTheme.contextMenuItemTextPreferredWidth + itemTextMargin;
|
||||
contextMenuItemText.elide = Text.ElideRight;
|
||||
} else
|
||||
itemPreferredWidth += boundingRect.width + itemTextMargin - sizeToCompare;
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: contextMenuItemText
|
||||
height: parent.height
|
||||
text: itemName
|
||||
color: dangerous ? JamiTheme.redColor : isActif ? JamiTheme.textColor : JamiTheme.chatViewFooterImgColor
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,7 +120,9 @@ MenuItem {
|
||||
anchors.leftMargin: leftBorderWidth
|
||||
anchors.rightMargin: rightBorderWidth
|
||||
|
||||
implicitWidth: itemPreferredWidth
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
|
||||
implicitWidth: itemRealWidth
|
||||
implicitHeight: itemPreferredHeight
|
||||
|
||||
border.width: 0
|
||||
@ -141,7 +133,7 @@ MenuItem {
|
||||
rBorderwidth: rightBorderWidth
|
||||
tBorderwidth: 0
|
||||
bBorderwidth: 0
|
||||
borderColor: JamiTheme.tabbarBorderColor
|
||||
borderColor: JamiTheme.primaryBackgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
231
src/app/commoncomponents/contextmenu/GeneralMenuItemList.qml
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import net.jami.Constants 1.1
|
||||
import "../"
|
||||
import net.jami.Adapters 1.1
|
||||
|
||||
// General menu item.
|
||||
// Can control top, bottom, left, right border width.
|
||||
// Use onClicked slot to simulate item click event.
|
||||
// Can have image icon at the left of the text.
|
||||
MenuItem {
|
||||
id: menuItem
|
||||
|
||||
property var modelList: undefined
|
||||
property string itemName: ""
|
||||
property var iconSource: undefined
|
||||
property string iconColor: ""
|
||||
property bool canTrigger: true
|
||||
property bool hasIcon: true
|
||||
property bool addMenuSeparatorAfter: false
|
||||
property bool autoTextSizeAdjustment: true
|
||||
property bool dangerous: false
|
||||
property BaseContextMenu parentMenu
|
||||
property string messageId
|
||||
|
||||
signal addMoreEmoji
|
||||
|
||||
property int itemPreferredWidth: 207
|
||||
property int itemRealWidth: itemPreferredWidth
|
||||
property int itemPreferredHeight: JamiTheme.menuItemsPreferredHeight
|
||||
property int leftBorderWidth: JamiTheme.menuItemsCommonBorderWidth
|
||||
property int rightBorderWidth: JamiTheme.menuItemsCommonBorderWidth
|
||||
|
||||
property int itemImageLeftMargin: 18
|
||||
|
||||
signal clicked
|
||||
|
||||
width: itemRealWidth
|
||||
|
||||
contentItem: Item {
|
||||
id: menuItemContentRect
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
|
||||
anchors.fill: menuItemContentRect
|
||||
|
||||
Rectangle {
|
||||
id: contextMenuItemImage
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: itemImageLeftMargin
|
||||
height: 36
|
||||
width: 36
|
||||
color: emojiReplied.includes(modelList[0]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
|
||||
radius: 5
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: modelList[0]
|
||||
font.pointSize: JamiTheme.emojiBubbleSize
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
contextMenuItemImage.color = JamiTheme.hoveredButtonColor;
|
||||
}
|
||||
onExited: {
|
||||
contextMenuItemImage.color = emojiReplied.includes(modelList[0]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
|
||||
}
|
||||
onClicked: {
|
||||
if (emojiReplied.includes(modelList[0])) {
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[0], msgId);
|
||||
} else {
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[0], msgId);
|
||||
}
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: contextMenuItemImage2
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: itemImageLeftMargin / 2
|
||||
height: 36
|
||||
width: 36
|
||||
color: emojiReplied.includes(modelList[1]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
|
||||
radius: 5
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: modelList[1]
|
||||
font.pointSize: JamiTheme.emojiBubbleSize
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
contextMenuItemImage2.color = JamiTheme.hoveredButtonColor;
|
||||
}
|
||||
onExited: {
|
||||
contextMenuItemImage2.color = emojiReplied.includes(modelList[1]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
|
||||
}
|
||||
onClicked: {
|
||||
if (emojiReplied.includes(modelList[1])) {
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[1], msgId);
|
||||
} else {
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[1], msgId);
|
||||
}
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: contextMenuItemImage3
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: itemImageLeftMargin / 2
|
||||
height: 36
|
||||
width: 36
|
||||
color: emojiReplied.includes(modelList[2]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor
|
||||
radius: 5
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: modelList[2]
|
||||
font.pointSize: JamiTheme.emojiBubbleSize
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
contextMenuItemImage3.color = JamiTheme.hoveredButtonColor;
|
||||
}
|
||||
onExited: {
|
||||
contextMenuItemImage3.color = emojiReplied.includes(modelList[2]) ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor;
|
||||
}
|
||||
onClicked: {
|
||||
if (emojiReplied.includes(modelList[2])) {
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, modelList[2], msgId);
|
||||
} else {
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id, modelList[2], msgId);
|
||||
}
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: contextMenuItemImage4
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: itemImageLeftMargin / 2
|
||||
Layout.rightMargin: itemImageLeftMargin
|
||||
height: 36
|
||||
width: 36
|
||||
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
radius: 5
|
||||
source: iconSource
|
||||
onClicked: {
|
||||
root.addMoreEmoji();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
highlighted: true
|
||||
|
||||
background: Rectangle {
|
||||
id: contextMenuBackgroundRect
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: leftBorderWidth
|
||||
anchors.rightMargin: rightBorderWidth
|
||||
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
|
||||
implicitWidth: itemRealWidth
|
||||
implicitHeight: itemPreferredHeight
|
||||
|
||||
border.width: 0
|
||||
|
||||
CustomBorder {
|
||||
commonBorder: false
|
||||
lBorderwidth: leftBorderWidth
|
||||
rBorderwidth: rightBorderWidth
|
||||
tBorderwidth: 0
|
||||
bBorderwidth: 0
|
||||
borderColor: JamiTheme.primaryBackgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,19 +23,24 @@ MenuSeparator {
|
||||
id: menuSeparator
|
||||
|
||||
property int separatorPreferredWidth: JamiTheme.menuItemsPreferredWidth
|
||||
property int separatorPreferredHeight: 1
|
||||
property string separatorColor: JamiTheme.tabbarBorderColor
|
||||
property int separatorPreferredHeight: 5
|
||||
property string separatorColor: JamiTheme.primaryBackgroundColor
|
||||
|
||||
padding: 0
|
||||
topPadding: 1
|
||||
bottomPadding: 1
|
||||
|
||||
contentItem: Rectangle {
|
||||
implicitWidth: separatorPreferredWidth
|
||||
implicitHeight: separatorPreferredHeight
|
||||
color: separatorColor
|
||||
radius: 5
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: JamiTheme.backgroundColor
|
||||
width: parent.width - 10
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: separatorColor
|
||||
radius: 5
|
||||
}
|
||||
}
|
||||
|
||||
228
src/app/connectioninfolistmodel.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "connectioninfolistmodel.h"
|
||||
|
||||
ConnectionInfoListModel::ConnectionInfoListModel(LRCInstance* instance, QObject* parent)
|
||||
: AbstractListModelBase(parent)
|
||||
{
|
||||
lrcInstance_ = instance;
|
||||
connect(lrcInstance_,
|
||||
&LRCInstance::currentAccountIdChanged,
|
||||
this,
|
||||
&ConnectionInfoListModel::resetData);
|
||||
}
|
||||
|
||||
int
|
||||
ConnectionInfoListModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return peerIds_.size();
|
||||
}
|
||||
|
||||
QVariant
|
||||
ConnectionInfoListModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
const auto accountId = lrcInstance_->get_currentAccountId();
|
||||
|
||||
if (accountId.isEmpty()) {
|
||||
qWarning() << "ConnectionInfoListModel::data: accountId or peerID is empty";
|
||||
return {};
|
||||
}
|
||||
const auto peerId = peerIds_[index.row()];
|
||||
const auto peerData = peerData_[peerId];
|
||||
|
||||
switch (role) {
|
||||
case ConnectionInfoList::ChannelsMap: {
|
||||
QVariantMap channelsMapMap;
|
||||
int i = 0;
|
||||
for (const auto& device : peerData.keys()) {
|
||||
QString channelsId = peerData[device]["id"].toString();
|
||||
QVariantMap channelsMap;
|
||||
const auto channelInfoList = lrcInstance_->getChannelList(accountId, channelsId);
|
||||
for (const auto& channelInfo : channelInfoList) {
|
||||
channelsMap.insert(channelInfo["id"], channelInfo["name"]);
|
||||
}
|
||||
channelsMapMap.insert(QString::number(i++), channelsMap);
|
||||
}
|
||||
return QVariant(channelsMapMap);
|
||||
}
|
||||
case ConnectionInfoList::ConnectionDatas: {
|
||||
QString peerString;
|
||||
peerString += "Peer:" + peerId;
|
||||
for (const auto& device : peerData.keys()) {
|
||||
peerString += "{";
|
||||
peerString += "Device:" + device + ",";
|
||||
peerString += "Status:" + peerData[device]["status"].toString() + ",";
|
||||
peerString += "Channels:" + peerData[device]["channels"].toString() + ",";
|
||||
peerString += "Remote Address" + peerData[device]["remoteAddress"].toString();
|
||||
peerString += "}";
|
||||
}
|
||||
return peerString;
|
||||
}
|
||||
case ConnectionInfoList::PeerId:
|
||||
return peerId;
|
||||
case ConnectionInfoList::RemoteAddress: {
|
||||
QVariantMap remoteAddressMap;
|
||||
int i = 0;
|
||||
for (const auto& device : peerData.keys()) {
|
||||
remoteAddressMap.insert(QString::number(i++), peerData[device]["remoteAddress"]);
|
||||
}
|
||||
return QVariant(remoteAddressMap);
|
||||
}
|
||||
case ConnectionInfoList::DeviceId: {
|
||||
QVariantMap deviceMap;
|
||||
int i = 0;
|
||||
for (const auto& device : peerData.keys()) {
|
||||
deviceMap.insert(QString::number(i++), device);
|
||||
}
|
||||
return QVariant(deviceMap);
|
||||
}
|
||||
case ConnectionInfoList::Status: {
|
||||
QVariantMap statusMap;
|
||||
int i = 0;
|
||||
for (const auto& device : peerData.keys()) {
|
||||
statusMap.insert(QString::number(i++), peerData[device]["status"]);
|
||||
}
|
||||
return QVariantMap(statusMap);
|
||||
}
|
||||
case ConnectionInfoList::Channels: {
|
||||
QVariantMap channelsMap;
|
||||
int i = 0;
|
||||
for (const auto& device : peerData.keys()) {
|
||||
channelsMap.insert(QString::number(i++), peerData[device]["channels"]);
|
||||
}
|
||||
return QVariant(channelsMap);
|
||||
}
|
||||
case ConnectionInfoList::Count:
|
||||
return peerData.size();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
ConnectionInfoListModel::roleNames() const
|
||||
{
|
||||
using namespace ConnectionInfoList;
|
||||
QHash<int, QByteArray> roles;
|
||||
#define X(role) roles[role] = #role;
|
||||
CONNECTONINFO_ROLES
|
||||
#undef X
|
||||
return roles;
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionInfoListModel::update()
|
||||
{
|
||||
const auto accountId = lrcInstance_->get_currentAccountId();
|
||||
if (accountId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
aggregateData();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::tuple<QVector<T>, QVector<T>>
|
||||
getSetDiff(QVector<T> u, QVector<T> v)
|
||||
{
|
||||
using namespace std;
|
||||
QVector<T> a, r;
|
||||
set_difference(v.begin(), v.end(), u.begin(), u.end(), inserter(a, a.begin()));
|
||||
set_difference(u.begin(), u.end(), v.begin(), v.end(), inserter(r, r.begin()));
|
||||
return {a, r};
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionInfoListModel::aggregateData()
|
||||
{
|
||||
const auto accountId = lrcInstance_->get_currentAccountId();
|
||||
if (accountId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
connectionInfoList_ = lrcInstance_->getConnectionList(accountId);
|
||||
|
||||
peerData_ = {};
|
||||
|
||||
QSet<QString> newPeerIds;
|
||||
|
||||
for (const auto& connectionInfo : connectionInfoList_) {
|
||||
if (!connectionInfo["peer"].isEmpty()) {
|
||||
newPeerIds.insert(connectionInfo["peer"]);
|
||||
}
|
||||
const auto channelInfoList = lrcInstance_->getChannelList(accountId, connectionInfo["id"]);
|
||||
peerData_[connectionInfo["peer"]][connectionInfo["device"]] = {};
|
||||
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["status"]
|
||||
= connectionInfo["status"];
|
||||
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["channels"] = channelInfoList
|
||||
.size();
|
||||
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["id"] = connectionInfo["id"];
|
||||
peerData_[connectionInfo["peer"]][connectionInfo["device"]]["remoteAddress"]
|
||||
= connectionInfo["remoteAddress"];
|
||||
}
|
||||
|
||||
QVector<QString> oldVector;
|
||||
for (const auto& peerId : peerIds_) {
|
||||
oldVector << peerId;
|
||||
}
|
||||
QVector<QString> newVector;
|
||||
for (const auto& peerId : newPeerIds) {
|
||||
newVector << peerId;
|
||||
}
|
||||
|
||||
std::sort(oldVector.begin(), oldVector.end());
|
||||
std::sort(newVector.begin(), newVector.end());
|
||||
|
||||
QVector<QString> removed, added;
|
||||
std::tie(added, removed) = getSetDiff(oldVector, newVector);
|
||||
Q_FOREACH (const auto& key, added) {
|
||||
auto index = std::distance(newVector.begin(),
|
||||
std::find(newVector.begin(), newVector.end(), key));
|
||||
beginInsertRows(QModelIndex(), index, index);
|
||||
peerIds_.insert(index, key);
|
||||
endInsertRows();
|
||||
}
|
||||
Q_FOREACH (const auto& key, removed) {
|
||||
auto index = std::distance(oldVector.begin(),
|
||||
std::find(oldVector.begin(), oldVector.end(), key));
|
||||
beginRemoveRows(QModelIndex(), index, index);
|
||||
if (peerIds_.size() > index) {
|
||||
peerIds_.remove(index);
|
||||
} else {
|
||||
qWarning() << "ConnectionInfoListModel::aggregateData: index out of range";
|
||||
qWarning() << "index: " << index;
|
||||
qWarning() << "key: " << key;
|
||||
}
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
// HACK: loop through all the peerIds_ and update the data for each one.
|
||||
// This is not efficient, but it works.
|
||||
Q_FOREACH (const auto& peerId, peerIds_) {
|
||||
auto index = std::distance(peerIds_.begin(),
|
||||
std::find(peerIds_.begin(), peerIds_.end(), peerId));
|
||||
Q_EMIT dataChanged(this->index(index), this->index(index));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConnectionInfoListModel::resetData()
|
||||
{
|
||||
beginResetModel();
|
||||
peerIds_.clear();
|
||||
peerData_.clear();
|
||||
endResetModel();
|
||||
}
|
||||
64
src/app/connectioninfolistmodel.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "abstractlistmodelbase.h"
|
||||
|
||||
#define CONNECTONINFO_ROLES \
|
||||
X(ConnectionDatas) \
|
||||
X(ChannelsMap) \
|
||||
X(PeerName) \
|
||||
X(PeerId) \
|
||||
X(DeviceId) \
|
||||
X(Status) \
|
||||
X(Channels) \
|
||||
X(RemoteAddress) \
|
||||
X(Count) // this is the number of connections (convenience)
|
||||
|
||||
namespace ConnectionInfoList {
|
||||
Q_NAMESPACE
|
||||
enum Role {
|
||||
DummyRole = Qt::UserRole + 1,
|
||||
#define X(role) role,
|
||||
CONNECTONINFO_ROLES
|
||||
#undef X
|
||||
};
|
||||
Q_ENUM_NS(Role)
|
||||
} // namespace ConnectionInfoList
|
||||
|
||||
class ConnectionInfoListModel : public AbstractListModelBase
|
||||
{
|
||||
public:
|
||||
explicit ConnectionInfoListModel(LRCInstance* instance, QObject* parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void update();
|
||||
|
||||
private:
|
||||
using Role = ConnectionInfoList::Role;
|
||||
|
||||
VectorMapStringString connectionInfoList_;
|
||||
|
||||
QVector<QString> peerIds_;
|
||||
QMap<QString, QMap<QString, QMap<QString, QVariant>>> peerData_;
|
||||
void aggregateData();
|
||||
void resetData();
|
||||
};
|
||||
@ -72,7 +72,11 @@ Item {
|
||||
}
|
||||
|
||||
function isDonationBannerVisible() {
|
||||
// The banner is visible if the current date is after the date set in the settings
|
||||
return new Date() > new Date(Date.parse(UtilsAdapter.getAppValue(Settings.Key.DonateVisibleDate)));
|
||||
// The banner is visible if the current date is after the date set in the settings and before the end date
|
||||
// And if the donation toggle is checked
|
||||
var isDonationVisible = UtilsAdapter.getAppValue(Settings.Key.IsDonationVisible);
|
||||
var endDonationDate = new Date(Date.parse(UtilsAdapter.getAppValue(Settings.Key.DonationEndDate)));
|
||||
var donationVisibleDate = new Date(Date.parse(UtilsAdapter.getAppValue(Settings.Key.DonationVisibleDate)));
|
||||
return new Date() < endDonationDate && new Date() > donationVisibleDate && isDonationVisible && false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,6 +83,15 @@ Item {
|
||||
property string selectNewRingtone: qsTr("Select a new ringtone")
|
||||
property string certificateFile: qsTr("Certificate File (*.crt)")
|
||||
property string audioFile: qsTr("Audio File (*.wav *.ogg *.opus *.mp3 *.aiff *.wma)")
|
||||
property string pushToTalk: qsTr("Push-to-talk")
|
||||
property string enablePTT: qsTr("Enable push-to-talk")
|
||||
property string keyboardShortcut: qsTr("Keyboard shortcut")
|
||||
property string changeKeyboardShortcut: qsTr("Change keyboard shortcut")
|
||||
|
||||
// ChangePttKeyPopup
|
||||
property string changeShortcut: qsTr("Change shortcut")
|
||||
property string assignmentIndication: qsTr("Press the key to be assigned to push-to-talk shortcut")
|
||||
property string assign: qsTr("Assign")
|
||||
|
||||
// AdvancedChatSettings
|
||||
property string enableReadReceipts: qsTr("Enable read receipts")
|
||||
@ -839,7 +848,28 @@ Item {
|
||||
property string zoomLevel: qsTr("Text zoom level")
|
||||
|
||||
//Donation campaign
|
||||
property string donationTipBoxText: qsTr("Free and private sharing. <a href=\"https://jami.net/donate/\">Donate</a> to expand it.")
|
||||
property string donation: qsTr("Donate")
|
||||
property string donationText: qsTr("If you enjoy using Jami and believe in our mission, would you make a donation?")
|
||||
property string notNow: qsTr("Not now")
|
||||
property string enableDonation: qsTr("Enable donation campaign")
|
||||
|
||||
//Chat setting page
|
||||
property string enter: qsTr("Enter")
|
||||
property string shiftEnter: qsTr("Shift+Enter")
|
||||
property string textFormattingDescription: qsTr("Enter or Shift+Enter to insert a new line")
|
||||
property string textFormatting: qsTr("Text formatting")
|
||||
|
||||
//Connection monitoring
|
||||
property string connected: qsTr("Connected")
|
||||
property string connectingTLS: qsTr("Connecting TLS")
|
||||
property string connectingICE: qsTr("Connecting ICE")
|
||||
property string connecting: qsTr("Connecting")
|
||||
property string waiting: qsTr("Waiting")
|
||||
property string contact: qsTr("Contact")
|
||||
property string connection: qsTr("Connection")
|
||||
property string channels: qsTr("Channels")
|
||||
property string copyAllData: qsTr("Copy all data")
|
||||
property string remote: qsTr("Remote: ")
|
||||
property string view: qsTr("View")
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ Item {
|
||||
property color greyBorderColor: "#333"
|
||||
property color selectionBlue: darkTheme ? "#0061a5" : "#109ede"
|
||||
|
||||
property color hoverColor: darkTheme ? "#4d4d4d" : "#c7c7c7"
|
||||
property color hoverColor: darkTheme ? "#4d4d4d" : "#DEDEDE"
|
||||
property color pressColor: darkTheme ? "#777" : "#c0c0c0"
|
||||
property color selectedColor: darkTheme ? "#0e81c5" : "#e0e0e0"
|
||||
property color smartListHoveredColor: darkTheme ? "#4d4d4d" : "#dedede"
|
||||
@ -367,9 +367,9 @@ Item {
|
||||
property int avatarReadReceiptSize: 18
|
||||
|
||||
property int menuItemsPreferredWidth: 220
|
||||
property int menuItemsPreferredHeight: 48
|
||||
property int menuItemsPreferredHeight: 36
|
||||
property int menuItemsCommonBorderWidth: 1
|
||||
property int menuBorderPreferredHeight: 8
|
||||
property int menuBorderPreferredHeight: 5
|
||||
|
||||
property real maximumWidthSettingsView: 516
|
||||
property real settingsHeaderpreferredHeight: 64
|
||||
@ -436,10 +436,6 @@ Item {
|
||||
property real switchPreferredWidth: 40
|
||||
property real switchIndicatorPreferredWidth: 20
|
||||
|
||||
// Jami Identifier
|
||||
property color mainColor: "#005699"
|
||||
property real pushButtonSize: 22
|
||||
property real pushButtonMargins: 10
|
||||
|
||||
// Modal Popup
|
||||
property real modalPopupRadius: 20
|
||||
@ -492,6 +488,7 @@ Item {
|
||||
|
||||
// MessageBar
|
||||
property int messageBarMarginSize: 10
|
||||
property int messageBarMinimumWidth: 438
|
||||
|
||||
// InvitationView
|
||||
property real invitationViewAvatarSize: 112
|
||||
@ -507,6 +504,11 @@ Item {
|
||||
property real jamiIdFontSize: calcSize(19)
|
||||
property real jamiIdSmallFontSize: calcSize(11)
|
||||
property color jamiIdColor: darkTheme ? blackColor : sysColor
|
||||
property color mainColor: "#005699"
|
||||
property real pushButtonSize: 22
|
||||
property real pushButtonMargins: 10
|
||||
property color jamiIdBackgroundColor: darkTheme ? "#333333" : "#F0EFEF"
|
||||
property color redDotColor: "#CC0022"
|
||||
|
||||
// MainView
|
||||
property color rectColor: darkTheme ? blackColor : "#e5eef5"
|
||||
@ -532,6 +534,7 @@ Item {
|
||||
|
||||
// WizardView Welcome Page
|
||||
property real welcomeLabelPointSize: 30
|
||||
property var welcomeLogo: darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
|
||||
property real welcomeLogoWidth: 100
|
||||
property real welcomeLogoHeight: 100
|
||||
property real wizardButtonWidth: 400
|
||||
@ -541,9 +544,9 @@ Item {
|
||||
property real welcomeRectTopMargin: 90
|
||||
property real welcomePageSpacing: 13
|
||||
property real welcomeGridWidth: 3 * JamiTheme.tipBoxWidth + 2 * JamiTheme.welcomePageSpacing
|
||||
property real welcomeHalfGridWidth: (welcomeGridWidth - JamiTheme.welcomePageSpacing) / 2
|
||||
property real welcomeThirdGridWidth: (welcomeGridWidth - JamiTheme.welcomePageSpacing) / 3
|
||||
property real welcomeShortGridWidth: 2 * JamiTheme.tipBoxWidth + JamiTheme.welcomePageSpacing
|
||||
readonly property string welcomeBg: darkTheme ? JamiResources.bg_darkmode_id_jami_png : JamiResources.bg_lightmode_id_jami_png
|
||||
readonly property string welcomeBg: darkTheme ? JamiResources.background_don_dark_jpg : JamiResources.background_don_white_jpg
|
||||
property color welcomeBlockColor: darkTheme ? "#4D000000" : "#4DFFFFFF"
|
||||
|
||||
// WizardView Advanced Account Settings
|
||||
@ -662,7 +665,17 @@ Item {
|
||||
property color donationBackgroundColor: "#D5E4EF"
|
||||
property string donationUrl: "https://jami.net/donate/"
|
||||
|
||||
//Connection monitoring
|
||||
property color connectionMonitoringTableColor1: darkTheme ? "#4D4D4D" : "#f0efef"
|
||||
property color connectionMonitoringTableColor2: darkTheme ? "#333333" : "#f6f5f5"
|
||||
property color connectionMonitoringHeaderColor: darkTheme ? "#6F6F6F" : "#d1d1d1"
|
||||
|
||||
function setTheme(dark) {
|
||||
darkTheme = dark;
|
||||
}
|
||||
|
||||
//Chat setting page
|
||||
property color chatSettingButtonBackgroundColor: darkTheme ? "#303030" : "#F0EFEF"
|
||||
property color chatSettingButtonBorderColor: darkTheme ? "#03B9E9" : "#005699"
|
||||
property color chatSettingButtonTextColor: textColor
|
||||
}
|
||||
|
||||
@ -21,10 +21,16 @@
|
||||
#include "contactadapter.h"
|
||||
|
||||
#include "lrcinstance.h"
|
||||
#include "qmlregister.h"
|
||||
|
||||
ContactAdapter::ContactAdapter(LRCInstance* instance, QObject* parent)
|
||||
: QmlAdapterBase(instance, parent)
|
||||
, connectionInfoListModel_(new ConnectionInfoListModel(lrcInstance_, this))
|
||||
{
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_MODELS,
|
||||
connectionInfoListModel_.get(),
|
||||
"ConnectionInfoListModel");
|
||||
|
||||
selectableProxyModel_.reset(new SelectableProxyModel(this));
|
||||
if (lrcInstance_) {
|
||||
connectSignals();
|
||||
@ -246,6 +252,12 @@ ContactAdapter::removeContact(const QString& peerUri, bool banContact)
|
||||
accInfo.contactModel->removeContact(peerUri, banContact);
|
||||
}
|
||||
|
||||
void
|
||||
ContactAdapter::updateConnectionInfo()
|
||||
{
|
||||
connectionInfoListModel_->update();
|
||||
}
|
||||
|
||||
void
|
||||
ContactAdapter::connectSignals()
|
||||
{
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "qmladapterbase.h"
|
||||
#include "smartlistmodel.h"
|
||||
#include "conversationlistmodel.h"
|
||||
#include "connectioninfolistmodel.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSortFilterProxyModel>
|
||||
@ -90,6 +91,7 @@ public:
|
||||
Q_INVOKABLE void setSearchFilter(const QString& filter);
|
||||
Q_INVOKABLE void contactSelected(int index);
|
||||
Q_INVOKABLE void removeContact(const QString& peerUri, bool banContact);
|
||||
Q_INVOKABLE void updateConnectionInfo();
|
||||
|
||||
void connectSignals();
|
||||
|
||||
@ -104,6 +106,7 @@ private:
|
||||
SmartListModel::Type listModeltype_;
|
||||
QScopedPointer<SmartListModel> smartListModel_;
|
||||
QScopedPointer<SelectableProxyModel> selectableProxyModel_;
|
||||
QScopedPointer<ConnectionInfoListModel> connectionInfoListModel_;
|
||||
|
||||
QStringList defaultModerators_;
|
||||
|
||||
|
||||
@ -458,3 +458,15 @@ LRCInstance::set_selectedConvUid(QString selectedConvUid)
|
||||
Q_EMIT selectedConvUidChanged();
|
||||
}
|
||||
}
|
||||
|
||||
VectorMapStringString
|
||||
LRCInstance::getConnectionList(const QString& accountId, const QString& uid)
|
||||
{
|
||||
return Lrc::getConnectionList(accountId, uid);
|
||||
}
|
||||
|
||||
VectorMapStringString
|
||||
LRCInstance::getChannelList(const QString& accountId, const QString& uid)
|
||||
{
|
||||
return Lrc::getChannelList(accountId, uid);
|
||||
}
|
||||
@ -135,6 +135,10 @@ public:
|
||||
return debugMode_;
|
||||
}
|
||||
|
||||
VectorMapStringString getConnectionList(const QString& accountId, const QString& uid = {});
|
||||
|
||||
VectorMapStringString getChannelList(const QString& accountId, const QString& uid = {});
|
||||
|
||||
Q_SIGNALS:
|
||||
void accountListChanged();
|
||||
void selectedConvUidChanged();
|
||||
|
||||
@ -105,7 +105,8 @@ ScreenInfo::onPhysicalDotsPerInchChanged()
|
||||
}
|
||||
|
||||
MainApplication::MainApplication(int& argc, char** argv)
|
||||
: QApplication(argc, argv), isCleanupped(false)
|
||||
: QApplication(argc, argv)
|
||||
, isCleanupped(false)
|
||||
{
|
||||
const char* qtVersion = qVersion();
|
||||
qInfo() << "Using Qt runtime version:" << qtVersion;
|
||||
@ -129,11 +130,12 @@ MainApplication::init()
|
||||
// This 2-phase initialisation prevents ephemeral instances from
|
||||
// performing unnecessary tasks, like initializing the webengine.
|
||||
engine_.reset(new QQmlApplicationEngine(this));
|
||||
connectivityMonitor_.reset(new ConnectivityMonitor(this));
|
||||
settingsManager_.reset(new AppSettingsManager(this));
|
||||
systemTray_.reset(new SystemTray(settingsManager_.get(), this));
|
||||
|
||||
QObject::connect(settingsManager_.get(),
|
||||
connectivityMonitor_ = new ConnectivityMonitor(this);
|
||||
settingsManager_ = new AppSettingsManager(this);
|
||||
systemTray_ = new SystemTray(settingsManager_, this);
|
||||
|
||||
QObject::connect(settingsManager_,
|
||||
&AppSettingsManager::retranslate,
|
||||
engine_.get(),
|
||||
&QQmlApplicationEngine::retranslate);
|
||||
@ -146,7 +148,7 @@ MainApplication::init()
|
||||
setApplicationFont();
|
||||
|
||||
initLrc(runOptions_[Option::UpdateUrl].toString(),
|
||||
connectivityMonitor_.get(),
|
||||
connectivityMonitor_,
|
||||
runOptions_[Option::Debug].toBool(),
|
||||
runOptions_[Option::MuteDaemon].toBool());
|
||||
|
||||
@ -168,7 +170,7 @@ MainApplication::init()
|
||||
}
|
||||
#endif
|
||||
|
||||
connect(connectivityMonitor_.get(), &ConnectivityMonitor::connectivityChanged, this, [this] {
|
||||
connect(connectivityMonitor_, &ConnectivityMonitor::connectivityChanged, this, [this] {
|
||||
QTimer::singleShot(500, this, [&]() { lrcInstance_->connectivityChanged(); });
|
||||
});
|
||||
|
||||
@ -195,6 +197,12 @@ MainApplication::init()
|
||||
engine_.get()->rootContext()->setContextProperty("WITH_WEBENGINE", QVariant(false));
|
||||
#endif
|
||||
|
||||
#ifdef APPSTORE
|
||||
engine_.get()->rootContext()->setContextProperty("APPSTORE", QVariant(true));
|
||||
#else
|
||||
engine_.get()->rootContext()->setContextProperty("APPSTORE", QVariant(false));
|
||||
#endif
|
||||
|
||||
initQmlLayer();
|
||||
|
||||
settingsManager_->setValue(Settings::Key::StartMinimized,
|
||||
@ -341,10 +349,10 @@ MainApplication::initQmlLayer()
|
||||
{
|
||||
// Expose custom types to the QML engine.
|
||||
Utils::registerTypes(engine_.get(),
|
||||
systemTray_.get(),
|
||||
lrcInstance_.get(),
|
||||
settingsManager_.get(),
|
||||
connectivityMonitor_.get(),
|
||||
systemTray_,
|
||||
settingsManager_,
|
||||
connectivityMonitor_,
|
||||
&screenInfo_,
|
||||
this);
|
||||
|
||||
@ -375,7 +383,7 @@ MainApplication::initSystray()
|
||||
QAction* restoreAction = new QAction(tr("&Show Jami"), this);
|
||||
connect(restoreAction, &QAction::triggered, this, &MainApplication::restoreApp);
|
||||
|
||||
connect(systemTray_.get(),
|
||||
connect(systemTray_,
|
||||
&QSystemTrayIcon::activated,
|
||||
this,
|
||||
[this](QSystemTrayIcon::ActivationReason reason) {
|
||||
@ -409,10 +417,8 @@ MainApplication::cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
void
|
||||
MainApplication::setEventFilter()
|
||||
{
|
||||
installEventFilter(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imagedownloader.h"
|
||||
#include "lrcinstance.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
@ -36,7 +35,6 @@
|
||||
class ConnectivityMonitor;
|
||||
class AppSettingsManager;
|
||||
class SystemTray;
|
||||
class CallAdapter;
|
||||
|
||||
// Provides information about the screen the app is displayed on
|
||||
class ScreenInfo : public QObject
|
||||
@ -82,17 +80,20 @@ public:
|
||||
return runOptions_[opt];
|
||||
};
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
Q_INVOKABLE void setEventFilter();
|
||||
|
||||
bool eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
#ifdef Q_OS_MACOS
|
||||
|
||||
if (event->type() == QEvent::ApplicationActivate) {
|
||||
restoreApp();
|
||||
}
|
||||
|
||||
#endif // Q_OS_MACOS
|
||||
|
||||
return QApplication::eventFilter(object, event);
|
||||
}
|
||||
#endif // Q_OS_MACOS
|
||||
|
||||
Q_SIGNALS:
|
||||
void closeRequested();
|
||||
@ -112,13 +113,14 @@ private:
|
||||
private:
|
||||
std::map<Option, QVariant> runOptions_;
|
||||
|
||||
// We want to be explicit about the destruction order of these objects
|
||||
QScopedPointer<QQmlApplicationEngine> engine_;
|
||||
QScopedPointer<LRCInstance> lrcInstance_;
|
||||
|
||||
QScopedPointer<ConnectivityMonitor> connectivityMonitor_;
|
||||
QScopedPointer<AppSettingsManager> settingsManager_;
|
||||
QScopedPointer<SystemTray> systemTray_;
|
||||
QScopedPointer<ImageDownloader> imageDownloader_;
|
||||
// These are injected into the QML layer along with our LRCInstance
|
||||
ConnectivityMonitor* connectivityMonitor_;
|
||||
SystemTray* systemTray_;
|
||||
AppSettingsManager* settingsManager_;
|
||||
|
||||
ScreenInfo screenInfo_;
|
||||
|
||||
|
||||
@ -123,13 +123,13 @@ Control {
|
||||
"Name": JamiStrings.shareScreen,
|
||||
"IconSource": JamiResources.laptop_black_24dp_svg
|
||||
});
|
||||
if (Qt.platform.os.toString() !== "osx") {
|
||||
if (Qt.platform.os.toString() !== "osx" && !UtilsAdapter.isWayland()) {
|
||||
shareModel.append({
|
||||
"Name": JamiStrings.shareWindow,
|
||||
"IconSource": JamiResources.window_black_24dp_svg
|
||||
});
|
||||
}
|
||||
if (Qt.platform.os.toString() !== "windows") {
|
||||
if (Qt.platform.os.toString() !== "windows" && !UtilsAdapter.isWayland()) {
|
||||
// temporarily disable for windows
|
||||
shareModel.append({
|
||||
"Name": JamiStrings.shareScreenArea,
|
||||
|
||||
@ -25,7 +25,6 @@ import "../../commoncomponents"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias chatViewContainer: ongoingCallPage.chatViewContainer
|
||||
property alias contentView: callStackMainView
|
||||
|
||||
@ -49,6 +48,16 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CallOverlayModel
|
||||
function onPttKeyPressed() {
|
||||
CallAdapter.muteAudioToggle();
|
||||
}
|
||||
function onPttKeyReleased() {
|
||||
CallAdapter.muteAudioToggle();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this should all be done by listening to
|
||||
// parent visibility change or parent `Component.onDestruction`
|
||||
function needToCloseInCallConversationAndPotentialWindow() {
|
||||
|
||||
@ -106,13 +106,18 @@ Popup {
|
||||
height: Top || Bottom ? 10 : 45
|
||||
|
||||
background: Rectangle {
|
||||
radius: 5
|
||||
visible: !Top && !Bottom
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
color: menuItem.down ? "#c4aaaaaa" : menuItem.hovered ? "#c4777777" : "transparent"
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 5
|
||||
anchors.rightMargin: 5
|
||||
visible: !Top && !Bottom
|
||||
ResponsiveImage {
|
||||
Layout.leftMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
@ -86,8 +86,7 @@ Rectangle {
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: 8
|
||||
|
||||
preferredSize: 24
|
||||
|
||||
//preferredSize: 24
|
||||
mirror: UtilsAdapter.isRTL
|
||||
|
||||
source: JamiResources.back_24dp_svg
|
||||
@ -155,12 +154,12 @@ Rectangle {
|
||||
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
Layout.preferredHeight: 30
|
||||
Layout.preferredWidth: 40 + (isOpen? JamiTheme.searchbarSize : 0)
|
||||
Layout.preferredWidth: 40 + (isOpen ? JamiTheme.searchbarSize : 0)
|
||||
colorSearchBar: JamiTheme.backgroundColor
|
||||
|
||||
hoverButtonRadius: JamiTheme.chatViewHeaderButtonRadius
|
||||
|
||||
Behavior on Layout.preferredWidth {
|
||||
Behavior on Layout.preferredWidth {
|
||||
NumberAnimation {
|
||||
duration: 150
|
||||
}
|
||||
@ -168,7 +167,7 @@ Rectangle {
|
||||
|
||||
visible: root.swarmDetailsVisibility
|
||||
|
||||
onSearchBarTextChanged: function(text){
|
||||
onSearchBarTextChanged: function (text) {
|
||||
MessagesAdapter.searchbarPrompt = text;
|
||||
}
|
||||
|
||||
|
||||
@ -104,7 +104,6 @@ ContextMenuAutoLoader {
|
||||
canTrigger: hasCall
|
||||
itemName: JamiStrings.endCall
|
||||
iconSource: JamiResources.ic_call_end_white_24dp_svg
|
||||
addMenuSeparatorAfter: contactType !== Profile.Type.SIP && (contactType === Profile.Type.PENDING || !hasCall)
|
||||
onClicked: CallAdapter.hangUpACall(responsibleAccountId, responsibleConvUid)
|
||||
},
|
||||
GeneralMenuItem {
|
||||
@ -129,7 +128,6 @@ ContextMenuAutoLoader {
|
||||
canTrigger: !hasCall && contactType !== Profile.Type.SIP && !root.isBanned && isCoreDialog && root.idText !== CurrentAccount.uri
|
||||
itemName: JamiStrings.blockContact
|
||||
iconSource: JamiResources.block_black_24dp_svg
|
||||
addMenuSeparatorAfter: canTrigger
|
||||
onClicked: {
|
||||
var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/ConfirmDialog.qml", {
|
||||
"title": JamiStrings.confirmAction,
|
||||
@ -147,7 +145,6 @@ ContextMenuAutoLoader {
|
||||
canTrigger: root.isBanned
|
||||
itemName: JamiStrings.reinstateContact
|
||||
iconSource: JamiResources.round_remove_circle_24dp_svg
|
||||
addMenuSeparatorAfter: canTrigger
|
||||
onClicked: MessagesAdapter.unbanConversation(responsibleConvUid)
|
||||
},
|
||||
GeneralMenuItem {
|
||||
|
||||
@ -45,7 +45,7 @@ Item {
|
||||
ctxMenu.y = mouse.y;
|
||||
ctxMenu.openMenu();
|
||||
} else {
|
||||
MessagesAdapter.openUrl(name.fileSource);
|
||||
MessagesAdapter.openUrl("file://" + Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,8 +109,7 @@ Rectangle {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
// When the user clicks on "Not now", we set the donation date to 7 days from now (1 for the test)
|
||||
// TODO reset to 7 days
|
||||
UtilsAdapter.setAppValue(Settings.Key.DonateVisibleDate, new Date(new Date().getTime() + 1 * 24 * 60 * 60 * 1000).toISOString().slice(0, 16).replace("T", " "));
|
||||
UtilsAdapter.setAppValue(Settings.Key.DonationVisibleDate, new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000).toISOString().slice(0, 16).replace("T", " "));
|
||||
donation.donationVisible = Qt.binding(() => JamiQmlUtils.isDonationBannerVisible());
|
||||
}
|
||||
}
|
||||
|
||||
105
src/app/mainview/components/DonationTipBox.qml
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import "../../commoncomponents"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
focus: true
|
||||
width: parent.width
|
||||
height: backupLayout.height
|
||||
|
||||
property real iconSize: 26
|
||||
property real margin: 5
|
||||
property real preferredWidth: 170
|
||||
|
||||
property real maxHeight: 250
|
||||
|
||||
property color textColor: JamiTheme.textColor
|
||||
property color iconColor: JamiTheme.tintedBlue
|
||||
|
||||
ColumnLayout {
|
||||
id: backupLayout
|
||||
|
||||
anchors.top: parent.top
|
||||
width: parent.width
|
||||
|
||||
RowLayout {
|
||||
id: rowlayout
|
||||
|
||||
Layout.leftMargin: 15
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
|
||||
ResponsiveImage {
|
||||
id: icon
|
||||
|
||||
visible: !opened
|
||||
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.topMargin: root.margin
|
||||
Layout.preferredWidth: root.iconSize
|
||||
Layout.preferredHeight: root.iconSize
|
||||
|
||||
containerHeight: Layout.preferredHeight
|
||||
containerWidth: Layout.preferredWidth
|
||||
|
||||
color: JamiTheme.tintedBlue
|
||||
|
||||
source: JamiResources.favorite_black_24dp_svg
|
||||
}
|
||||
|
||||
Text {
|
||||
id: title
|
||||
text: JamiStrings.donation
|
||||
color: root.textColor
|
||||
font.weight: Font.Medium
|
||||
Layout.topMargin: root.margin
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.leftMargin: root.margin
|
||||
Layout.preferredWidth: root.preferredWidth - 2 * root.margin - root.iconSize
|
||||
font.pixelSize: JamiTheme.tipBoxTitleFontSize
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
elide: Qt.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: content
|
||||
Layout.preferredWidth: root.preferredWidth
|
||||
focus: true
|
||||
Layout.leftMargin: 20
|
||||
Layout.topMargin: 8
|
||||
Layout.bottomMargin: 8
|
||||
font.pixelSize: JamiTheme.tipBoxContentFontSize
|
||||
visible: true
|
||||
wrapMode: Text.WordWrap
|
||||
font.weight: Font.Normal
|
||||
text: JamiStrings.donationTipBoxText
|
||||
color: root.textColor
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
linkColor: JamiTheme.buttonTintedBlue
|
||||
onLinkActivated: {
|
||||
Qt.openUrlExternally(JamiTheme.donationUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,6 +61,7 @@ RowLayout {
|
||||
color: JamiTheme.transparentColor
|
||||
ComboBox {
|
||||
id: showMoreButton
|
||||
focus: true
|
||||
width: JamiTheme.chatViewFooterButtonSize
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
anchors.bottom: parent.bottom
|
||||
@ -103,19 +104,20 @@ RowLayout {
|
||||
toolTipMoreButton.text = sharePopup.opened ? JamiStrings.showLess : JamiStrings.showMore;
|
||||
}
|
||||
|
||||
onPressedChanged: {
|
||||
if (sharePopup.enabled)
|
||||
sharePopup.close();
|
||||
}
|
||||
|
||||
popup: SharePopup {
|
||||
popup: ShareMenu {
|
||||
id: sharePopup
|
||||
y: -180
|
||||
x: -20
|
||||
|
||||
menuMoreButton: listViewMoreButton.menuMoreButton
|
||||
|
||||
onClosed: messageBar.textAreaObj.forceActiveFocus()
|
||||
onAudioRecordMessageButtonClicked: {
|
||||
root.audioRecordMessageButtonClicked();
|
||||
}
|
||||
onVideoRecordMessageButtonClicked: {
|
||||
root.videoRecordMessageButtonClicked();
|
||||
}
|
||||
onShowMapClicked: {
|
||||
root.showMapClicked();
|
||||
}
|
||||
modelList: listViewMoreButton.menuMoreButton
|
||||
y: showMoreButton.y + 31
|
||||
x: showMoreButton.x - 3
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -141,12 +143,10 @@ RowLayout {
|
||||
|
||||
onWidthChanged: {
|
||||
height = Qt.binding(() => root.height);
|
||||
if (width < 468) {
|
||||
if (width < JamiTheme.messageBarMinimumWidth) {
|
||||
showTypoSecond = false;
|
||||
} else {
|
||||
if (width >= 468) {
|
||||
showTypoSecond = true;
|
||||
}
|
||||
showTypoSecond = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,6 +307,8 @@ RowLayout {
|
||||
context: Qt.ApplicationShortcut
|
||||
onActivated: {
|
||||
showTypo = !showTypo;
|
||||
messageBarTextArea.isShowTypo = showTypo;
|
||||
UtilsAdapter.setAppValue(Settings.Key.ShowMardownOption, showTypo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -761,7 +763,7 @@ RowLayout {
|
||||
id: markdownPopup
|
||||
y: 1.5 * parent.height
|
||||
x: -parent.width * 2
|
||||
width: 155
|
||||
width: 105
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
|
||||
menuTypoActionsSecond: listViewTypoSecond.menuTypoActionsSecond
|
||||
@ -817,20 +819,6 @@ RowLayout {
|
||||
onTriggered: function clickAction() {
|
||||
listViewTypo.addPrefixStyle(root.text, messageBarTextArea.selectionStart, messageBarTextArea.selectionEnd, "", true);
|
||||
}
|
||||
},
|
||||
Action {
|
||||
id: shiftEnterActiom
|
||||
property var iconSrc: JamiResources.shift_enter_black_24dp_svg
|
||||
property var shortcutText: chatViewEnterIsNewLine ? JamiStrings.enterNewLine : JamiStrings.shiftEnterNewLine
|
||||
property var imageColor: chatViewEnterIsNewLine ? JamiTheme.chatViewFooterImgHoverColor : "#7f7f7f"
|
||||
property var normalColor: chatViewEnterIsNewLine ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor
|
||||
property var hasShortcut: false
|
||||
property var shortcutKey: null
|
||||
property bool isStyle: false
|
||||
onTriggered: function clickAction() {
|
||||
root.chatViewEnterIsNewLine = !root.chatViewEnterIsNewLine;
|
||||
UtilsAdapter.setAppValue(Settings.Key.ChatViewEnterIsNewLine, chatViewEnterIsNewLine);
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -906,17 +894,11 @@ RowLayout {
|
||||
|
||||
onClicked: {
|
||||
showTypo = !showTypo;
|
||||
messageBarTextArea.isShowTypo = showTypo;
|
||||
if (messageBar.width < messageBarLayoutMaximumWidth + sendMessageButton.width + 2 * JamiTheme.preferredMarginSize)
|
||||
showTypoSecond = false;
|
||||
if (!showDefault)
|
||||
showDefault = true;
|
||||
if (showTypo) {
|
||||
root.chatViewEnterIsNewLine = true;
|
||||
UtilsAdapter.setAppValue(Settings.Key.ChatViewEnterIsNewLine, true);
|
||||
} else {
|
||||
root.chatViewEnterIsNewLine = false;
|
||||
UtilsAdapter.setAppValue(Settings.Key.ChatViewEnterIsNewLine, false);
|
||||
}
|
||||
UtilsAdapter.setAppValue(Settings.Key.ShowMardownOption, showTypo);
|
||||
UtilsAdapter.setAppValue(Settings.Key.ShowSendOption, !showDefault);
|
||||
}
|
||||
@ -1160,7 +1142,7 @@ RowLayout {
|
||||
imageContainerHeight: 25
|
||||
radius: 5
|
||||
source: JamiResources.preview_black_24dp_svg
|
||||
normalColor: showPreview ? hoveredColor : JamiTheme.transparentColor
|
||||
normalColor: showPreview ? hoveredColor : JamiTheme.primaryBackgroundColor
|
||||
imageColor: (hovered || showPreview) ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
|
||||
hoveredColor: JamiTheme.hoveredButtonColor
|
||||
pressedColor: hoveredColor
|
||||
|
||||
@ -41,6 +41,7 @@ JamiFlickable {
|
||||
property alias selectionStart: textArea.selectionStart
|
||||
property alias selectionEnd: textArea.selectionEnd
|
||||
property bool showPreview: false
|
||||
property bool isShowTypo: UtilsAdapter.getAppValue(Settings.Key.ShowMardownOption)
|
||||
|
||||
ScrollBar.vertical.visible: textArea.text
|
||||
ScrollBar.horizontal.visible: textArea.text
|
||||
@ -206,7 +207,13 @@ JamiFlickable {
|
||||
const isEnterNewLine = UtilsAdapter.getAppValue(Settings.Key.ChatViewEnterIsNewLine);
|
||||
const isShiftPressed = (keyEvent.modifiers & Qt.ShiftModifier);
|
||||
const isCtrlPressed = (keyEvent.modifiers & Qt.ControlModifier);
|
||||
if (!isEnterNewLine && !isShiftPressed || isCtrlPressed) {
|
||||
if (!root.isShowTypo && !isShiftPressed) {
|
||||
root.sendMessagesRequired();
|
||||
keyEvent.accepted = true;
|
||||
} else if (isCtrlPressed) {
|
||||
root.sendMessagesRequired();
|
||||
keyEvent.accepted = true;
|
||||
} else if (!isEnterNewLine && !isShiftPressed) {
|
||||
root.sendMessagesRequired();
|
||||
keyEvent.accepted = true;
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
|
||||
* Author: Albert Babí <albert.babi@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -22,45 +21,9 @@ import "../../commoncomponents"
|
||||
PushButton {
|
||||
id: root
|
||||
|
||||
property alias toolTipText: toolTip.text
|
||||
|
||||
normalColor: JamiTheme.buttonConference
|
||||
hoveredColor: JamiTheme.buttonConferenceHovered
|
||||
pressedColor: JamiTheme.buttonConferencePressed
|
||||
|
||||
imageColor: JamiTheme.whiteColor
|
||||
hoverEnabled: false
|
||||
|
||||
Rectangle {
|
||||
id: toolTipRect
|
||||
height: 16
|
||||
width: toolTip.width + 8
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
top: parent.bottom
|
||||
topMargin: isBarLayout ? 6 : 2
|
||||
}
|
||||
color: isBarLayout ? JamiTheme.darkGreyColorOpacity : "transparent"
|
||||
visible: hover.hovered && !isSmall
|
||||
radius: 2
|
||||
|
||||
Text {
|
||||
id: toolTip
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: JamiTheme.whiteColor
|
||||
font.pointSize: JamiTheme.tinyFontSize
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
|
||||
HoverHandler {
|
||||
id: hover
|
||||
onHoveredChanged: {
|
||||
root.forceHovered = hover.hovered;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ Rectangle {
|
||||
hoveredColor: JamiTheme.hoveredButtonColor
|
||||
source: JamiResources.ic_baseline_search_24dp_svg
|
||||
toolTipText: JamiStrings.search
|
||||
normalColor: "transparent"
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
imageColor: {
|
||||
if (reductionEnabled) {
|
||||
if (hovered) {
|
||||
|
||||
@ -338,7 +338,7 @@ SidePanelBase {
|
||||
id: smartListLayout
|
||||
|
||||
width: parent.width
|
||||
anchors.top: donation.donationVisible ? donation.bottom : sidePanelTabBar.bottom
|
||||
anchors.top: donation.donationVisible ? donation.bottom : searchStatusRect.bottom
|
||||
anchors.topMargin: (sidePanelTabBar.visible || searchStatusRect.visible) ? 0 : 12
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
|
||||
@ -51,7 +51,6 @@ Rectangle {
|
||||
anchors.right: parent.right
|
||||
height: headerRow.implicitHeight + JamiTheme.preferredMarginSize + settingsTabButton.height
|
||||
|
||||
|
||||
RowLayout {
|
||||
id: headerRow
|
||||
spacing: 15
|
||||
@ -105,7 +104,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
editMode: false
|
||||
isPersistent: false
|
||||
|
||||
placeholderText: JamiStrings.title
|
||||
|
||||
onActiveFocusChanged: {
|
||||
@ -148,7 +147,6 @@ Rectangle {
|
||||
onAccepted: ConversationsAdapter.updateConversationDescription(LRCInstance.selectedConvUid, dynamicText)
|
||||
|
||||
editMode: false
|
||||
isPersistent: false
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (!activeFocus) {
|
||||
|
||||
@ -37,7 +37,6 @@ FocusScope {
|
||||
property color textColor: JamiTheme.textColor
|
||||
property color iconColor: JamiTheme.tintedBlue
|
||||
|
||||
|
||||
property string customizeTip: "CustomizeTipBox {}"
|
||||
|
||||
property string backupTip: "BackupTipBox {" + " onIgnore: {" + " root.ignoreClicked()" + " }" + "}"
|
||||
@ -56,7 +55,6 @@ FocusScope {
|
||||
focus: true
|
||||
activeFocusOnTab: true
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: rect
|
||||
anchors.fill: parent
|
||||
@ -73,6 +71,18 @@ FocusScope {
|
||||
width: parent.width
|
||||
anchors.topMargin: 10
|
||||
|
||||
Loader {
|
||||
id: loader_donationTip
|
||||
active: type === "donation"
|
||||
focus: true
|
||||
sourceComponent: DonationTipBox {
|
||||
maxHeight: root.maximumHeight
|
||||
textColor: root.textColor
|
||||
iconColor: root.iconColor
|
||||
}
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader_backupTip
|
||||
active: type === "backup"
|
||||
@ -95,7 +105,6 @@ FocusScope {
|
||||
}
|
||||
width: parent.width
|
||||
focus: true
|
||||
|
||||
}
|
||||
Loader {
|
||||
id: loader_infoTip
|
||||
@ -106,7 +115,6 @@ FocusScope {
|
||||
iconColor: root.iconColor
|
||||
}
|
||||
width: parent.width
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -119,6 +127,7 @@ FocusScope {
|
||||
|
||||
TapHandler {
|
||||
target: rect
|
||||
enabled: type !== "donation"
|
||||
onTapped: {
|
||||
return opened ? focus = false : root.forceActiveFocus();
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ Item {
|
||||
property color textColor: JamiTheme.textColor
|
||||
property color idColor: JamiTheme.welcomeBlockColor
|
||||
property color contentIdColor: JamiTheme.tintedBlue
|
||||
property bool hasTitle: true
|
||||
property bool hasTitle: false
|
||||
property bool hasDescription: true
|
||||
|
||||
property string title: JamiStrings.welcomeToJami
|
||||
@ -39,8 +39,6 @@ Item {
|
||||
|
||||
property real contentWidth: welcomeInfo.width - 2 * JamiTheme.mainViewMargin
|
||||
|
||||
|
||||
|
||||
function getHeight() {
|
||||
return bgRect.height;
|
||||
}
|
||||
@ -70,7 +68,6 @@ Item {
|
||||
Loader {
|
||||
id: loader_identifierDescription
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: contentWidth
|
||||
Layout.preferredHeight: item ? item.contentHeight : 0
|
||||
Layout.bottomMargin: loader_bottomIdentifier.item ? JamiTheme.mainViewMargin - 10 : 0
|
||||
sourceComponent: {
|
||||
@ -93,7 +90,6 @@ Item {
|
||||
sourceComponent: JamiIdentifier {
|
||||
backgroundColor: welcomeInfo.idColor
|
||||
contentColor: contentIdColor
|
||||
|
||||
}
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredHeight: active ? item.getHeight() : 0
|
||||
@ -133,7 +129,7 @@ Item {
|
||||
|
||||
width: welcomeInfo.contentWidth
|
||||
height: contentHeight
|
||||
font.pixelSize: JamiTheme.headerFontSize
|
||||
font.pixelSize: JamiTheme.tipBoxContentFontSize
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
|
||||
@ -36,18 +36,18 @@ Item {
|
||||
width: getWidth()
|
||||
|
||||
function getWidth() {
|
||||
return JamiTheme.welcomeHalfGridWidth;
|
||||
return JamiTheme.welcomeThirdGridWidth;
|
||||
}
|
||||
|
||||
function getHeight() {
|
||||
return 120;
|
||||
return 80;
|
||||
}
|
||||
|
||||
CachedImage {
|
||||
id: cachedImgLogo
|
||||
objectName: "cachedImgLogo"
|
||||
downloadUrl: logoUrl
|
||||
defaultImage: JamiResources.jami_logo_icon_svg
|
||||
defaultImage: JamiTheme.welcomeLogo
|
||||
visible: welcomeLogo.visible
|
||||
height: parent.height * logoSize
|
||||
width: parent.width * logoSize
|
||||
|
||||
@ -49,7 +49,7 @@ ListSelectionView {
|
||||
|
||||
property bool hasCustomUi: false
|
||||
|
||||
property bool hasTitle: true
|
||||
property bool hasTitle: false
|
||||
property bool hasDescription: true
|
||||
|
||||
property bool hasCustomTitle: false
|
||||
@ -95,7 +95,7 @@ ListSelectionView {
|
||||
|
||||
function updateUiFlags() {
|
||||
hasCustomUi = Object.keys(uiCustomization).length > 0;
|
||||
hasTitle = hasCustomUi ? uiCustomization.title !== "" : true;
|
||||
hasTitle = hasCustomUi ? uiCustomization.title !== "" : false;
|
||||
hasDescription = hasCustomUi ? uiCustomization.description !== "" : true;
|
||||
title = hasCustomUi && uiCustomization.title !== undefined ? uiCustomization.title : JamiStrings.welcomeToJami;
|
||||
description = hasCustomUi && uiCustomization.description !== undefined ? uiCustomization.description : JamiStrings.hereIsIdentifier;
|
||||
@ -266,8 +266,9 @@ ListSelectionView {
|
||||
}
|
||||
|
||||
tertiary: true
|
||||
secHoveredColor: JamiTheme.secAndTertiHoveredBackgroundColor
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
preferredWidth: text.width
|
||||
preferredWidth: textSize.width + 2 * JamiTheme.preferredMarginSize
|
||||
text: JamiStrings.aboutJami
|
||||
|
||||
onClicked: viewCoordinator.presentDialog(appWindow, "mainview/components/AboutPopUp.qml")
|
||||
@ -282,6 +283,7 @@ ListSelectionView {
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: JamiTheme.preferredMarginSize
|
||||
preferredSize: 30
|
||||
anchors.verticalCenter: aboutJami.verticalCenter
|
||||
imageContainerWidth: JamiTheme.pushButtonSize
|
||||
imageContainerHeight: JamiTheme.pushButtonSize
|
||||
|
||||
|
||||
42
src/app/platform/local/pttlistener.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pttlistener.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVariant>
|
||||
|
||||
class PTTListener::Impl : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Impl(PTTListener* parent)
|
||||
: QObject(parent)
|
||||
{}
|
||||
|
||||
~Impl() = default;
|
||||
};
|
||||
|
||||
PTTListener::PTTListener(AppSettingsManager* settingsManager, QObject* parent)
|
||||
: settingsManager_(settingsManager)
|
||||
, QObject(parent)
|
||||
, pimpl_(std::make_unique<Impl>(this))
|
||||
{}
|
||||
|
||||
PTTListener::~PTTListener() = default;
|
||||
|
||||
#include "pttlistener.moc"
|
||||
390
src/app/platform/macos/pttlistener.cpp
Normal file
@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#include "pttlistener.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVariant>
|
||||
|
||||
class PTTListener::Impl : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Impl(PTTListener* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
qApp->setProperty("PTTListener", QVariant::fromValue(parent));
|
||||
}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
stopListening();
|
||||
};
|
||||
|
||||
void startListening()
|
||||
{
|
||||
CGEventMask eventMask = (1 << kCGEventKeyDown) | (1 << kCGEventKeyUp);
|
||||
CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap,
|
||||
kCGHeadInsertEventTap,
|
||||
kCGEventTapOptionDefault,
|
||||
eventMask,
|
||||
CGEventCallback,
|
||||
this);
|
||||
|
||||
if (eventTap) {
|
||||
CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,
|
||||
eventTap,
|
||||
0);
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
|
||||
CFRelease(runLoopSource);
|
||||
|
||||
CGEventTapEnable(eventTap, true);
|
||||
} else {
|
||||
qDebug() << "Impossible to create the keyboard tap.";
|
||||
}
|
||||
}
|
||||
|
||||
void stopListening()
|
||||
{
|
||||
if (eventTap) {
|
||||
CGEventTapEnable(eventTap, false);
|
||||
CFRelease(eventTap);
|
||||
}
|
||||
}
|
||||
|
||||
static CGEventRef CGEventCallback(CGEventTapProxy proxy,
|
||||
CGEventType type,
|
||||
CGEventRef event,
|
||||
void* refcon)
|
||||
{
|
||||
auto* pThis = qApp->property("PTTListener").value<PTTListener*>();
|
||||
CGKeyCode keycode = (CGKeyCode) CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode);
|
||||
if (pThis == nullptr) {
|
||||
qWarning() << "PTTListener not found";
|
||||
return {};
|
||||
}
|
||||
CGKeyCode pttKey = (CGKeyCode) pThis->pimpl_->qtKeyTokVKey(pThis->getCurrentKey());
|
||||
static bool isKeyDown = false;
|
||||
if (keycode == pttKey) {
|
||||
if (type == kCGEventKeyDown && !isKeyDown) {
|
||||
Q_EMIT pThis->pttKeyPressed();
|
||||
isKeyDown = true;
|
||||
} else if (type == kCGEventKeyUp && isKeyDown) {
|
||||
Q_EMIT pThis->pttKeyReleased();
|
||||
isKeyDown = false;
|
||||
}
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
quint32 qtKeyTokVKey(Qt::Key key);
|
||||
|
||||
private:
|
||||
CFMachPortRef eventTap;
|
||||
};
|
||||
|
||||
PTTListener::PTTListener(AppSettingsManager* settingsManager, QObject* parent)
|
||||
: settingsManager_(settingsManager)
|
||||
, QObject(parent)
|
||||
, pimpl_(std::make_unique<Impl>(this))
|
||||
{}
|
||||
|
||||
PTTListener::~PTTListener() = default;
|
||||
|
||||
void
|
||||
PTTListener::startListening()
|
||||
{
|
||||
pimpl_->startListening();
|
||||
}
|
||||
|
||||
void
|
||||
PTTListener::stopListening()
|
||||
{
|
||||
pimpl_->stopListening();
|
||||
}
|
||||
|
||||
quint32
|
||||
PTTListener::Impl::qtKeyTokVKey(Qt::Key key)
|
||||
{
|
||||
UTF16Char ch;
|
||||
// Constants found in NSEvent.h from AppKit.framework
|
||||
switch (key) {
|
||||
case Qt::Key_Return:
|
||||
return kVK_Return;
|
||||
case Qt::Key_Enter:
|
||||
return kVK_ANSI_KeypadEnter;
|
||||
case Qt::Key_Tab:
|
||||
return kVK_Tab;
|
||||
case Qt::Key_Space:
|
||||
return kVK_Space;
|
||||
case Qt::Key_Backspace:
|
||||
return kVK_Delete;
|
||||
case Qt::Key_Control:
|
||||
return kVK_Command;
|
||||
case Qt::Key_Shift:
|
||||
return kVK_Shift;
|
||||
case Qt::Key_CapsLock:
|
||||
return kVK_CapsLock;
|
||||
case Qt::Key_Option:
|
||||
return kVK_Option;
|
||||
case Qt::Key_Meta:
|
||||
return kVK_Control;
|
||||
case Qt::Key_F17:
|
||||
return kVK_F17;
|
||||
case Qt::Key_VolumeUp:
|
||||
return kVK_VolumeUp;
|
||||
case Qt::Key_VolumeDown:
|
||||
return kVK_VolumeDown;
|
||||
case Qt::Key_F18:
|
||||
return kVK_F18;
|
||||
case Qt::Key_F19:
|
||||
return kVK_F19;
|
||||
case Qt::Key_F20:
|
||||
return kVK_F20;
|
||||
case Qt::Key_F5:
|
||||
return kVK_F5;
|
||||
case Qt::Key_F6:
|
||||
return kVK_F6;
|
||||
case Qt::Key_F7:
|
||||
return kVK_F7;
|
||||
case Qt::Key_F3:
|
||||
return kVK_F3;
|
||||
case Qt::Key_F8:
|
||||
return kVK_F8;
|
||||
case Qt::Key_F9:
|
||||
return kVK_F9;
|
||||
case Qt::Key_F11:
|
||||
return kVK_F11;
|
||||
case Qt::Key_F13:
|
||||
return kVK_F13;
|
||||
case Qt::Key_F16:
|
||||
return kVK_F16;
|
||||
case Qt::Key_F14:
|
||||
return kVK_F14;
|
||||
case Qt::Key_F10:
|
||||
return kVK_F10;
|
||||
case Qt::Key_F12:
|
||||
return kVK_F12;
|
||||
case Qt::Key_F15:
|
||||
return kVK_F15;
|
||||
case Qt::Key_Help:
|
||||
return kVK_Help;
|
||||
case Qt::Key_Home:
|
||||
return kVK_Home;
|
||||
case Qt::Key_PageUp:
|
||||
return kVK_PageUp;
|
||||
case Qt::Key_Delete:
|
||||
return kVK_ForwardDelete;
|
||||
case Qt::Key_F4:
|
||||
return kVK_F4;
|
||||
case Qt::Key_End:
|
||||
return kVK_End;
|
||||
case Qt::Key_F2:
|
||||
return kVK_F2;
|
||||
case Qt::Key_PageDown:
|
||||
return kVK_PageDown;
|
||||
case Qt::Key_F1:
|
||||
return kVK_F1;
|
||||
case Qt::Key_Left:
|
||||
return kVK_LeftArrow;
|
||||
case Qt::Key_Right:
|
||||
return kVK_RightArrow;
|
||||
case Qt::Key_Down:
|
||||
return kVK_DownArrow;
|
||||
case Qt::Key_Up:
|
||||
return kVK_UpArrow;
|
||||
default:;
|
||||
}
|
||||
|
||||
if (key == Qt::Key_Escape)
|
||||
ch = 27;
|
||||
else if (key == Qt::Key_Return)
|
||||
ch = 13;
|
||||
else if (key == Qt::Key_Enter)
|
||||
ch = 3;
|
||||
else if (key == Qt::Key_Tab)
|
||||
ch = 9;
|
||||
else
|
||||
ch = key;
|
||||
|
||||
CFDataRef currentLayoutData;
|
||||
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
|
||||
|
||||
if (currentKeyboard == nullptr)
|
||||
return 0;
|
||||
|
||||
currentLayoutData = (CFDataRef) TISGetInputSourceProperty(currentKeyboard,
|
||||
kTISPropertyUnicodeKeyLayoutData);
|
||||
CFRelease(currentKeyboard);
|
||||
if (currentLayoutData == nullptr)
|
||||
return 0;
|
||||
|
||||
UCKeyboardLayout* header = (UCKeyboardLayout*) CFDataGetBytePtr(currentLayoutData);
|
||||
UCKeyboardTypeHeader* table = header->keyboardTypeList;
|
||||
|
||||
uint8_t* data = (uint8_t*) header;
|
||||
// God, would a little documentation for this shit kill you...
|
||||
for (quint32 i = 0; i < header->keyboardTypeCount; i++) {
|
||||
UCKeyStateRecordsIndex* stateRec = 0;
|
||||
if (table[i].keyStateRecordsIndexOffset != 0) {
|
||||
stateRec = reinterpret_cast<UCKeyStateRecordsIndex*>(
|
||||
data + table[i].keyStateRecordsIndexOffset);
|
||||
if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat)
|
||||
stateRec = 0;
|
||||
}
|
||||
|
||||
UCKeyToCharTableIndex* charTable = reinterpret_cast<UCKeyToCharTableIndex*>(
|
||||
data + table[i].keyToCharTableIndexOffset);
|
||||
if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat)
|
||||
continue;
|
||||
|
||||
for (quint32 j = 0; j < charTable->keyToCharTableCount; j++) {
|
||||
UCKeyOutput* keyToChar = reinterpret_cast<UCKeyOutput*>(
|
||||
data + charTable->keyToCharTableOffsets[j]);
|
||||
for (quint32 k = 0; k < charTable->keyToCharTableSize; k++) {
|
||||
if (keyToChar[k] & kUCKeyOutputTestForIndexMask) {
|
||||
long idx = keyToChar[k] & kUCKeyOutputGetIndexMask;
|
||||
if (stateRec && idx < stateRec->keyStateRecordCount) {
|
||||
UCKeyStateRecord* rec = reinterpret_cast<UCKeyStateRecord*>(
|
||||
data + stateRec->keyStateRecordOffsets[idx]);
|
||||
if (rec->stateZeroCharData == ch)
|
||||
return k;
|
||||
}
|
||||
} else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask)
|
||||
&& keyToChar[k] < 0xFFFE) {
|
||||
if (keyToChar[k] == ch)
|
||||
return k;
|
||||
}
|
||||
} // for k
|
||||
} // for j
|
||||
} // for i
|
||||
|
||||
// The code above fails to translate keys like semicolon with Qt 5.7.1.
|
||||
// Last resort is to try mapping the rest of the keys directly.
|
||||
switch (key) {
|
||||
case Qt::Key_A:
|
||||
return kVK_ANSI_A;
|
||||
case Qt::Key_S:
|
||||
return kVK_ANSI_S;
|
||||
case Qt::Key_D:
|
||||
return kVK_ANSI_D;
|
||||
case Qt::Key_F:
|
||||
return kVK_ANSI_F;
|
||||
case Qt::Key_H:
|
||||
return kVK_ANSI_H;
|
||||
case Qt::Key_G:
|
||||
return kVK_ANSI_G;
|
||||
case Qt::Key_Z:
|
||||
return kVK_ANSI_Z;
|
||||
case Qt::Key_X:
|
||||
return kVK_ANSI_X;
|
||||
case Qt::Key_C:
|
||||
return kVK_ANSI_C;
|
||||
case Qt::Key_V:
|
||||
return kVK_ANSI_V;
|
||||
case Qt::Key_B:
|
||||
return kVK_ANSI_B;
|
||||
case Qt::Key_Q:
|
||||
return kVK_ANSI_Q;
|
||||
case Qt::Key_W:
|
||||
return kVK_ANSI_W;
|
||||
case Qt::Key_E:
|
||||
return kVK_ANSI_E;
|
||||
case Qt::Key_R:
|
||||
return kVK_ANSI_R;
|
||||
case Qt::Key_Y:
|
||||
return kVK_ANSI_Y;
|
||||
case Qt::Key_T:
|
||||
return kVK_ANSI_T;
|
||||
case Qt::Key_1:
|
||||
return kVK_ANSI_1;
|
||||
case Qt::Key_2:
|
||||
return kVK_ANSI_2;
|
||||
case Qt::Key_3:
|
||||
return kVK_ANSI_3;
|
||||
case Qt::Key_4:
|
||||
return kVK_ANSI_4;
|
||||
case Qt::Key_6:
|
||||
return kVK_ANSI_6;
|
||||
case Qt::Key_5:
|
||||
return kVK_ANSI_5;
|
||||
case Qt::Key_Equal:
|
||||
return kVK_ANSI_Equal;
|
||||
case Qt::Key_9:
|
||||
return kVK_ANSI_9;
|
||||
case Qt::Key_7:
|
||||
return kVK_ANSI_7;
|
||||
case Qt::Key_Minus:
|
||||
return kVK_ANSI_Minus;
|
||||
case Qt::Key_8:
|
||||
return kVK_ANSI_8;
|
||||
case Qt::Key_0:
|
||||
return kVK_ANSI_0;
|
||||
case Qt::Key_BracketRight:
|
||||
return kVK_ANSI_RightBracket;
|
||||
case Qt::Key_O:
|
||||
return kVK_ANSI_O;
|
||||
case Qt::Key_U:
|
||||
return kVK_ANSI_U;
|
||||
case Qt::Key_BracketLeft:
|
||||
return kVK_ANSI_LeftBracket;
|
||||
case Qt::Key_I:
|
||||
return kVK_ANSI_I;
|
||||
case Qt::Key_P:
|
||||
return kVK_ANSI_P;
|
||||
case Qt::Key_L:
|
||||
return kVK_ANSI_L;
|
||||
case Qt::Key_J:
|
||||
return kVK_ANSI_J;
|
||||
case Qt::Key_QuoteDbl:
|
||||
return kVK_ANSI_Quote;
|
||||
case Qt::Key_K:
|
||||
return kVK_ANSI_K;
|
||||
case Qt::Key_Semicolon:
|
||||
return kVK_ANSI_Semicolon;
|
||||
case Qt::Key_Backslash:
|
||||
return kVK_ANSI_Backslash;
|
||||
case Qt::Key_Comma:
|
||||
return kVK_ANSI_Comma;
|
||||
case Qt::Key_Slash:
|
||||
return kVK_ANSI_Slash;
|
||||
case Qt::Key_N:
|
||||
return kVK_ANSI_N;
|
||||
case Qt::Key_M:
|
||||
return kVK_ANSI_M;
|
||||
case Qt::Key_Period:
|
||||
return kVK_ANSI_Period;
|
||||
case Qt::Key_Dead_Grave:
|
||||
return kVK_ANSI_Grave;
|
||||
case Qt::Key_Asterisk:
|
||||
return kVK_ANSI_KeypadMultiply;
|
||||
case Qt::Key_Plus:
|
||||
return kVK_ANSI_KeypadPlus;
|
||||
case Qt::Key_Clear:
|
||||
return kVK_ANSI_KeypadClear;
|
||||
case Qt::Key_Escape:
|
||||
return kVK_Escape;
|
||||
default:;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include "pttlistener.moc"
|
||||
307
src/app/platform/windows/pttlistener.cpp
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pttlistener.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVariant>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
class PTTListener::Impl : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Impl(PTTListener* parent)
|
||||
: QObject(nullptr)
|
||||
{
|
||||
qApp->setProperty("PTTListener", QVariant::fromValue(parent));
|
||||
}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
stopListening();
|
||||
};
|
||||
|
||||
void startListening()
|
||||
{
|
||||
keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, GlobalKeyboardProc, NULL, 0);
|
||||
}
|
||||
|
||||
void stopListening()
|
||||
{
|
||||
UnhookWindowsHookEx(keyboardHook);
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK GlobalKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
auto* pThis = qApp->property("PTTListener").value<PTTListener*>();
|
||||
if (pThis == nullptr) {
|
||||
qWarning() << "PTTListener not found";
|
||||
return {};
|
||||
}
|
||||
auto* keyboardHook = pThis->pimpl_->keyboardHook;
|
||||
|
||||
quint32 key = qtKeyToVKey(pThis->getCurrentKey());
|
||||
static bool isKeyDown = false;
|
||||
if (nCode == HC_ACTION) {
|
||||
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
|
||||
KBDLLHOOKSTRUCT* keyInfo = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
if (keyInfo->vkCode == key && !isKeyDown) {
|
||||
Q_EMIT pThis->pttKeyPressed();
|
||||
isKeyDown = true;
|
||||
}
|
||||
} else if (wParam == WM_KEYUP || wParam == WM_SYSKEYUP) {
|
||||
KBDLLHOOKSTRUCT* keyInfo = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
|
||||
if (keyInfo->vkCode == key) {
|
||||
Q_EMIT pThis->pttKeyReleased();
|
||||
isKeyDown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CallNextHookEx(keyboardHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
HHOOK keyboardHook;
|
||||
|
||||
static quint32 qtKeyToVKey(Qt::Key key);
|
||||
};
|
||||
|
||||
PTTListener::PTTListener(AppSettingsManager* settingsManager, QObject* parent)
|
||||
: QObject(parent)
|
||||
, pimpl_(std::make_unique<Impl>(this))
|
||||
, settingsManager_(settingsManager)
|
||||
{}
|
||||
|
||||
PTTListener::~PTTListener() = default;
|
||||
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
void
|
||||
PTTListener::startListening()
|
||||
{
|
||||
pimpl_->startListening();
|
||||
}
|
||||
|
||||
void
|
||||
PTTListener::stopListening()
|
||||
{
|
||||
pimpl_->stopListening();
|
||||
}
|
||||
#endif
|
||||
|
||||
quint32
|
||||
PTTListener::Impl::qtKeyToVKey(Qt::Key key)
|
||||
{
|
||||
switch (key) {
|
||||
case Qt::Key_Escape:
|
||||
return VK_ESCAPE;
|
||||
case Qt::Key_Tab:
|
||||
case Qt::Key_Backtab:
|
||||
return VK_TAB;
|
||||
case Qt::Key_Backspace:
|
||||
return VK_BACK;
|
||||
case Qt::Key_Return:
|
||||
case Qt::Key_Enter:
|
||||
return VK_RETURN;
|
||||
case Qt::Key_Insert:
|
||||
return VK_INSERT;
|
||||
case Qt::Key_Delete:
|
||||
return VK_DELETE;
|
||||
case Qt::Key_Pause:
|
||||
return VK_PAUSE;
|
||||
case Qt::Key_Print:
|
||||
return VK_PRINT;
|
||||
case Qt::Key_Clear:
|
||||
return VK_CLEAR;
|
||||
case Qt::Key_Home:
|
||||
return VK_HOME;
|
||||
case Qt::Key_End:
|
||||
return VK_END;
|
||||
case Qt::Key_Left:
|
||||
return VK_LEFT;
|
||||
case Qt::Key_Up:
|
||||
return VK_UP;
|
||||
case Qt::Key_Right:
|
||||
return VK_RIGHT;
|
||||
case Qt::Key_Down:
|
||||
return VK_DOWN;
|
||||
case Qt::Key_PageUp:
|
||||
return VK_PRIOR;
|
||||
case Qt::Key_PageDown:
|
||||
return VK_NEXT;
|
||||
case Qt::Key_F1:
|
||||
return VK_F1;
|
||||
case Qt::Key_F2:
|
||||
return VK_F2;
|
||||
case Qt::Key_F3:
|
||||
return VK_F3;
|
||||
case Qt::Key_F4:
|
||||
return VK_F4;
|
||||
case Qt::Key_F5:
|
||||
return VK_F5;
|
||||
case Qt::Key_F6:
|
||||
return VK_F6;
|
||||
case Qt::Key_F7:
|
||||
return VK_F7;
|
||||
case Qt::Key_F8:
|
||||
return VK_F8;
|
||||
case Qt::Key_F9:
|
||||
return VK_F9;
|
||||
case Qt::Key_F10:
|
||||
return VK_F10;
|
||||
case Qt::Key_F11:
|
||||
return VK_F11;
|
||||
case Qt::Key_F12:
|
||||
return VK_F12;
|
||||
case Qt::Key_F13:
|
||||
return VK_F13;
|
||||
case Qt::Key_F14:
|
||||
return VK_F14;
|
||||
case Qt::Key_F15:
|
||||
return VK_F15;
|
||||
case Qt::Key_F16:
|
||||
return VK_F16;
|
||||
case Qt::Key_F17:
|
||||
return VK_F17;
|
||||
case Qt::Key_F18:
|
||||
return VK_F18;
|
||||
case Qt::Key_F19:
|
||||
return VK_F19;
|
||||
case Qt::Key_F20:
|
||||
return VK_F20;
|
||||
case Qt::Key_F21:
|
||||
return VK_F21;
|
||||
case Qt::Key_F22:
|
||||
return VK_F22;
|
||||
case Qt::Key_F23:
|
||||
return VK_F23;
|
||||
case Qt::Key_F24:
|
||||
return VK_F24;
|
||||
case Qt::Key_Space:
|
||||
return VK_SPACE;
|
||||
case Qt::Key_Asterisk:
|
||||
return VK_MULTIPLY;
|
||||
case Qt::Key_Plus:
|
||||
return VK_ADD;
|
||||
case Qt::Key_Minus:
|
||||
return VK_SUBTRACT;
|
||||
case Qt::Key_Slash:
|
||||
return VK_DIVIDE;
|
||||
case Qt::Key_MediaNext:
|
||||
return VK_MEDIA_NEXT_TRACK;
|
||||
case Qt::Key_MediaPrevious:
|
||||
return VK_MEDIA_PREV_TRACK;
|
||||
case Qt::Key_MediaPlay:
|
||||
return VK_MEDIA_PLAY_PAUSE;
|
||||
case Qt::Key_MediaStop:
|
||||
return VK_MEDIA_STOP;
|
||||
// couldn't find those in VK_*
|
||||
// case Qt::Key_MediaLast:
|
||||
// case Qt::Key_MediaRecord:
|
||||
case Qt::Key_VolumeDown:
|
||||
return VK_VOLUME_DOWN;
|
||||
case Qt::Key_VolumeUp:
|
||||
return VK_VOLUME_UP;
|
||||
case Qt::Key_VolumeMute:
|
||||
return VK_VOLUME_MUTE;
|
||||
case Qt::Key_0:
|
||||
return VK_NUMPAD0;
|
||||
case Qt::Key_1:
|
||||
return VK_NUMPAD1;
|
||||
case Qt::Key_2:
|
||||
return VK_NUMPAD2;
|
||||
case Qt::Key_3:
|
||||
return VK_NUMPAD3;
|
||||
case Qt::Key_4:
|
||||
return VK_NUMPAD4;
|
||||
case Qt::Key_5:
|
||||
return VK_NUMPAD5;
|
||||
case Qt::Key_6:
|
||||
return VK_NUMPAD6;
|
||||
case Qt::Key_7:
|
||||
return VK_NUMPAD7;
|
||||
case Qt::Key_8:
|
||||
return VK_NUMPAD8;
|
||||
case Qt::Key_9:
|
||||
return VK_NUMPAD9;
|
||||
case Qt::Key_A:
|
||||
return 'A';
|
||||
case Qt::Key_B:
|
||||
return 'B';
|
||||
case Qt::Key_C:
|
||||
return 'C';
|
||||
case Qt::Key_D:
|
||||
return 'D';
|
||||
case Qt::Key_E:
|
||||
return 'E';
|
||||
case Qt::Key_F:
|
||||
return 'F';
|
||||
case Qt::Key_G:
|
||||
return 'G';
|
||||
case Qt::Key_H:
|
||||
return 'H';
|
||||
case Qt::Key_I:
|
||||
return 'I';
|
||||
case Qt::Key_J:
|
||||
return 'J';
|
||||
case Qt::Key_K:
|
||||
return 'K';
|
||||
case Qt::Key_L:
|
||||
return 'L';
|
||||
case Qt::Key_M:
|
||||
return 'M';
|
||||
case Qt::Key_N:
|
||||
return 'N';
|
||||
case Qt::Key_O:
|
||||
return 'O';
|
||||
case Qt::Key_P:
|
||||
return 'P';
|
||||
case Qt::Key_Q:
|
||||
return 'Q';
|
||||
case Qt::Key_R:
|
||||
return 'R';
|
||||
case Qt::Key_S:
|
||||
return 'S';
|
||||
case Qt::Key_T:
|
||||
return 'T';
|
||||
case Qt::Key_U:
|
||||
return 'U';
|
||||
case Qt::Key_V:
|
||||
return 'V';
|
||||
case Qt::Key_W:
|
||||
return 'W';
|
||||
case Qt::Key_X:
|
||||
return 'X';
|
||||
case Qt::Key_Y:
|
||||
return 'Y';
|
||||
case Qt::Key_Z:
|
||||
return 'Z';
|
||||
|
||||
default:
|
||||
// Try to get virtual key from current keyboard layout or US.
|
||||
const HKL layout = GetKeyboardLayout(0);
|
||||
int vk = VkKeyScanEx(key, layout);
|
||||
if (vk == -1) {
|
||||
const HKL layoutUs = GetKeyboardLayout(0x409);
|
||||
vk = VkKeyScanEx(key, layoutUs);
|
||||
}
|
||||
return vk == -1 ? 0 : vk;
|
||||
}
|
||||
}
|
||||
|
||||
#include "pttlistener.moc"
|
||||
192
src/app/platform/x11/pttlistener.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pttlistener.h"
|
||||
#include "appsettingsmanager.h"
|
||||
#include "xcbkeyboard.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVariant>
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
class PTTListener::Impl : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Impl(PTTListener* parent)
|
||||
: QObject(nullptr)
|
||||
, parent_(*parent)
|
||||
, display_(XOpenDisplay(NULL))
|
||||
, root_(DefaultRootWindow(display_))
|
||||
{
|
||||
thread_.reset(new QThread());
|
||||
moveToThread(thread_.get());
|
||||
}
|
||||
|
||||
~Impl()
|
||||
{
|
||||
stopListening();
|
||||
XCloseDisplay(display_);
|
||||
};
|
||||
|
||||
void startListening()
|
||||
{
|
||||
stop_.store(false);
|
||||
connect(thread_.get(), &QThread::started, this, &Impl::processEvents);
|
||||
thread_->start();
|
||||
}
|
||||
|
||||
void stopListening()
|
||||
{
|
||||
stop_.store(true);
|
||||
thread_->quit();
|
||||
thread_->wait();
|
||||
}
|
||||
|
||||
static const unsigned int* keyTbl_;
|
||||
|
||||
KeySym getKeySymFromQtKey(Qt::Key qtKey);
|
||||
|
||||
QString keySymToQString(KeySym ks);
|
||||
|
||||
KeySym qtKeyToXKeySym(Qt::Key key);
|
||||
|
||||
private Q_SLOTS:
|
||||
void processEvents()
|
||||
{
|
||||
Window curFocus;
|
||||
char buf[17];
|
||||
KeySym ks;
|
||||
XComposeStatus comp;
|
||||
int len;
|
||||
int revert;
|
||||
static auto flags = KeyPressMask | KeyReleaseMask | FocusChangeMask;
|
||||
|
||||
XGetInputFocus(display_, &curFocus, &revert);
|
||||
XSelectInput(display_, curFocus, flags);
|
||||
bool pressed = false;
|
||||
KeySym key = qtKeyToXKeySym(parent_.getCurrentKey());
|
||||
|
||||
while (!stop_.load()) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
while (XPending(display_)) {
|
||||
XEvent ev;
|
||||
|
||||
XNextEvent(display_, &ev);
|
||||
XLookupString(&ev.xkey, buf, 16, &ks, &comp);
|
||||
switch (ev.type) {
|
||||
case FocusOut:
|
||||
if (curFocus != root_)
|
||||
XSelectInput(display_, curFocus, 0);
|
||||
XGetInputFocus(display_, &curFocus, &revert);
|
||||
if (curFocus == PointerRoot)
|
||||
curFocus = root_;
|
||||
XSelectInput(display_, curFocus, flags);
|
||||
break;
|
||||
|
||||
case KeyPress: {
|
||||
if (!(pressed) && ks == key) {
|
||||
Q_EMIT parent_.pttKeyPressed();
|
||||
pressed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyRelease:
|
||||
bool is_retriggered = false;
|
||||
if (XEventsQueued(display_, QueuedAfterReading)) {
|
||||
XEvent nev;
|
||||
XPeekEvent(display_, &nev);
|
||||
if (nev.type == KeyPress && nev.xkey.time == ev.xkey.time
|
||||
&& nev.xkey.keycode == ev.xkey.keycode) {
|
||||
is_retriggered = true;
|
||||
}
|
||||
}
|
||||
if (!is_retriggered && ks == key) {
|
||||
Q_EMIT parent_.pttKeyReleased();
|
||||
pressed = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
PTTListener& parent_;
|
||||
Display* display_;
|
||||
Window root_;
|
||||
QScopedPointer<QThread> thread_;
|
||||
std::atomic_bool stop_ {false};
|
||||
};
|
||||
|
||||
QString
|
||||
PTTListener::Impl::keySymToQString(KeySym ks)
|
||||
{
|
||||
return QString::fromUtf8(XKeysymToString(ks));
|
||||
}
|
||||
|
||||
KeySym
|
||||
PTTListener::Impl::qtKeyToXKeySym(Qt::Key key)
|
||||
{
|
||||
const auto keySym = getKeySymFromQtKey(key);
|
||||
if (keySym != NoSymbol) {
|
||||
return keySym;
|
||||
}
|
||||
for (int i = 0; keyTbl_[i] != 0; i += 2) {
|
||||
if (keyTbl_[i + 1] == key)
|
||||
return keyTbl_[i];
|
||||
}
|
||||
|
||||
return static_cast<ushort>(key);
|
||||
}
|
||||
|
||||
PTTListener::PTTListener(AppSettingsManager* settingsManager, QObject* parent)
|
||||
: settingsManager_(settingsManager)
|
||||
, QObject(parent)
|
||||
, pimpl_(std::make_unique<Impl>(this))
|
||||
{}
|
||||
|
||||
PTTListener::~PTTListener() = default;
|
||||
|
||||
void
|
||||
PTTListener::startListening()
|
||||
{
|
||||
pimpl_->startListening();
|
||||
}
|
||||
|
||||
void
|
||||
PTTListener::stopListening()
|
||||
{
|
||||
pimpl_->stopListening();
|
||||
}
|
||||
KeySym
|
||||
PTTListener::Impl::getKeySymFromQtKey(Qt::Key qtKey)
|
||||
{
|
||||
QString keyString = QKeySequence(qtKey).toString().toLower();
|
||||
KeySym keySym = XStringToKeysym(keyString.toUtf8().data());
|
||||
return keySym;
|
||||
}
|
||||
|
||||
const unsigned int* PTTListener::Impl::keyTbl_ = keyTable;
|
||||
|
||||
#include "pttlistener.moc"
|
||||
856
src/app/platform/x11/xcbkeyboard.h
Normal file
@ -0,0 +1,856 @@
|
||||
#include "pttlistener.h"
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
// Following definitions and table are taken from
|
||||
// "qt5/qtbase/src/plugins/platforms/xcb/qxcbkeyboard.cpp".
|
||||
|
||||
#include <Qt>
|
||||
#include <X11/keysym.h>
|
||||
|
||||
#ifndef XK_ISO_Left_Tab
|
||||
#define XK_ISO_Left_Tab 0xFE20
|
||||
#endif
|
||||
|
||||
#ifndef XK_dead_hook
|
||||
#define XK_dead_hook 0xFE61
|
||||
#endif
|
||||
|
||||
#ifndef XK_dead_horn
|
||||
#define XK_dead_horn 0xFE62
|
||||
#endif
|
||||
|
||||
#ifndef XK_Codeinput
|
||||
#define XK_Codeinput 0xFF37
|
||||
#endif
|
||||
|
||||
#ifndef XK_Kanji_Bangou
|
||||
#define XK_Kanji_Bangou 0xFF37 /* same as codeinput */
|
||||
#endif
|
||||
|
||||
// Fix old X libraries
|
||||
#ifndef XK_KP_Home
|
||||
#define XK_KP_Home 0xFF95
|
||||
#endif
|
||||
#ifndef XK_KP_Left
|
||||
#define XK_KP_Left 0xFF96
|
||||
#endif
|
||||
#ifndef XK_KP_Up
|
||||
#define XK_KP_Up 0xFF97
|
||||
#endif
|
||||
#ifndef XK_KP_Right
|
||||
#define XK_KP_Right 0xFF98
|
||||
#endif
|
||||
#ifndef XK_KP_Down
|
||||
#define XK_KP_Down 0xFF99
|
||||
#endif
|
||||
#ifndef XK_KP_Prior
|
||||
#define XK_KP_Prior 0xFF9A
|
||||
#endif
|
||||
#ifndef XK_KP_Next
|
||||
#define XK_KP_Next 0xFF9B
|
||||
#endif
|
||||
#ifndef XK_KP_End
|
||||
#define XK_KP_End 0xFF9C
|
||||
#endif
|
||||
#ifndef XK_KP_Insert
|
||||
#define XK_KP_Insert 0xFF9E
|
||||
#endif
|
||||
#ifndef XK_KP_Delete
|
||||
#define XK_KP_Delete 0xFF9F
|
||||
#endif
|
||||
|
||||
// the next lines are taken on 10/2009 from X.org (X11/XF86keysym.h), defining some special
|
||||
// multimedia keys. They are included here as not every system has them.
|
||||
#define XF86XK_MonBrightnessUp 0x1008FF02
|
||||
#define XF86XK_MonBrightnessDown 0x1008FF03
|
||||
#define XF86XK_KbdLightOnOff 0x1008FF04
|
||||
#define XF86XK_KbdBrightnessUp 0x1008FF05
|
||||
#define XF86XK_KbdBrightnessDown 0x1008FF06
|
||||
#define XF86XK_Standby 0x1008FF10
|
||||
#define XF86XK_AudioLowerVolume 0x1008FF11
|
||||
#define XF86XK_AudioMute 0x1008FF12
|
||||
#define XF86XK_AudioRaiseVolume 0x1008FF13
|
||||
#define XF86XK_AudioPlay 0x1008FF14
|
||||
#define XF86XK_AudioStop 0x1008FF15
|
||||
#define XF86XK_AudioPrev 0x1008FF16
|
||||
#define XF86XK_AudioNext 0x1008FF17
|
||||
#define XF86XK_HomePage 0x1008FF18
|
||||
#define XF86XK_Mail 0x1008FF19
|
||||
#define XF86XK_Start 0x1008FF1A
|
||||
#define XF86XK_Search 0x1008FF1B
|
||||
#define XF86XK_AudioRecord 0x1008FF1C
|
||||
#define XF86XK_Calculator 0x1008FF1D
|
||||
#define XF86XK_Memo 0x1008FF1E
|
||||
#define XF86XK_ToDoList 0x1008FF1F
|
||||
#define XF86XK_Calendar 0x1008FF20
|
||||
#define XF86XK_PowerDown 0x1008FF21
|
||||
#define XF86XK_ContrastAdjust 0x1008FF22
|
||||
#define XF86XK_Back 0x1008FF26
|
||||
#define XF86XK_Forward 0x1008FF27
|
||||
#define XF86XK_Stop 0x1008FF28
|
||||
#define XF86XK_Refresh 0x1008FF29
|
||||
#define XF86XK_PowerOff 0x1008FF2A
|
||||
#define XF86XK_WakeUp 0x1008FF2B
|
||||
#define XF86XK_Eject 0x1008FF2C
|
||||
#define XF86XK_ScreenSaver 0x1008FF2D
|
||||
#define XF86XK_WWW 0x1008FF2E
|
||||
#define XF86XK_Sleep 0x1008FF2F
|
||||
#define XF86XK_Favorites 0x1008FF30
|
||||
#define XF86XK_AudioPause 0x1008FF31
|
||||
#define XF86XK_AudioMedia 0x1008FF32
|
||||
#define XF86XK_MyComputer 0x1008FF33
|
||||
#define XF86XK_LightBulb 0x1008FF35
|
||||
#define XF86XK_Shop 0x1008FF36
|
||||
#define XF86XK_History 0x1008FF37
|
||||
#define XF86XK_OpenURL 0x1008FF38
|
||||
#define XF86XK_AddFavorite 0x1008FF39
|
||||
#define XF86XK_HotLinks 0x1008FF3A
|
||||
#define XF86XK_BrightnessAdjust 0x1008FF3B
|
||||
#define XF86XK_Finance 0x1008FF3C
|
||||
#define XF86XK_Community 0x1008FF3D
|
||||
#define XF86XK_AudioRewind 0x1008FF3E
|
||||
#define XF86XK_BackForward 0x1008FF3F
|
||||
#define XF86XK_Launch0 0x1008FF40
|
||||
#define XF86XK_Launch1 0x1008FF41
|
||||
#define XF86XK_Launch2 0x1008FF42
|
||||
#define XF86XK_Launch3 0x1008FF43
|
||||
#define XF86XK_Launch4 0x1008FF44
|
||||
#define XF86XK_Launch5 0x1008FF45
|
||||
#define XF86XK_Launch6 0x1008FF46
|
||||
#define XF86XK_Launch7 0x1008FF47
|
||||
#define XF86XK_Launch8 0x1008FF48
|
||||
#define XF86XK_Launch9 0x1008FF49
|
||||
#define XF86XK_LaunchA 0x1008FF4A
|
||||
#define XF86XK_LaunchB 0x1008FF4B
|
||||
#define XF86XK_LaunchC 0x1008FF4C
|
||||
#define XF86XK_LaunchD 0x1008FF4D
|
||||
#define XF86XK_LaunchE 0x1008FF4E
|
||||
#define XF86XK_LaunchF 0x1008FF4F
|
||||
#define XF86XK_ApplicationLeft 0x1008FF50
|
||||
#define XF86XK_ApplicationRight 0x1008FF51
|
||||
#define XF86XK_Book 0x1008FF52
|
||||
#define XF86XK_CD 0x1008FF53
|
||||
#define XF86XK_Calculater 0x1008FF54
|
||||
#define XF86XK_Clear 0x1008FF55
|
||||
#define XF86XK_ClearGrab 0x1008FE21
|
||||
#define XF86XK_Close 0x1008FF56
|
||||
#define XF86XK_Copy 0x1008FF57
|
||||
#define XF86XK_Cut 0x1008FF58
|
||||
#define XF86XK_Display 0x1008FF59
|
||||
#define XF86XK_DOS 0x1008FF5A
|
||||
#define XF86XK_Documents 0x1008FF5B
|
||||
#define XF86XK_Excel 0x1008FF5C
|
||||
#define XF86XK_Explorer 0x1008FF5D
|
||||
#define XF86XK_Game 0x1008FF5E
|
||||
#define XF86XK_Go 0x1008FF5F
|
||||
#define XF86XK_iTouch 0x1008FF60
|
||||
#define XF86XK_LogOff 0x1008FF61
|
||||
#define XF86XK_Market 0x1008FF62
|
||||
#define XF86XK_Meeting 0x1008FF63
|
||||
#define XF86XK_MenuKB 0x1008FF65
|
||||
#define XF86XK_MenuPB 0x1008FF66
|
||||
#define XF86XK_MySites 0x1008FF67
|
||||
#define XF86XK_New 0x1008FF68
|
||||
#define XF86XK_News 0x1008FF69
|
||||
#define XF86XK_OfficeHome 0x1008FF6A
|
||||
#define XF86XK_Open 0x1008FF6B
|
||||
#define XF86XK_Option 0x1008FF6C
|
||||
#define XF86XK_Paste 0x1008FF6D
|
||||
#define XF86XK_Phone 0x1008FF6E
|
||||
#define XF86XK_Reply 0x1008FF72
|
||||
#define XF86XK_Reload 0x1008FF73
|
||||
#define XF86XK_RotateWindows 0x1008FF74
|
||||
#define XF86XK_RotationPB 0x1008FF75
|
||||
#define XF86XK_RotationKB 0x1008FF76
|
||||
#define XF86XK_Save 0x1008FF77
|
||||
#define XF86XK_Send 0x1008FF7B
|
||||
#define XF86XK_Spell 0x1008FF7C
|
||||
#define XF86XK_SplitScreen 0x1008FF7D
|
||||
#define XF86XK_Support 0x1008FF7E
|
||||
#define XF86XK_TaskPane 0x1008FF7F
|
||||
#define XF86XK_Terminal 0x1008FF80
|
||||
#define XF86XK_Tools 0x1008FF81
|
||||
#define XF86XK_Travel 0x1008FF82
|
||||
#define XF86XK_Video 0x1008FF87
|
||||
#define XF86XK_Word 0x1008FF89
|
||||
#define XF86XK_Xfer 0x1008FF8A
|
||||
#define XF86XK_ZoomIn 0x1008FF8B
|
||||
#define XF86XK_ZoomOut 0x1008FF8C
|
||||
#define XF86XK_Away 0x1008FF8D
|
||||
#define XF86XK_Messenger 0x1008FF8E
|
||||
#define XF86XK_WebCam 0x1008FF8F
|
||||
#define XF86XK_MailForward 0x1008FF90
|
||||
#define XF86XK_Pictures 0x1008FF91
|
||||
#define XF86XK_Music 0x1008FF92
|
||||
#define XF86XK_Battery 0x1008FF93
|
||||
#define XF86XK_Bluetooth 0x1008FF94
|
||||
#define XF86XK_WLAN 0x1008FF95
|
||||
#define XF86XK_UWB 0x1008FF96
|
||||
#define XF86XK_AudioForward 0x1008FF97
|
||||
#define XF86XK_AudioRepeat 0x1008FF98
|
||||
#define XF86XK_AudioRandomPlay 0x1008FF99
|
||||
#define XF86XK_Subtitle 0x1008FF9A
|
||||
#define XF86XK_AudioCycleTrack 0x1008FF9B
|
||||
#define XF86XK_Time 0x1008FF9F
|
||||
#define XF86XK_Select 0x1008FFA0
|
||||
#define XF86XK_View 0x1008FFA1
|
||||
#define XF86XK_TopMenu 0x1008FFA2
|
||||
#define XF86XK_Red 0x1008FFA3
|
||||
#define XF86XK_Green 0x1008FFA4
|
||||
#define XF86XK_Yellow 0x1008FFA5
|
||||
#define XF86XK_Blue 0x1008FFA6
|
||||
#define XF86XK_Suspend 0x1008FFA7
|
||||
#define XF86XK_Hibernate 0x1008FFA8
|
||||
#define XF86XK_TouchpadToggle 0x1008FFA9
|
||||
#define XF86XK_TouchpadOn 0x1008FFB0
|
||||
#define XF86XK_TouchpadOff 0x1008FFB1
|
||||
#define XF86XK_AudioMicMute 0x1008FFB2
|
||||
|
||||
// end of XF86keysyms.h
|
||||
|
||||
// keyboard mapping table
|
||||
static const unsigned int keyTable[] = {
|
||||
|
||||
// misc keys
|
||||
|
||||
XK_Escape,
|
||||
Qt::Key_Escape,
|
||||
XK_Tab,
|
||||
Qt::Key_Tab,
|
||||
XK_ISO_Left_Tab,
|
||||
Qt::Key_Backtab,
|
||||
XK_BackSpace,
|
||||
Qt::Key_Backspace,
|
||||
XK_Return,
|
||||
Qt::Key_Return,
|
||||
XK_Insert,
|
||||
Qt::Key_Insert,
|
||||
XK_Delete,
|
||||
Qt::Key_Delete,
|
||||
XK_Clear,
|
||||
Qt::Key_Delete,
|
||||
XK_Pause,
|
||||
Qt::Key_Pause,
|
||||
XK_Print,
|
||||
Qt::Key_Print,
|
||||
0x1005FF60,
|
||||
Qt::Key_SysReq, // hardcoded Sun SysReq
|
||||
0x1007ff00,
|
||||
Qt::Key_SysReq, // hardcoded X386 SysReq
|
||||
|
||||
// cursor movement
|
||||
|
||||
XK_Home,
|
||||
Qt::Key_Home,
|
||||
XK_End,
|
||||
Qt::Key_End,
|
||||
XK_Left,
|
||||
Qt::Key_Left,
|
||||
XK_Up,
|
||||
Qt::Key_Up,
|
||||
XK_Right,
|
||||
Qt::Key_Right,
|
||||
XK_Down,
|
||||
Qt::Key_Down,
|
||||
XK_Prior,
|
||||
Qt::Key_PageUp,
|
||||
XK_Next,
|
||||
Qt::Key_PageDown,
|
||||
|
||||
// modifiers
|
||||
|
||||
XK_Shift_L,
|
||||
Qt::Key_Shift,
|
||||
XK_Shift_R,
|
||||
Qt::Key_Shift,
|
||||
XK_Shift_Lock,
|
||||
Qt::Key_Shift,
|
||||
XK_Control_L,
|
||||
Qt::Key_Control,
|
||||
XK_Control_R,
|
||||
Qt::Key_Control,
|
||||
XK_Meta_L,
|
||||
Qt::Key_Meta,
|
||||
XK_Meta_R,
|
||||
Qt::Key_Meta,
|
||||
XK_Alt_L,
|
||||
Qt::Key_Alt,
|
||||
XK_Alt_R,
|
||||
Qt::Key_Alt,
|
||||
XK_Caps_Lock,
|
||||
Qt::Key_CapsLock,
|
||||
XK_Num_Lock,
|
||||
Qt::Key_NumLock,
|
||||
XK_Scroll_Lock,
|
||||
Qt::Key_ScrollLock,
|
||||
XK_Super_L,
|
||||
Qt::Key_Super_L,
|
||||
XK_Super_R,
|
||||
Qt::Key_Super_R,
|
||||
XK_Menu,
|
||||
Qt::Key_Menu,
|
||||
XK_Hyper_L,
|
||||
Qt::Key_Hyper_L,
|
||||
XK_Hyper_R,
|
||||
Qt::Key_Hyper_R,
|
||||
XK_Help,
|
||||
Qt::Key_Help,
|
||||
0x1000FF74,
|
||||
Qt::Key_Backtab, // hardcoded HP backtab
|
||||
0x1005FF10,
|
||||
Qt::Key_F11, // hardcoded Sun F36 (labeled F11)
|
||||
0x1005FF11,
|
||||
Qt::Key_F12, // hardcoded Sun F37 (labeled F12)
|
||||
|
||||
// numeric and function keypad keys
|
||||
|
||||
XK_KP_Space,
|
||||
Qt::Key_Space,
|
||||
XK_KP_Tab,
|
||||
Qt::Key_Tab,
|
||||
XK_KP_Enter,
|
||||
Qt::Key_Enter,
|
||||
XK_KP_F1,
|
||||
Qt::Key_F1,
|
||||
XK_F2,
|
||||
Qt::Key_F2,
|
||||
XK_F3,
|
||||
Qt::Key_F3,
|
||||
XK_F4,
|
||||
Qt::Key_F4,
|
||||
XK_F5,
|
||||
Qt::Key_F5,
|
||||
XK_F6,
|
||||
Qt::Key_F6,
|
||||
XK_F7,
|
||||
Qt::Key_F7,
|
||||
XK_F8,
|
||||
Qt::Key_F8,
|
||||
XK_F9,
|
||||
Qt::Key_F9,
|
||||
XK_F10,
|
||||
Qt::Key_F10,
|
||||
XK_KP_Home,
|
||||
Qt::Key_Home,
|
||||
XK_KP_Left,
|
||||
Qt::Key_Left,
|
||||
XK_KP_Up,
|
||||
Qt::Key_Up,
|
||||
XK_KP_Right,
|
||||
Qt::Key_Right,
|
||||
XK_KP_Down,
|
||||
Qt::Key_Down,
|
||||
XK_KP_Prior,
|
||||
Qt::Key_PageUp,
|
||||
XK_KP_Next,
|
||||
Qt::Key_PageDown,
|
||||
XK_KP_End,
|
||||
Qt::Key_End,
|
||||
XK_KP_Begin,
|
||||
Qt::Key_Clear,
|
||||
XK_KP_Insert,
|
||||
Qt::Key_Insert,
|
||||
XK_KP_Delete,
|
||||
Qt::Key_Delete,
|
||||
XK_KP_Equal,
|
||||
Qt::Key_Equal,
|
||||
XK_KP_Multiply,
|
||||
Qt::Key_Asterisk,
|
||||
XK_KP_Add,
|
||||
Qt::Key_Plus,
|
||||
XK_KP_Separator,
|
||||
Qt::Key_Comma,
|
||||
XK_KP_Subtract,
|
||||
Qt::Key_Minus,
|
||||
XK_KP_Decimal,
|
||||
Qt::Key_Period,
|
||||
XK_KP_Divide,
|
||||
Qt::Key_Slash,
|
||||
|
||||
// International input method support keys
|
||||
|
||||
// International & multi-key character composition
|
||||
XK_ISO_Level3_Shift,
|
||||
Qt::Key_AltGr,
|
||||
XK_Multi_key,
|
||||
Qt::Key_Multi_key,
|
||||
XK_Codeinput,
|
||||
Qt::Key_Codeinput,
|
||||
XK_SingleCandidate,
|
||||
Qt::Key_SingleCandidate,
|
||||
XK_MultipleCandidate,
|
||||
Qt::Key_MultipleCandidate,
|
||||
XK_PreviousCandidate,
|
||||
Qt::Key_PreviousCandidate,
|
||||
|
||||
// Misc Functions
|
||||
XK_Mode_switch,
|
||||
Qt::Key_Mode_switch,
|
||||
XK_script_switch,
|
||||
Qt::Key_Mode_switch,
|
||||
|
||||
// Japanese keyboard support
|
||||
XK_Kanji,
|
||||
Qt::Key_Kanji,
|
||||
XK_Muhenkan,
|
||||
Qt::Key_Muhenkan,
|
||||
// XK_Henkan_Mode, Qt::Key_Henkan_Mode,
|
||||
XK_Henkan_Mode,
|
||||
Qt::Key_Henkan,
|
||||
XK_Henkan,
|
||||
Qt::Key_Henkan,
|
||||
XK_Romaji,
|
||||
Qt::Key_Romaji,
|
||||
XK_Hiragana,
|
||||
Qt::Key_Hiragana,
|
||||
XK_Katakana,
|
||||
Qt::Key_Katakana,
|
||||
XK_Hiragana_Katakana,
|
||||
Qt::Key_Hiragana_Katakana,
|
||||
XK_Zenkaku,
|
||||
Qt::Key_Zenkaku,
|
||||
XK_Hankaku,
|
||||
Qt::Key_Hankaku,
|
||||
XK_Zenkaku_Hankaku,
|
||||
Qt::Key_Zenkaku_Hankaku,
|
||||
XK_Touroku,
|
||||
Qt::Key_Touroku,
|
||||
XK_Massyo,
|
||||
Qt::Key_Massyo,
|
||||
XK_Kana_Lock,
|
||||
Qt::Key_Kana_Lock,
|
||||
XK_Kana_Shift,
|
||||
Qt::Key_Kana_Shift,
|
||||
XK_Eisu_Shift,
|
||||
Qt::Key_Eisu_Shift,
|
||||
XK_Eisu_toggle,
|
||||
Qt::Key_Eisu_toggle,
|
||||
// XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
|
||||
// XK_Zen_Koho, Qt::Key_Zen_Koho,
|
||||
// XK_Mae_Koho, Qt::Key_Mae_Koho,
|
||||
XK_Kanji_Bangou,
|
||||
Qt::Key_Codeinput,
|
||||
XK_Zen_Koho,
|
||||
Qt::Key_MultipleCandidate,
|
||||
XK_Mae_Koho,
|
||||
Qt::Key_PreviousCandidate,
|
||||
|
||||
#ifdef XK_KOREAN
|
||||
// Korean keyboard support
|
||||
XK_Hangul,
|
||||
Qt::Key_Hangul,
|
||||
XK_Hangul_Start,
|
||||
Qt::Key_Hangul_Start,
|
||||
XK_Hangul_End,
|
||||
Qt::Key_Hangul_End,
|
||||
XK_Hangul_Hanja,
|
||||
Qt::Key_Hangul_Hanja,
|
||||
XK_Hangul_Jamo,
|
||||
Qt::Key_Hangul_Jamo,
|
||||
XK_Hangul_Romaja,
|
||||
Qt::Key_Hangul_Romaja,
|
||||
// XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
|
||||
XK_Hangul_Codeinput,
|
||||
Qt::Key_Codeinput,
|
||||
XK_Hangul_Jeonja,
|
||||
Qt::Key_Hangul_Jeonja,
|
||||
XK_Hangul_Banja,
|
||||
Qt::Key_Hangul_Banja,
|
||||
XK_Hangul_PreHanja,
|
||||
Qt::Key_Hangul_PreHanja,
|
||||
XK_Hangul_PostHanja,
|
||||
Qt::Key_Hangul_PostHanja,
|
||||
// XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
|
||||
// XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
|
||||
// XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
|
||||
XK_Hangul_SingleCandidate,
|
||||
Qt::Key_SingleCandidate,
|
||||
XK_Hangul_MultipleCandidate,
|
||||
Qt::Key_MultipleCandidate,
|
||||
XK_Hangul_PreviousCandidate,
|
||||
Qt::Key_PreviousCandidate,
|
||||
XK_Hangul_Special,
|
||||
Qt::Key_Hangul_Special,
|
||||
// XK_Hangul_switch, Qt::Key_Hangul_switch,
|
||||
XK_Hangul_switch,
|
||||
Qt::Key_Mode_switch,
|
||||
#endif // XK_KOREAN
|
||||
|
||||
// dead keys
|
||||
XK_dead_grave,
|
||||
Qt::Key_Dead_Grave,
|
||||
XK_dead_acute,
|
||||
Qt::Key_Dead_Acute,
|
||||
XK_dead_circumflex,
|
||||
Qt::Key_Dead_Circumflex,
|
||||
XK_dead_tilde,
|
||||
Qt::Key_Dead_Tilde,
|
||||
XK_dead_macron,
|
||||
Qt::Key_Dead_Macron,
|
||||
XK_dead_breve,
|
||||
Qt::Key_Dead_Breve,
|
||||
XK_dead_abovedot,
|
||||
Qt::Key_Dead_Abovedot,
|
||||
XK_dead_diaeresis,
|
||||
Qt::Key_Dead_Diaeresis,
|
||||
XK_dead_abovering,
|
||||
Qt::Key_Dead_Abovering,
|
||||
XK_dead_doubleacute,
|
||||
Qt::Key_Dead_Doubleacute,
|
||||
XK_dead_caron,
|
||||
Qt::Key_Dead_Caron,
|
||||
XK_dead_cedilla,
|
||||
Qt::Key_Dead_Cedilla,
|
||||
XK_dead_ogonek,
|
||||
Qt::Key_Dead_Ogonek,
|
||||
XK_dead_iota,
|
||||
Qt::Key_Dead_Iota,
|
||||
XK_dead_voiced_sound,
|
||||
Qt::Key_Dead_Voiced_Sound,
|
||||
XK_dead_semivoiced_sound,
|
||||
Qt::Key_Dead_Semivoiced_Sound,
|
||||
XK_dead_belowdot,
|
||||
Qt::Key_Dead_Belowdot,
|
||||
XK_dead_hook,
|
||||
Qt::Key_Dead_Hook,
|
||||
XK_dead_horn,
|
||||
Qt::Key_Dead_Horn,
|
||||
|
||||
// Special keys from X.org - This include multimedia keys,
|
||||
// wireless/bluetooth/uwb keys, special launcher keys, etc.
|
||||
XF86XK_Back,
|
||||
Qt::Key_Back,
|
||||
XF86XK_Forward,
|
||||
Qt::Key_Forward,
|
||||
XF86XK_Stop,
|
||||
Qt::Key_Stop,
|
||||
XF86XK_Refresh,
|
||||
Qt::Key_Refresh,
|
||||
XF86XK_Favorites,
|
||||
Qt::Key_Favorites,
|
||||
XF86XK_AudioMedia,
|
||||
Qt::Key_LaunchMedia,
|
||||
XF86XK_OpenURL,
|
||||
Qt::Key_OpenUrl,
|
||||
XF86XK_HomePage,
|
||||
Qt::Key_HomePage,
|
||||
XF86XK_Search,
|
||||
Qt::Key_Search,
|
||||
XF86XK_AudioLowerVolume,
|
||||
Qt::Key_VolumeDown,
|
||||
XF86XK_AudioMute,
|
||||
Qt::Key_VolumeMute,
|
||||
XF86XK_AudioRaiseVolume,
|
||||
Qt::Key_VolumeUp,
|
||||
XF86XK_AudioPlay,
|
||||
Qt::Key_MediaPlay,
|
||||
XF86XK_AudioStop,
|
||||
Qt::Key_MediaStop,
|
||||
XF86XK_AudioPrev,
|
||||
Qt::Key_MediaPrevious,
|
||||
XF86XK_AudioNext,
|
||||
Qt::Key_MediaNext,
|
||||
XF86XK_AudioRecord,
|
||||
Qt::Key_MediaRecord,
|
||||
XF86XK_AudioPause,
|
||||
Qt::Key_MediaPause,
|
||||
XF86XK_Mail,
|
||||
Qt::Key_LaunchMail,
|
||||
XF86XK_MyComputer,
|
||||
Qt::Key_Launch0, // ### Qt 6: remap properly
|
||||
XF86XK_Calculator,
|
||||
Qt::Key_Launch1,
|
||||
XF86XK_Memo,
|
||||
Qt::Key_Memo,
|
||||
XF86XK_ToDoList,
|
||||
Qt::Key_ToDoList,
|
||||
XF86XK_Calendar,
|
||||
Qt::Key_Calendar,
|
||||
XF86XK_PowerDown,
|
||||
Qt::Key_PowerDown,
|
||||
XF86XK_ContrastAdjust,
|
||||
Qt::Key_ContrastAdjust,
|
||||
XF86XK_Standby,
|
||||
Qt::Key_Standby,
|
||||
XF86XK_MonBrightnessUp,
|
||||
Qt::Key_MonBrightnessUp,
|
||||
XF86XK_MonBrightnessDown,
|
||||
Qt::Key_MonBrightnessDown,
|
||||
XF86XK_KbdLightOnOff,
|
||||
Qt::Key_KeyboardLightOnOff,
|
||||
XF86XK_KbdBrightnessUp,
|
||||
Qt::Key_KeyboardBrightnessUp,
|
||||
XF86XK_KbdBrightnessDown,
|
||||
Qt::Key_KeyboardBrightnessDown,
|
||||
XF86XK_PowerOff,
|
||||
Qt::Key_PowerOff,
|
||||
XF86XK_WakeUp,
|
||||
Qt::Key_WakeUp,
|
||||
XF86XK_Eject,
|
||||
Qt::Key_Eject,
|
||||
XF86XK_ScreenSaver,
|
||||
Qt::Key_ScreenSaver,
|
||||
XF86XK_WWW,
|
||||
Qt::Key_WWW,
|
||||
XF86XK_Sleep,
|
||||
Qt::Key_Sleep,
|
||||
XF86XK_LightBulb,
|
||||
Qt::Key_LightBulb,
|
||||
XF86XK_Shop,
|
||||
Qt::Key_Shop,
|
||||
XF86XK_History,
|
||||
Qt::Key_History,
|
||||
XF86XK_AddFavorite,
|
||||
Qt::Key_AddFavorite,
|
||||
XF86XK_HotLinks,
|
||||
Qt::Key_HotLinks,
|
||||
XF86XK_BrightnessAdjust,
|
||||
Qt::Key_BrightnessAdjust,
|
||||
XF86XK_Finance,
|
||||
Qt::Key_Finance,
|
||||
XF86XK_Community,
|
||||
Qt::Key_Community,
|
||||
XF86XK_AudioRewind,
|
||||
Qt::Key_AudioRewind,
|
||||
XF86XK_BackForward,
|
||||
Qt::Key_BackForward,
|
||||
XF86XK_ApplicationLeft,
|
||||
Qt::Key_ApplicationLeft,
|
||||
XF86XK_ApplicationRight,
|
||||
Qt::Key_ApplicationRight,
|
||||
XF86XK_Book,
|
||||
Qt::Key_Book,
|
||||
XF86XK_CD,
|
||||
Qt::Key_CD,
|
||||
XF86XK_Calculater,
|
||||
Qt::Key_Calculator,
|
||||
XF86XK_Clear,
|
||||
Qt::Key_Clear,
|
||||
XF86XK_ClearGrab,
|
||||
Qt::Key_ClearGrab,
|
||||
XF86XK_Close,
|
||||
Qt::Key_Close,
|
||||
XF86XK_Copy,
|
||||
Qt::Key_Copy,
|
||||
XF86XK_Cut,
|
||||
Qt::Key_Cut,
|
||||
XF86XK_Display,
|
||||
Qt::Key_Display,
|
||||
XF86XK_DOS,
|
||||
Qt::Key_DOS,
|
||||
XF86XK_Documents,
|
||||
Qt::Key_Documents,
|
||||
XF86XK_Excel,
|
||||
Qt::Key_Excel,
|
||||
XF86XK_Explorer,
|
||||
Qt::Key_Explorer,
|
||||
XF86XK_Game,
|
||||
Qt::Key_Game,
|
||||
XF86XK_Go,
|
||||
Qt::Key_Go,
|
||||
XF86XK_iTouch,
|
||||
Qt::Key_iTouch,
|
||||
XF86XK_LogOff,
|
||||
Qt::Key_LogOff,
|
||||
XF86XK_Market,
|
||||
Qt::Key_Market,
|
||||
XF86XK_Meeting,
|
||||
Qt::Key_Meeting,
|
||||
XF86XK_MenuKB,
|
||||
Qt::Key_MenuKB,
|
||||
XF86XK_MenuPB,
|
||||
Qt::Key_MenuPB,
|
||||
XF86XK_MySites,
|
||||
Qt::Key_MySites,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_New,
|
||||
Qt::Key_New,
|
||||
#endif
|
||||
XF86XK_News,
|
||||
Qt::Key_News,
|
||||
XF86XK_OfficeHome,
|
||||
Qt::Key_OfficeHome,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_Open,
|
||||
Qt::Key_Open,
|
||||
#endif
|
||||
XF86XK_Option,
|
||||
Qt::Key_Option,
|
||||
XF86XK_Paste,
|
||||
Qt::Key_Paste,
|
||||
XF86XK_Phone,
|
||||
Qt::Key_Phone,
|
||||
XF86XK_Reply,
|
||||
Qt::Key_Reply,
|
||||
XF86XK_Reload,
|
||||
Qt::Key_Reload,
|
||||
XF86XK_RotateWindows,
|
||||
Qt::Key_RotateWindows,
|
||||
XF86XK_RotationPB,
|
||||
Qt::Key_RotationPB,
|
||||
XF86XK_RotationKB,
|
||||
Qt::Key_RotationKB,
|
||||
XF86XK_Save,
|
||||
Qt::Key_Save,
|
||||
XF86XK_Send,
|
||||
Qt::Key_Send,
|
||||
XF86XK_Spell,
|
||||
Qt::Key_Spell,
|
||||
XF86XK_SplitScreen,
|
||||
Qt::Key_SplitScreen,
|
||||
XF86XK_Support,
|
||||
Qt::Key_Support,
|
||||
XF86XK_TaskPane,
|
||||
Qt::Key_TaskPane,
|
||||
XF86XK_Terminal,
|
||||
Qt::Key_Terminal,
|
||||
XF86XK_Tools,
|
||||
Qt::Key_Tools,
|
||||
XF86XK_Travel,
|
||||
Qt::Key_Travel,
|
||||
XF86XK_Video,
|
||||
Qt::Key_Video,
|
||||
XF86XK_Word,
|
||||
Qt::Key_Word,
|
||||
XF86XK_Xfer,
|
||||
Qt::Key_Xfer,
|
||||
XF86XK_ZoomIn,
|
||||
Qt::Key_ZoomIn,
|
||||
XF86XK_ZoomOut,
|
||||
Qt::Key_ZoomOut,
|
||||
XF86XK_Away,
|
||||
Qt::Key_Away,
|
||||
XF86XK_Messenger,
|
||||
Qt::Key_Messenger,
|
||||
XF86XK_WebCam,
|
||||
Qt::Key_WebCam,
|
||||
XF86XK_MailForward,
|
||||
Qt::Key_MailForward,
|
||||
XF86XK_Pictures,
|
||||
Qt::Key_Pictures,
|
||||
XF86XK_Music,
|
||||
Qt::Key_Music,
|
||||
XF86XK_Battery,
|
||||
Qt::Key_Battery,
|
||||
XF86XK_Bluetooth,
|
||||
Qt::Key_Bluetooth,
|
||||
XF86XK_WLAN,
|
||||
Qt::Key_WLAN,
|
||||
XF86XK_UWB,
|
||||
Qt::Key_UWB,
|
||||
XF86XK_AudioForward,
|
||||
Qt::Key_AudioForward,
|
||||
XF86XK_AudioRepeat,
|
||||
Qt::Key_AudioRepeat,
|
||||
XF86XK_AudioRandomPlay,
|
||||
Qt::Key_AudioRandomPlay,
|
||||
XF86XK_Subtitle,
|
||||
Qt::Key_Subtitle,
|
||||
XF86XK_AudioCycleTrack,
|
||||
Qt::Key_AudioCycleTrack,
|
||||
XF86XK_Time,
|
||||
Qt::Key_Time,
|
||||
XF86XK_Select,
|
||||
Qt::Key_Select,
|
||||
XF86XK_View,
|
||||
Qt::Key_View,
|
||||
XF86XK_TopMenu,
|
||||
Qt::Key_TopMenu,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_Red,
|
||||
Qt::Key_Red,
|
||||
XF86XK_Green,
|
||||
Qt::Key_Green,
|
||||
XF86XK_Yellow,
|
||||
Qt::Key_Yellow,
|
||||
XF86XK_Blue,
|
||||
Qt::Key_Blue,
|
||||
#endif
|
||||
XF86XK_Bluetooth,
|
||||
Qt::Key_Bluetooth,
|
||||
XF86XK_Suspend,
|
||||
Qt::Key_Suspend,
|
||||
XF86XK_Hibernate,
|
||||
Qt::Key_Hibernate,
|
||||
#if QT_VERSION >= 0x050400
|
||||
XF86XK_TouchpadToggle,
|
||||
Qt::Key_TouchpadToggle,
|
||||
XF86XK_TouchpadOn,
|
||||
Qt::Key_TouchpadOn,
|
||||
XF86XK_TouchpadOff,
|
||||
Qt::Key_TouchpadOff,
|
||||
XF86XK_AudioMicMute,
|
||||
Qt::Key_MicMute,
|
||||
#endif
|
||||
XF86XK_Launch0,
|
||||
Qt::Key_Launch2, // ### Qt 6: remap properly
|
||||
XF86XK_Launch1,
|
||||
Qt::Key_Launch3,
|
||||
XF86XK_Launch2,
|
||||
Qt::Key_Launch4,
|
||||
XF86XK_Launch3,
|
||||
Qt::Key_Launch5,
|
||||
XF86XK_Launch4,
|
||||
Qt::Key_Launch6,
|
||||
XF86XK_Launch5,
|
||||
Qt::Key_Launch7,
|
||||
XF86XK_Launch6,
|
||||
Qt::Key_Launch8,
|
||||
XF86XK_Launch7,
|
||||
Qt::Key_Launch9,
|
||||
XF86XK_Launch8,
|
||||
Qt::Key_LaunchA,
|
||||
XF86XK_Launch9,
|
||||
Qt::Key_LaunchB,
|
||||
XF86XK_LaunchA,
|
||||
Qt::Key_LaunchC,
|
||||
XF86XK_LaunchB,
|
||||
Qt::Key_LaunchD,
|
||||
XF86XK_LaunchC,
|
||||
Qt::Key_LaunchE,
|
||||
XF86XK_LaunchD,
|
||||
Qt::Key_LaunchF,
|
||||
XF86XK_LaunchE,
|
||||
Qt::Key_LaunchG,
|
||||
XF86XK_LaunchF,
|
||||
Qt::Key_LaunchH,
|
||||
|
||||
0,
|
||||
0};
|
||||
@ -24,7 +24,6 @@
|
||||
#include "networkmanager.h"
|
||||
#include "lrcinstance.h"
|
||||
#include "appsettingsmanager.h"
|
||||
#include "utilsadapter.h"
|
||||
#include "qmlregister.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
@ -40,7 +39,7 @@ PluginAdapter::PluginAdapter(LRCInstance* instance,
|
||||
QString baseUrl)
|
||||
: QmlAdapterBase(instance, parent)
|
||||
, pluginStoreListModel_(new PluginStoreListModel(instance, this))
|
||||
, pluginVersionManager_(new PluginVersionManager(instance, this))
|
||||
, pluginVersionManager_(new PluginVersionManager(instance, settingsManager, this))
|
||||
, pluginListModel_(new PluginListModel(instance, this))
|
||||
, lrcInstance_(instance)
|
||||
, settingsManager_(settingsManager)
|
||||
|
||||
@ -218,10 +218,12 @@ void
|
||||
PluginListModel::onVersionStatusChanged(const QString& pluginId, PluginStatus::Role status)
|
||||
{
|
||||
auto pluginIndex = -1;
|
||||
for (auto& p : installedPlugins_) {
|
||||
QString pluginModelId = "";
|
||||
for (const auto& p : installedPlugins_) {
|
||||
auto details = lrcInstance_->pluginModel().getPluginDetails(p);
|
||||
if (details.name == pluginId) {
|
||||
if (details.id == pluginId) {
|
||||
pluginIndex = installedPlugins_.indexOf(p, -1);
|
||||
pluginModelId = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -229,6 +231,10 @@ PluginListModel::onVersionStatusChanged(const QString& pluginId, PluginStatus::R
|
||||
case PluginStatus::INSTALLED:
|
||||
addPlugin();
|
||||
break;
|
||||
case PluginStatus::FAILED:
|
||||
errorOccurred(pluginId);
|
||||
status = PluginStatus::UPDATABLE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -236,7 +242,8 @@ PluginListModel::onVersionStatusChanged(const QString& pluginId, PluginStatus::R
|
||||
if (pluginIndex == -1) {
|
||||
return;
|
||||
}
|
||||
pluginStatus_[pluginId] = status;
|
||||
pluginStatus_[pluginModelId] = status;
|
||||
pluginChanged(pluginIndex);
|
||||
switch (status) {
|
||||
case PluginStatus::INSTALLABLE:
|
||||
removePlugin(pluginIndex);
|
||||
|
||||
@ -72,6 +72,8 @@ Q_SIGNALS:
|
||||
void setVersionStatus(const QString& pluginId, PluginStatus::Role status);
|
||||
void autoUpdateChanged(bool state);
|
||||
void disabled(const QString& pluginId);
|
||||
void errorOccurred(const QString& pluginId);
|
||||
|
||||
public Q_SLOTS:
|
||||
void onVersionStatusChanged(const QString& pluginId, PluginStatus::Role status);
|
||||
void onNewVersionAvailable(const QString& pluginId, const QString& version);
|
||||
|
||||
@ -21,6 +21,8 @@
|
||||
#include "lrcinstance.h"
|
||||
#include "api/pluginmodel.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QMap>
|
||||
#include <QTimer>
|
||||
#include <QDir>
|
||||
@ -30,10 +32,10 @@ static constexpr int updatePeriod = 1000 * 60 * 60 * 24; // one day in millis
|
||||
struct PluginVersionManager::Impl : public QObject
|
||||
{
|
||||
public:
|
||||
Impl(LRCInstance* instance, PluginVersionManager& parent)
|
||||
Impl(LRCInstance* instance, AppSettingsManager* settingsManager, PluginVersionManager& parent)
|
||||
: QObject(nullptr)
|
||||
, parent_(parent)
|
||||
, settingsManager_(new AppSettingsManager(this))
|
||||
, settingsManager_(settingsManager)
|
||||
, lrcInstance_(instance)
|
||||
, updateTimer_(new QTimer(this))
|
||||
{
|
||||
@ -101,21 +103,20 @@ public:
|
||||
Q_EMIT parent_.versionStatusChanged(plugin.id, PluginStatus::Role::FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
parent_.sendGetRequest(QUrl(settingsManager_->getValue("PluginStoreEndpoint").toString()
|
||||
+ "/versions/" + plugin.id + "?arch="
|
||||
+ lrcInstance_->pluginModel().getPlatformInfo()["os"]),
|
||||
[this, plugin](const QByteArray& data) {
|
||||
// `data` represents the version in this case.
|
||||
if (plugin.version < data) {
|
||||
if (isAutoUpdaterEnabled()) {
|
||||
installRemotePlugin(plugin.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
parent_.versionStatusChanged(plugin.id,
|
||||
PluginStatus::Role::UPDATABLE);
|
||||
});
|
||||
parent_.sendGetRequest(
|
||||
QUrl(settingsManager_->getValue("PluginStoreEndpoint").toString() + "/versions/"
|
||||
+ plugin.id + "?arch=" + lrcInstance_->pluginModel().getPlatformInfo()["os"]),
|
||||
[this, plugin](const QByteArray& data) {
|
||||
// `data` represents the version in this case.
|
||||
auto result = QJsonDocument::fromJson(data).array().toVariantList()[0].toMap();
|
||||
if (parent_.checkVersion(plugin.version, result["version"].toString())) {
|
||||
if (isAutoUpdaterEnabled()) {
|
||||
installRemotePlugin(plugin.id);
|
||||
return;
|
||||
}
|
||||
parent_.versionStatusChanged(plugin.id, PluginStatus::Role::UPDATABLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void installRemotePlugin(const QString& pluginId)
|
||||
@ -163,9 +164,11 @@ public:
|
||||
QTimer* updateTimer_;
|
||||
};
|
||||
|
||||
PluginVersionManager::PluginVersionManager(LRCInstance* instance, QObject* parent)
|
||||
PluginVersionManager::PluginVersionManager(LRCInstance* instance,
|
||||
AppSettingsManager* settingsManager,
|
||||
QObject* parent)
|
||||
: NetworkManager(&instance->connectivityMonitor(), parent)
|
||||
, pimpl_(std::make_unique<Impl>(instance, *this))
|
||||
, pimpl_(std::make_unique<Impl>(instance, settingsManager, *this))
|
||||
{}
|
||||
|
||||
PluginVersionManager::~PluginVersionManager()
|
||||
@ -222,3 +225,22 @@ PluginVersionManager::installRemotePlugin(const QString& pluginId)
|
||||
{
|
||||
pimpl_->installRemotePlugin(pluginId);
|
||||
}
|
||||
|
||||
bool
|
||||
PluginVersionManager::checkVersion(const QString& installedVersion,
|
||||
const QString& remoteVersion) const
|
||||
{
|
||||
auto installedVersionDetails = installedVersion.split(".");
|
||||
auto remoteVersionDetails = remoteVersion.split(".");
|
||||
if (remoteVersionDetails.size() != installedVersionDetails.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < installedVersionDetails.size(); i++) {
|
||||
if (installedVersionDetails[i].toInt() < remoteVersionDetails[i].toInt()) {
|
||||
return true;
|
||||
} else if (installedVersionDetails[i].toInt() > remoteVersionDetails[i].toInt()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
class QString;
|
||||
class LRCInstance;
|
||||
class AppSettingsManager;
|
||||
|
||||
#define PLUGIN_STATUS_ROLES \
|
||||
X(INSTALLABLE) \
|
||||
@ -46,7 +47,9 @@ class PluginVersionManager final : public NetworkManager
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PluginVersionManager(LRCInstance* instance, QObject* parent = nullptr);
|
||||
explicit PluginVersionManager(LRCInstance* instance,
|
||||
AppSettingsManager* settingsManager,
|
||||
QObject* parent = nullptr);
|
||||
~PluginVersionManager();
|
||||
|
||||
Q_INVOKABLE bool isAutoUpdaterEnabled();
|
||||
@ -69,6 +72,7 @@ Q_SIGNALS:
|
||||
void newVersionAvailable(const QString& pluginId, const QString& version);
|
||||
|
||||
private:
|
||||
bool checkVersion(const QString& installedVersion, const QString& remoteVersion) const;
|
||||
QString baseUrl;
|
||||
bool autoUpdateCheck = false;
|
||||
QMap<QString, int> pluginRepliesId {};
|
||||
|
||||
53
src/app/pttlistener.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "appsettingsmanager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <QKeyEvent>
|
||||
|
||||
class PTTListener : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE Qt::Key getCurrentKey()
|
||||
{
|
||||
int keyInt = settingsManager_->getValue(Settings::Key::pttKey).toInt();
|
||||
Qt::Key key = static_cast<Qt::Key>(keyInt);
|
||||
return key;
|
||||
}
|
||||
|
||||
Q_INVOKABLE QString keyToString(Qt::Key key)
|
||||
{
|
||||
return QKeySequence(key).toString();
|
||||
}
|
||||
|
||||
Q_INVOKABLE void setPttKey(Qt::Key key)
|
||||
{
|
||||
settingsManager_->setValue(Settings::Key::pttKey, key);
|
||||
}
|
||||
Q_INVOKABLE bool getPttState()
|
||||
{
|
||||
return settingsManager_->getValue(Settings::Key::EnablePtt).toBool();
|
||||
}
|
||||
|
||||
PTTListener(AppSettingsManager* settingsManager, QObject* parent = nullptr);
|
||||
~PTTListener();
|
||||
|
||||
Q_SIGNALS:
|
||||
void pttKeyPressed();
|
||||
void pttKeyReleased();
|
||||
|
||||
#ifdef HAVE_GLOBAL_PTT
|
||||
public Q_SLOTS:
|
||||
void startListening();
|
||||
void stopListening();
|
||||
#endif
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> pimpl_;
|
||||
|
||||
AppSettingsManager* settingsManager_;
|
||||
};
|
||||
@ -55,7 +55,6 @@
|
||||
#include "appsettingsmanager.h"
|
||||
#include "mainapplication.h"
|
||||
#include "namedirectory.h"
|
||||
#include "pluginlistmodel.h"
|
||||
#include "pluginversionmanager.h"
|
||||
#include "appversionmanager.h"
|
||||
#include "pluginlistpreferencemodel.h"
|
||||
@ -105,33 +104,33 @@ namespace Utils {
|
||||
*/
|
||||
void
|
||||
registerTypes(QQmlEngine* engine,
|
||||
SystemTray* systemTray,
|
||||
LRCInstance* lrcInstance,
|
||||
SystemTray* systemTray,
|
||||
AppSettingsManager* settingsManager,
|
||||
ConnectivityMonitor* connectivityMonitor,
|
||||
ScreenInfo* screenInfo,
|
||||
QObject* parent)
|
||||
MainApplication* app)
|
||||
{
|
||||
// setup the adapters (their lifetimes are that of MainApplication)
|
||||
auto callAdapter = new CallAdapter(systemTray, lrcInstance, parent);
|
||||
auto previewEngine = new PreviewEngine(connectivityMonitor, parent);
|
||||
auto imageDownloader = new ImageDownloader(connectivityMonitor, parent);
|
||||
auto messagesAdapter = new MessagesAdapter(settingsManager, previewEngine, lrcInstance, parent);
|
||||
auto positionManager = new PositionManager(settingsManager, systemTray, lrcInstance, parent);
|
||||
auto conversationsAdapter = new ConversationsAdapter(systemTray, lrcInstance, parent);
|
||||
auto avAdapter = new AvAdapter(lrcInstance, parent);
|
||||
auto contactAdapter = new ContactAdapter(lrcInstance, parent);
|
||||
auto accountAdapter = new AccountAdapter(settingsManager, systemTray, lrcInstance, parent);
|
||||
auto utilsAdapter = new UtilsAdapter(settingsManager, systemTray, lrcInstance, parent);
|
||||
auto pluginAdapter = new PluginAdapter(lrcInstance, settingsManager, parent);
|
||||
auto currentCall = new CurrentCall(lrcInstance, parent);
|
||||
auto currentConversation = new CurrentConversation(lrcInstance, parent);
|
||||
auto currentAccount = new CurrentAccount(lrcInstance, settingsManager, parent);
|
||||
auto tipsModel = new TipsModel(settingsManager, parent);
|
||||
auto videoDevices = new VideoDevices(lrcInstance, parent);
|
||||
auto currentAccountToMigrate = new CurrentAccountToMigrate(lrcInstance, parent);
|
||||
auto avatarRegistry = new AvatarRegistry(lrcInstance, parent);
|
||||
auto wizardViewStepModel = new WizardViewStepModel(lrcInstance, accountAdapter, settingsManager, parent);
|
||||
auto callAdapter = new CallAdapter(settingsManager, systemTray, lrcInstance, engine);
|
||||
auto previewEngine = new PreviewEngine(connectivityMonitor, engine);
|
||||
auto imageDownloader = new ImageDownloader(connectivityMonitor, engine);
|
||||
auto messagesAdapter = new MessagesAdapter(settingsManager, previewEngine, lrcInstance, engine);
|
||||
auto positionManager = new PositionManager(settingsManager, systemTray, lrcInstance, engine);
|
||||
auto conversationsAdapter = new ConversationsAdapter(systemTray, lrcInstance, engine);
|
||||
auto avAdapter = new AvAdapter(lrcInstance, engine);
|
||||
auto contactAdapter = new ContactAdapter(lrcInstance, engine);
|
||||
auto accountAdapter = new AccountAdapter(settingsManager, systemTray, lrcInstance, engine);
|
||||
auto utilsAdapter = new UtilsAdapter(settingsManager, systemTray, lrcInstance, engine);
|
||||
auto pluginAdapter = new PluginAdapter(lrcInstance, settingsManager, engine);
|
||||
auto currentCall = new CurrentCall(lrcInstance, engine);
|
||||
auto currentConversation = new CurrentConversation(lrcInstance, engine);
|
||||
auto currentAccount = new CurrentAccount(lrcInstance, settingsManager, engine);
|
||||
auto tipsModel = new TipsModel(settingsManager, engine);
|
||||
auto videoDevices = new VideoDevices(lrcInstance, engine);
|
||||
auto currentAccountToMigrate = new CurrentAccountToMigrate(lrcInstance, engine);
|
||||
auto avatarRegistry = new AvatarRegistry(lrcInstance, engine);
|
||||
auto wizardViewStepModel = new WizardViewStepModel(lrcInstance, accountAdapter, settingsManager, engine);
|
||||
|
||||
// qml adapter registration
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, callAdapter, "CallAdapter");
|
||||
@ -197,7 +196,7 @@ registerTypes(QQmlEngine* engine,
|
||||
QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/constant/JamiResources.qml", JamiResources);
|
||||
QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/constant/MsgSeq.qml", MsgSeq);
|
||||
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, parent, "MainApplication")
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, app, "MainApplication")
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, screenInfo, "CurrentScreenInfo")
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, lrcInstance, "LRCInstance")
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, settingsManager, "AppSettingsManager")
|
||||
|
||||
@ -63,10 +63,10 @@ Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
|
||||
|
||||
namespace Utils {
|
||||
void registerTypes(QQmlEngine* engine,
|
||||
SystemTray* systemTray,
|
||||
LRCInstance* lrcInstance,
|
||||
SystemTray* systemTray,
|
||||
AppSettingsManager* appSettingsManager,
|
||||
ConnectivityMonitor* connectivityMonitor,
|
||||
ScreenInfo* screenInfo,
|
||||
QObject* parent);
|
||||
MainApplication* app);
|
||||
}
|
||||
|
||||
@ -45,7 +45,8 @@ SidePanelBase {
|
||||
"title": JamiStrings.manageAccountSettingsTitle
|
||||
}, {
|
||||
"id": 1,
|
||||
"title": JamiStrings.customizeProfile
|
||||
"title": JamiStrings.customizeProfile,
|
||||
"visible": CurrentAccount.type !== Profile.Type.SIP
|
||||
}, {
|
||||
"id": 2,
|
||||
"title": JamiStrings.linkedDevicesSettingsTitle,
|
||||
@ -70,10 +71,10 @@ SidePanelBase {
|
||||
"title": JamiStrings.appearance
|
||||
}, {
|
||||
"id": 7,
|
||||
"title": JamiStrings.locationSharingLabel
|
||||
"title": JamiStrings.chatSettingsTitle
|
||||
}, {
|
||||
"id": 8,
|
||||
"title": JamiStrings.fileTransfer
|
||||
"title": JamiStrings.locationSharingLabel
|
||||
}, {
|
||||
"id": 9,
|
||||
"title": JamiStrings.callRecording
|
||||
@ -124,6 +125,7 @@ SidePanelBase {
|
||||
|
||||
function onTypeChanged() {
|
||||
updateModel();
|
||||
select(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||