diff --git a/.github/workflows/macos-build.yml b/.github/workflows/macos-build.yml new file mode 100644 index 000000000..006c33a61 --- /dev/null +++ b/.github/workflows/macos-build.yml @@ -0,0 +1,30 @@ +# Build MapMap on macOS with Qt 6 +name: Build on macOS + +on: + push: + branches: [ dev, master ] + pull_request: + branches: [ dev, master ] + +jobs: + build: + runs-on: macos-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install dependencies + run: | + brew install qt + + - name: Configure with qmake + run: | + export PATH="$(brew --prefix qt)/bin:$PATH" + qmake mapmap.pro CONFIG+=release + + - name: Build + run: | + export PATH="$(brew --prefix qt)/bin:$PATH" + make -j$(sysctl -n hw.logicalcpu) diff --git a/.github/workflows/qt-linux.yml b/.github/workflows/qt-linux.yml deleted file mode 100644 index 92a2e9dd4..000000000 --- a/.github/workflows/qt-linux.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Build a Qt project on Ubuntu -name: Build on Ubuntu (old) - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -jobs: - build: - if: false # Disable for now - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Install Qt - uses: jurplel/install-qt-action@v4 - with: - version: '5.12.12' - host: 'linux' - target: 'desktop' - modules: 'gui core serialport network opengl xml' - - name: qmake - run: qmake . - - name: make - run: make - - name: make check - run: make check - -# - name: make distcheck -# run: make distcheck diff --git a/.github/workflows/qt-macos.yml b/.github/workflows/qt-macos.yml deleted file mode 100644 index a6f4f986c..000000000 --- a/.github/workflows/qt-macos.yml +++ /dev/null @@ -1,32 +0,0 @@ -# Build a Qt project on macOS -name: Build on macOS - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -jobs: - build: - if: false # Disable for now - - runs-on: macos-latest - - steps: - - uses: actions/checkout@v2 - - name: Install Qt - uses: jurplel/install-qt-action@v4 - with: - version: '5.12.12' - target: 'desktop' - modules: 'gui core serialport network opengl xml' - - name: qmake - run: qmake . - - name: make - run: make - - name: make check - run: make check - -# - name: make distcheck -# run: make distcheck diff --git a/.github/workflows/qt-windows.yml b/.github/workflows/qt-windows.yml deleted file mode 100644 index 563fb6ab6..000000000 --- a/.github/workflows/qt-windows.yml +++ /dev/null @@ -1,34 +0,0 @@ -# Build a Qt project on Windows -name: Build on Windows - -on: - push: - branches: [ develop ] - pull_request: - branches: [ develop ] - -jobs: - build: - if: false # Disable for now - - runs-on: windows-2019 - - steps: - - uses: actions/checkout@v4 - - name: Install Qt - uses: jurplel/install-qt-action@v2 - with: - version: '5.12.12' - host: 'windows' - target: 'desktop' - arch: 'win64_msvc2017_64' - modules: 'gui core serialport network opengl xml' - - name: qmake - run: qmake . - - name: make - run: make - - name: make check - run: make check - -# - name: make distcheck -# run: make distcheck diff --git a/.github/workflows/ubuntu-build.yml b/.github/workflows/ubuntu-build.yml index bdfa0ac97..1200f50aa 100644 --- a/.github/workflows/ubuntu-build.yml +++ b/.github/workflows/ubuntu-build.yml @@ -3,9 +3,9 @@ name: Build on Ubuntu on: push: - branches: [ develop, master ] + branches: [ dev, master ] pull_request: - branches: [ develop, master ] + branches: [ dev, master ] jobs: build: @@ -19,33 +19,17 @@ jobs: run: | sudo apt-get update sudo apt-get install -y \ - liblo-dev liblo-tools \ - qtbase5-dev \ - qttools5-dev-tools \ - qtmultimedia5-dev \ - libqt5opengl5-dev \ - qtwebengine5-dev \ - qt5-qmake \ - libqt5serialport5-dev \ - libqt5xml5 \ - libqt5network5 \ - libqt5multimedia5-plugins \ - libgstreamer1.0-dev \ - libgstreamer-plugins-base1.0-dev \ - gstreamer1.0-plugins-bad \ - gstreamer1.0-libav \ - gstreamer1.0-vaapi \ - gstreamer1.0-plugins-base \ - gstreamer1.0-plugins-base-apps \ - gstreamer1.0-plugins-good \ - gstreamer1.0-plugins-ugly \ - gstreamer1.0-x \ - gstreamer1.0-tools \ build-essential \ - pkg-config + libqt6opengl6-dev \ + libqt6openglwidgets6 \ + pkg-config \ + qmake6 \ + qt6-base-dev \ + qt6-multimedia-dev \ + qt6-tools-dev - name: Configure with qmake - run: qmake mapmap.pro + run: qmake6 mapmap.pro - name: Build run: make -j$(nproc) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml new file mode 100644 index 000000000..492d77088 --- /dev/null +++ b/.github/workflows/windows-build.yml @@ -0,0 +1,32 @@ +# Build MapMap on Windows with Qt 6 +name: Build on Windows + +on: + push: + branches: [ dev, master ] + pull_request: + branches: [ dev, master ] + +jobs: + build: + runs-on: windows-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install Qt 6 + uses: jurplel/install-qt-action@v4 + with: + version: '6.8.0' + host: 'windows' + target: 'desktop' + arch: 'win64_mingw' + modules: 'qtmultimedia' + tools: 'tools_mingw1310' + + - name: Configure with qmake + run: qmake mapmap.pro CONFIG+=release + + - name: Build + run: mingw32-make -j4 diff --git a/.gitignore b/.gitignore index c1f35df6a..a39ed2ec4 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,6 @@ Makefile* # Generated by Qt mapmap moc_*.cpp -prototypes/gst/ qrc_*.cpp *.moc src/*/mocs/* @@ -77,7 +76,7 @@ MapMap-*.*.*-*.dmg prototypes/sdl/run prototypes/wx-01-simple/run prototypes/wx-03-polyline/run -prototypes/wx-04-gst/run +prototypes/wx-04/run prototypes/wx-02-input-output/run prototypes/qgraphicsview contrib/qtpropertybrowser.new diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 58398ee10..000000000 --- a/.travis.yml +++ /dev/null @@ -1,77 +0,0 @@ -language: cpp -cache: ccache - - -jobs: - include: - - os: linux - dist: bionic - env: TARGET="linux64" - compiler: gcc - cache: - directories: - - ~/.ccache - before_cache: - - rm -f ~/.cache/*.log - - - os: osx - osx_image: xcode11.3 - env: TARGET="osx" - compiler: - - gcc - - clang - -before_install: - - if [ "$TARGET" == "linux64" ]; then - sudo apt-get update; - fi - - - if [ "$TARGET" == "osx" ]; then - brew update; - fi - -install: - - if [ "$TARGET" == "linux64" ]; then - sudo apt-get install qt5-default qttools5-dev-tools - libqt5opengl5-dev qtmultimedia5-dev qtwebengine5-dev; - sudo apt-get install liblo-dev liblo-tools; - sudo apt-get install libgstreamer1.0-dev - libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-bad - gstreamer1.0-libav gstreamer1.0-vaapi gstreamer1.0-plugins-base - gstreamer1.0-plugins-base-apps gstreamer1.0-plugins-good - gstreamer1.0-plugins-ugly gstreamer1.0-x gstreamer1.0-tools; - sudo apt-get install ccache; - fi - - - if [ "$TARGET" == "osx" ]; then - brew install qt; - brew install liblo; - brew install ccache; - export PATH="/usr/local/opt/ccache/libexec:$PATH"; - wget --quiet https://gstreamer.freedesktop.org/data/pkg/osx/1.16.2/gstreamer-1.0-1.16.2-x86_64.pkg; - sudo installer -verboseR -pkg gstreamer-1.0-1.16.2-x86_64.pkg -target /; - wget --quiet https://gstreamer.freedesktop.org/data/pkg/osx/1.16.2/gstreamer-1.0-devel-1.16.2-x86_64.pkg; - sudo installer -verboseR -pkg gstreamer-1.0-devel-1.16.2-x86_64.pkg -target /; - fi - -before_script: - - if [ "$TARGET" == "osx" ]; then - brew link qt --force; - brew link liblo --force; - gstreamer="GStreamer.framework/Versions/1.0/lib/GStreamer"; - app="MapMap.app"; - fi - -script: - - ccache -z - - ccache -s - - if [ "$TARGET" == "linux64" ]; then - qmake mapmap.pro; - make -j4; - fi - - - if [ "$TARGET" == "osx" ]; then - qmake -config release; - make -j4; - fi - - ccache -s diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b75dd8bd..c2f587d37 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ We love hearing about bugs! It's how we get them fixed. - Only if you don't find a relevant issue, open a new issue. A new issue does not generate more exposure/visibility than commenting on an existing one. - Make sure you give it a good title! A good title explains the core of the problem in about 5-10 words. (It's sometimes easier to write the title after you've written the description.) - In the description, include the following details: - 1. **relevant system information** such as which MapMap version, operating system, Qt version, Gstreamer version and IDE you are using, + 1. **relevant system information** such as which MapMap version, operating system, Qt version and IDE you are using, 2. what you were doing when you noticed the bug, 3. what you expected to happen, 4. what actually happened, and how to make it happen again (ie how to reproduce the bug). diff --git a/INSTALL.md b/INSTALL.md index ceab4f2cb..43ef78486 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -21,36 +21,15 @@ Alternatively: ### Ubuntu -NOTE: Tested on 13.10, 14.04, 15.04 and 16.04 - -Install basic development tools for Qt projects, plus liblo for OSC support: - -``` -sudo apt-get install -y \ - liblo-dev liblo-tools \ - qttools5-dev-tools \ - qtmultimedia5-dev \ - libqt5opengl5-dev \ - qtwebengine5-dev \ - libqt5multimedia5-plugins \ - qt5-default -``` - -Install GStreamer 1.0 libraries and plugins: +Install basic development tools for Qt 6 projects: ``` sudo apt-get install -y \ - libgstreamer1.0-dev \ - libgstreamer-plugins-base1.0-dev \ - gstreamer1.0-plugins-bad \ - gstreamer1.0-libav \ - gstreamer1.0-vaapi \ - gstreamer1.0-plugins-base \ - gstreamer1.0-plugins-base-apps \ - gstreamer1.0-plugins-good \ - gstreamer1.0-plugins-ugly \ - gstreamer1.0-x \ - gstreamer1.0-tools + qt6-tools-dev \ + qt6-multimedia-dev \ + qt6-base-dev \ + libqt6opengl6-dev \ + libqt6openglwidgets6 ``` Install extra packages if you want to build the documentation: @@ -65,61 +44,29 @@ sudo apt-get install -y \ ### Arch Linux -Install basic development tools for Qt projects, GStreamer 1.0 and liblo for OSC support: +Install basic development tools for Qt 6 projects: ``` -sudo pacman -S qt5-tools qt5-multimedia qt5-webengine liblo gstreamer +sudo pacman -S qt6-tools qt6-multimedia qt6-base ``` -Install GStreamer 1.0 libraries and plugins:: - -``` -sudo pacman -S gst-libav \ - gstreamer-vaapi \ - gst-plugins-bad \ - gst-plugins-base \ - gst-plugins-base-libs \ - gst-plugins-good \ - gst-plugins-ugly -``` - -Build on Mac OS X ------------------ - -NOTE: This has been tested on OS X 10.11 (El Capitan). +Build on macOS +-------------- Install tools and dependencies: -1) Install the Apple Developer Tools - - You need to register with a credit card in the Apple Store in order to download it (no need to pay, but Apple requires your credit card number). -2) Install Qt5 - - You can get the open source version from http://www.qt.io/download-open-source/ - - Run the installer and choose the default location (which should be ~/Qt). - - Latest tested version: 5.5.1= -3) Install liblo - - Use the following guide: http://macappstore.org/liblo/ - - OR compile from the tar.gz - it should install it to /usr/local -4) Install the GStreamer framework. You need the runtime and devel packages to be installed: - - https://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-1.6.0-x86_64.pkg - - https://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-devel-1.6.0-x86_64.pkg - - http://gstreamer.freedesktop.org/data/pkg/osx/1.6.0/gstreamer-1.0-1.6.0-x86_64-packages.dmg - -Do this: - ``` -./scripts/build.sh +./scripts/sh_install_deps_macos.sh ``` -It will create a .app and a .dmg. +Build: -DMGVERSION.txt should be created automatically with "1" as its contents. Update to "2", and so on, if needed. +``` +./scripts/sh_build_macos.sh +``` ### Troubleshooting -#### GStreamer header not found - -If you have a compilation error saying that file `````` cannot be found: make sure your GStreamer.framework folder is installed and is _not_ read-protected. - #### Corrupted OSC port If the appearance of the window of the OSC port number in the preferences seem corrupted, you might want to reset MapMap's preferences: @@ -128,27 +75,16 @@ If the appearance of the window of the OSC port number in the preferences seem c rm -f ~/Library/Preferences/info.mapmap.MapMap.plist ``` -To print debugging informations, launch it from the Terminal app like this:: - -``` -GSTPLUGIN_PATH=/Library/Frameworks/GStreamer.framework/Libraries GST_DEBUG=2 /Applications/MapMap.app/Contents/MacOS/MapMap -``` - Build on Windows ---------------- ## Build dynamic version to debug project: -- Download and install gstreamer-x86 [runtime](https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-mingw-x86-1.16.2.msi) and [devel](https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-devel-mingw-x86-1.16.2.msi) -- Download and install [Qt5 MinGW incl. QtCreator](https://www.qt.io/download-thank-you?os=windows) -- Add the GStreamer bin path (e.g. C:\gstreamer\1.0\x86\bin) to PATH variable into the QtCreator project build enviroment settings +- Download and install [Qt6 MinGW incl. QtCreator](https://www.qt.io/download-open-source/) - Build and run MapMap project within QtCreator (Ctrl-R) ## Build static version for release: -- Download and install gstreamer-x86 [runtime](https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-mingw-x86-1.16.2.msi) and [devel](https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-devel-mingw-x86-1.16.2.msi) -- Build a [Qt static environment](https://wiki.qt.io/Building_a_static_Qt_for_Windows_using_MinGW) (This [video](https://www.youtube.com/watch?v=nEQGrBiz2T0) may explain it better) +- Build a [Qt static environment](https://wiki.qt.io/Building_a_static_Qt_for_Windows_using_MinGW) - Build MapMap using QtCreator (qmake, build release) -- Copy all dll files of the gstreamer's bin folder (e.g. C:\gstreamer\1.0\x86\bin) into the target folder together with MapMap.exe -- Copy all dll files of the gstreamer's plugin folder (e.g. C:\gstreamer\1.0\x86\lib\gstreamer-1.0) into an new folder named 'plugin' in parallel to MapMap.exe. - Run MapMap.exe #### For packaging diff --git a/OSC b/OSC index 3f93117db..81a82aea0 100644 --- a/OSC +++ b/OSC @@ -27,5 +27,4 @@ You might consider using: * The txosc library for python. It contains osc-send * The oscsend utility -* The liblo C library diff --git a/README.md b/README.md index bc79ca602..574231031 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,7 @@ triggered by, audio to create an audio-visual narrative. Build status --------------- -Github Actions: ![Build on macOS](https://github.com/mapmapteam/mapmap/workflows/Build%20on%20macOS/badge.svg) ![Build on Ubuntu](https://github.com/mapmapteam/mapmap/workflows/Build%20on%20Ubuntu/badge.svg) ![Build on Windows](https://github.com/mapmapteam/mapmap/workflows/Build%20on%20Windows/badge.svg) - -Travis CI: [![Build on Linux and macOS](https://travis-ci.org/mapmapteam/mapmap.svg?branch=develop)](https://travis-ci.org/mapmapteam/mapmap) [![Build on Windows](https://ci.appveyor.com/api/projects/status/5b2ww0n8m8s9p55c?svg=true)](https://ci.appveyor.com/project/baydam/mapmap) +![Build on macOS](https://github.com/mapmapteam/mapmap/workflows/Build%20on%20macOS/badge.svg) ![Build on Ubuntu](https://github.com/mapmapteam/mapmap/workflows/Build%20on%20Ubuntu/badge.svg) ![Build on Windows](https://github.com/mapmapteam/mapmap/workflows/Build%20on%20Windows/badge.svg) Ackowledgements --------------- @@ -38,9 +36,6 @@ Build and installation ---------------------- To build and install it, see the INSTALL file provided with the source code. -To use this software on Mac OS X: -* Install GStreamer using http://gstreamer.freedesktop.org/data/pkg/osx/1.2.4.1/gstreamer-1.0-1.2.4.1-universal.pkg : you should customize the installation and choose to install all components. - To use this software on Gnu/Linux with window managers other than Unity, make sure that this package is NOT installed: appmenu-qt5 or else the menu will not show. diff --git a/TODO b/TODO index 8e7ef91ac..b7576d1a2 100644 --- a/TODO +++ b/TODO @@ -6,7 +6,7 @@ TODO before 0.2.0 * change xy position to integers? * "avec le soutien de l'Organisation internationale de la Francophonie", with the logo. * integration des icones de mike -* shmsrc???? non... on a plutot autre chose.. c'est a dire, plus de formes. +* plus de formes. * traduction complete. multilinguisme fonctionnel. * video upside-down fixed * manuel de base, bilingue. (en HTML dans le Contents?) @@ -27,7 +27,7 @@ Code * MapperGLCanvas has a strange name considering we also have a Mapper class; actually I'm thinking we should rename Mapper to MappingView or something (since a Mapper is actually the View of the Mapping class) * DONE Override includesPoint() in Mesh -* video gstreamer + Packaging --------- diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index ca5c435ae..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,38 +0,0 @@ -version: '{branch}-{build}' - -build: - verbosity: minimal - -environment: - matrix: - - BUILD: 'Release' - CONFIG: debug - -install: - - set QTDIR=C:\Qt\5.14.1\mingw73_32 - - set PATH=%PATH%;%QTDIR%\bin;C:\MinGW\bin - - ps: | - Write-Host "Installing GStreamer..." -ForegroundColor Cyan - $msiPath = "$($env:USERPROFILE)\gstreamer-1.0-mingw-x86-1.16.2.msi" - $gstreamerPath = "C:\" - Write-Host "Downloading..." - (New-Object Net.WebClient).DownloadFile('https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-mingw-x86-1.16.2.msi', $msiPath) - Write-Host "Installing..." - cmd /c start /wait msiexec /package $msiPath /passive ADDLOCAL=ALL TARGETDIR=$gstreamerPath - Write-Host "Installed" -ForegroundColor Green - - - ps: | - Write-Host "Installing GStreamer Devel..." -ForegroundColor Cyan - $msiPath = "$($env:USERPROFILE)\gstreamer-1.0-devel-mingw-x86-1.16.2.msi" - $gstreamerPath = "C:\" - Write-Host "Downloading..." - (New-Object Net.WebClient).DownloadFile('https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-devel-mingw-x86-1.16.2.msi', $msiPath) - Write-Host "Installing..." - cmd /c start /wait msiexec /package $msiPath /passive ADDLOCAL=ALL TARGETDIR=$gstreamerPath - Write-Host "Installed" -ForegroundColor Green - - - set GSTREAMER_1_0_ROOT_X86=C:\gstreamer\1.0\x86 - -build_script: - - C:\Qt\5.14.1\mingw73_32\bin\qmake.exe mapmap.pro - - mingw32-make diff --git a/docs/index.dox b/docs/index.dox index 1dfe2222a..994c98e7b 100644 --- a/docs/index.dox +++ b/docs/index.dox @@ -25,8 +25,5 @@ * * \section install_sec Installation * - * liblo-dev - * qttools5-dev-tools - * qt5-default - * ./build.sh + * See INSTALL.md for build instructions. */ diff --git a/mapmap.pro b/mapmap.pro index e6e3e16a2..4ce4515b9 100644 --- a/mapmap.pro +++ b/mapmap.pro @@ -53,7 +53,6 @@ system($$QMAKE_LRELEASE mapmap.pro) # Run lrelease # Linux-specific: unix:!macx { - QMAKE_CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 QMAKE_CXXFLAGS += -Wno-expansion-to-defined } diff --git a/resources/macOS/Get GStreamer macOS.url b/resources/macOS/Get GStreamer macOS.url deleted file mode 100644 index eaa4a20d1..000000000 --- a/resources/macOS/Get GStreamer macOS.url +++ /dev/null @@ -1,3 +0,0 @@ -[InternetShortcut] -URL=https://gstreamer.freedesktop.org/data/pkg/osx/1.14.0/gstreamer-1.0-1.14.0-x86_64.pkg -IconIndex=0 diff --git a/scripts/build.sh b/scripts/build.sh index d02a46546..7ee062c2e 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -26,7 +26,6 @@ do_create_dmg() { cp -R MapMap.app ${DMGDIR} cp README.md ${DMGDIR}/README.txt cp NEWS ${DMGDIR}/NEWS.txt - cp resources/macOS/Get\ GStreamer\ macOS.url ${DMGDIR}/ hdiutil create \ -volname ${DMGDIR} \ -srcfolder ${DMGDIR} \ @@ -68,7 +67,6 @@ if [[ $unamestr == "Darwin" ]]; then #export QMAKESPEC=macx-xcode qtbindir=~/Qt/${qtversion}/clang_64/bin/ PATH=$PATH:${qtbindir} - gstreamer="GStreamer.framework/Versions/1.0/lib/GStreamer" app="MapMap.app" # XXX @@ -100,12 +98,6 @@ if [[ $unamestr == "Darwin" ]]; then sudo killall Finder sudo killall Dock - # Bundle GStreamer framework in app - #echo "Bundling GStreamer ..." - #cp -R /Library/Frameworks/GStreamer.framework ${app}/Contents/Frameworks/ - #install_name_tool -id @executable_path/../Frameworks/${gstreamer} ${app}/Contents/Frameworks/${gstreamer} - #install_name_tool -change /Library/Frameworks/${gstreamer} @executable_path/../Frameworks/${gstreamer} ${app}/Contents/MacOs/MapMap - # do_fix_qt_plugins_in_app echo "Creating DMG ..." do_create_dmg diff --git a/scripts/run.sh b/scripts/run.sh index ca0dab573..308b7262b 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -1,6 +1,4 @@ #!/bin/bash -#export GST_PLUGIN_PATH=/Library/Frameworks/GStreamer.framework/Libraries -#export GST_DEBUG=2 export LANG=C if [[ `uname` == 'Linux' ]]; then diff --git a/scripts/sh_build_macos.sh b/scripts/sh_build_macos.sh new file mode 100644 index 000000000..2b1c121c4 --- /dev/null +++ b/scripts/sh_build_macos.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Build MapMap on macOS using Homebrew Qt 6. +# +# Run scripts/sh_install_deps_macos.sh first if dependencies are not yet installed. +# +# Usage: +# ./scripts/sh_build_macos.sh + +set -euo pipefail + +# Change to the project root regardless of where the script is called from. +cd "$(dirname "$0")/.." + +# --------------------------------------------------------------------------- +# Locate Homebrew Qt 6 +# --------------------------------------------------------------------------- +QT_PREFIX="$(brew --prefix qt)" + +export PATH="${QT_PREFIX}/bin:${PATH}" + +echo "qmake: $(command -v qmake)" +echo "Qt version: $(qmake --version | tail -1)" + +# --------------------------------------------------------------------------- +# Build +# --------------------------------------------------------------------------- +qmake mapmap.pro +make -j"$(sysctl -n hw.logicalcpu)" diff --git a/scripts/sh_install_deps_macos.sh b/scripts/sh_install_deps_macos.sh new file mode 100644 index 000000000..73bc3de69 --- /dev/null +++ b/scripts/sh_install_deps_macos.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Install build dependencies for MapMap on macOS using Homebrew. +# +# Qt 6 is used as the media backend (QMediaPlayer, QVideoSink, QCamera). +# +# Usage: +# chmod +x scripts/sh_install_deps_macos.sh +# ./scripts/sh_install_deps_macos.sh + +set -euo pipefail + +# --------------------------------------------------------------------------- +# Homebrew +# --------------------------------------------------------------------------- +if ! command -v brew &>/dev/null; then + echo "Homebrew not found. Installing..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +fi + +# --------------------------------------------------------------------------- +# Qt 6 +# Modules used: core gui widgets opengl openglwidgets xml network multimedia +# multimediawidgets +# --------------------------------------------------------------------------- +brew install qt + +# Make Qt 6 tools (qmake, lrelease, …) available on PATH for this session. +QT_PREFIX="$(brew --prefix qt)" +export PATH="${QT_PREFIX}/bin:${PATH}" +echo "Qt prefix: ${QT_PREFIX}" +echo "qmake: $(command -v qmake)" +qmake --version + +# --------------------------------------------------------------------------- +# Summary +# --------------------------------------------------------------------------- +cat <type() << endl; + qDebug() << "std::exception was caught: " << ex.what() << Qt::endl; + qDebug() << "event type: " << event->type() << Qt::endl; } return false; diff --git a/src/app/MainApplication.h b/src/app/MainApplication.h index 6741ab04d..269a68183 100644 --- a/src/app/MainApplication.h +++ b/src/app/MainApplication.h @@ -22,7 +22,6 @@ #ifndef MAINAPPLICATION_H_ #define MAINAPPLICATION_H_ -#include #include #include #include "MM.h" diff --git a/src/app/main.cpp b/src/app/main.cpp index a0d7044be..b3a481ec5 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -1,14 +1,12 @@ // NOTE: To run, it is recommended not to be in Compiz or Beryl, they have shown some instability. -#define USING_QT_5 (QT_VERSION >= QT_VERSION_CHECK(5,0,0)) - #include #include #include -#if USING_QT_5 #include #include -#endif +#include + #include "MM.h" #include "MainWindow.h" #include "MainApplication.h" @@ -20,18 +18,6 @@ MM_USE_NAMESPACE -static void set_env_vars_if_needed() -{ -#ifdef __MACOSX_CORE__ - std::cout << "OS X detected. Set environment for GStreamer support." << std::endl; - if (0 == setenv("GST_PLUGIN_PATH", "/Library/Frameworks/GStreamer.framework/Libraries", 1)) - std::cout << " * GST_PLUGIN_PATH=/Library/Frameworks/GStreamer.framework/Libraries" << std::endl; - if (0 == setenv("GST_DEBUG", "2", 1)) - std::cout << " * GST_DEBUG=2" << std::endl; - //setenv("LANG", "C", 1); -#endif // __MACOSX_CORE__ -} - // This class is just used to provide sleep functionalities in the main() method. class I : public QThread { @@ -75,18 +61,17 @@ void logMessageHandler(QtMsgType type, const QMessageLogContext &context, const int main(int argc, char *argv[]) { - set_env_vars_if_needed(); + // Enable shared OpenGL contexts so the two canvases share textures. + QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // Initialize meta-object registry. initRegistry(); MainApplication app(argc, argv); - - // Install message handler - // after QGuiApplication has been instanciated + + // Install message handler after QGuiApplication has been instantiated. qInstallMessageHandler(logMessageHandler); -#if USING_QT_5 QCommandLineParser parser; parser.setApplicationDescription("Video mapping editor"); @@ -150,13 +135,12 @@ int main(int argc, char *argv[]) QTranslator appTranslator; if (MM::SUPPORTED_LANGUAGES.contains(lang)) { - //QLocale::setDefault(QLocale(lang)); #ifdef Q_OS_WIN32 qtTranslator.load(QString("qt_%1").arg(lang), QApplication::applicationDirPath().append("/translations")); #else qtTranslator.load(QString("qtbase_%1").arg(lang), - QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + QLibraryInfo::path(QLibraryInfo::TranslationsPath)); #endif app.installTranslator(&qtTranslator); @@ -167,15 +151,6 @@ int main(int argc, char *argv[]) qWarning() << "Unrecognized/unsupported language: " << lang; } - -#endif // USING_QT_5 - - if (! QGLFormat::hasOpenGL()) - { - qFatal("This system has no OpenGL support."); - return 1; - } - // Create splash screen. QPixmap pixmap(":/mapmap-splash"); QSplashScreen splash(pixmap); @@ -201,7 +176,6 @@ int main(int argc, char *argv[]) stylesheet.open(QFile::ReadOnly); app.setStyleSheet(QLatin1String(stylesheet.readAll())); -#if USING_QT_5 // read positional argument: const QStringList args = parser.positionalArguments(); QString projectFileValue = QString(); @@ -234,9 +208,6 @@ int main(int argc, char *argv[]) else qFatal("Invalid option ."); -#endif - - // Terminate splash. splash.showMessage(" " + QObject::tr("Done."), Qt::AlignLeft | Qt::AlignTop, MM::WHITE); @@ -246,12 +217,10 @@ int main(int argc, char *argv[]) // Launch program. win->show(); -#if USING_QT_5 if (parser.isSet(fullscreenOption)) { win->startFullScreen(); } -#endif // Start app. int result = app.exec(); diff --git a/src/control/OscInterface.cpp b/src/control/OscInterface.cpp index 46c7cac3b..bfe1a3b57 100644 --- a/src/control/OscInterface.cpp +++ b/src/control/OscInterface.cpp @@ -143,7 +143,7 @@ static void printCommand(QVariantList &command) qDebug() << "(?) "; } } - qDebug() << endl; + qDebug() << Qt::endl; } void OscInterface::applyOscCommand(MainWindow &main_window, QVariantList & command) { @@ -270,7 +270,7 @@ void OscInterface::applyOscCommand(MainWindow &main_window, QVariantList & comma if (! pathIsValid) { - qDebug() << "Path could not be processed: " << path << endl; + qDebug() << "Path could not be processed: " << path << Qt::endl; printCommand(command); } diff --git a/src/control/qosc/oscreceiver.cpp b/src/control/qosc/oscreceiver.cpp index 58d98ca3e..6f324944b 100644 --- a/src/control/qosc/oscreceiver.cpp +++ b/src/control/qosc/oscreceiver.cpp @@ -26,7 +26,7 @@ void OscReceiver::readyReadCb() { } void OscReceiver::byteArrayToVariantList(QVariantList& outputVariantList, QString& outputOscAddress, const QByteArray& inputByteArray) { - osc::ReceivedPacket packet(inputByteArray.data(), inputByteArray.size()); + osc::ReceivedPacket packet(inputByteArray.data(), static_cast(inputByteArray.size())); // TODO: catch parsing exceptions if (packet.IsMessage()) { osc::ReceivedMessage message(packet); diff --git a/src/control/qosc/qosc_global.h b/src/control/qosc/qosc_global.h index 3f42a4d33..b650ac253 100644 --- a/src/control/qosc/qosc_global.h +++ b/src/control/qosc/qosc_global.h @@ -3,5 +3,5 @@ #if defined(QOSC_LIBRARY) # define QOSC_EXPORT Q_DECL_EXPORT #else -# define QOSC_EXPORT Q_DECL_IMPORT +# define QOSC_EXPORT #endif diff --git a/src/core/CameraImpl.cpp b/src/core/CameraImpl.cpp index 93dc6ac9b..ac2b8f229 100644 --- a/src/core/CameraImpl.cpp +++ b/src/core/CameraImpl.cpp @@ -18,59 +18,81 @@ */ #include "CameraImpl.h" +#include +#include namespace mmp { -CameraImpl::CameraImpl() : - _camera(nullptr), - _cameraSurface(nullptr) +CameraImpl::CameraImpl() + : _camera(nullptr), + _captureSession(nullptr), + _cameraSurface(nullptr) { - } CameraImpl::~CameraImpl() { - _camera->stop(); + if (_camera) + _camera->stop(); delete _camera; + delete _captureSession; delete _cameraSurface; } -bool CameraImpl::loadMovie(const QString &deviceName) +bool CameraImpl::loadMovie(const QString &deviceId) { - VideoImpl::loadMovie(deviceName); - - _camera = new QCamera(deviceName.toLocal8Bit()); - - _cameraSurface = new CameraSurface(); - - _camera->setViewfinder(_cameraSurface); - - if (_camera->isAvailable()) - _camera->start(); - - if (_camera->state() == QCamera::ActiveState) - return true; - - if (_camera->error() != QCamera::NoError) - QMessageBox(QMessageBox::Critical, "Camera Error", - "Failed to start: " + _camera->errorString()).exec(); - - return false; + VideoImpl::loadMovie(deviceId); + + // Find the camera device matching the given ID. + QCameraDevice dev; + for (const QCameraDevice& d : QMediaDevices::videoInputs()) { + if (QString::fromUtf8(d.id()) == deviceId) { + dev = d; + break; + } + } + + if (dev.isNull()) { + // Fall back to default camera. + dev = QMediaDevices::defaultVideoInput(); + if (dev.isNull()) { + qWarning() << "No camera available for device:" << deviceId; + return false; + } + } + + _cameraSurface = new CameraSurface(); + _camera = new QCamera(dev); + _captureSession = new QMediaCaptureSession(); + + _captureSession->setCamera(_camera); + _captureSession->setVideoSink(_cameraSurface->videoSink()); + + _camera->start(); + + if (!_camera->isActive()) { + qWarning() << "Failed to start camera."; + return false; + } + + _videoIsConnected = true; + _setMovieReady(true); + return true; } int CameraImpl::getWidth() const { - return _cameraSurface->surfaceFormat().frameWidth(); + return _cameraSurface ? _cameraSurface->frameWidth() : -1; } int CameraImpl::getHeight() const { - return _cameraSurface->surfaceFormat().frameHeight(); + return _cameraSurface ? _cameraSurface->frameHeight() : -1; } -const uchar *CameraImpl::getBits() +const uchar* CameraImpl::getBits() { - return _cameraSurface->bits(); + return _cameraSurface ? _cameraSurface->bits() : nullptr; } } diff --git a/src/core/CameraImpl.h b/src/core/CameraImpl.h index b6bca55eb..852152f94 100644 --- a/src/core/CameraImpl.h +++ b/src/core/CameraImpl.h @@ -24,7 +24,9 @@ #include "VideoImpl.h" #include -#include +#include +#include +#include namespace mmp { @@ -34,22 +36,22 @@ class CameraImpl : public VideoImpl CameraImpl(); ~CameraImpl(); - bool loadMovie(const QString& deviceName); - bool isLive() { return true; } + bool loadMovie(const QString& deviceName) override; + bool isLive() override { return true; } + bool seekTo(qint64) override { return false; } - int getWidth() const; - int getHeight() const; + int getWidth() const override; + int getHeight() const override; - const uchar* getBits(); + const uchar* getBits() override; - bool hasBits() const { return _cameraSurface->isActive(); } - - bool bitsHaveChanged() const { return true; } + bool hasBits() const override { return _cameraSurface && _cameraSurface->isActive(); } + bool bitsHaveChanged() const override { return true; } private: - QCamera *_camera; - CameraSurface *_cameraSurface; - + QCamera *_camera; + QMediaCaptureSession *_captureSession; + CameraSurface *_cameraSurface; }; } diff --git a/src/core/CameraSurface.cpp b/src/core/CameraSurface.cpp index f62d6f2fc..d6ba12728 100644 --- a/src/core/CameraSurface.cpp +++ b/src/core/CameraSurface.cpp @@ -6,110 +6,43 @@ ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** +** ... ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "CameraSurface.h" - -#include -#include #include namespace mmp { CameraSurface::CameraSurface(QObject *parent) - : QAbstractVideoSurface(parent) + : QObject(parent), + _videoSink(new QVideoSink(this)) { + connect(_videoSink, &QVideoSink::videoFrameChanged, + this, &CameraSurface::onVideoFrameChanged); } CameraSurface::~CameraSurface() { } -QList CameraSurface::supportedPixelFormats( - QAbstractVideoBuffer::HandleType handleType) const -{ - - if (handleType == QAbstractVideoBuffer::NoHandle) { - return QList() - << QVideoFrame::Format_ARGB32 - << QVideoFrame::Format_ARGB32_Premultiplied - << QVideoFrame::Format_RGB32 - << QVideoFrame::Format_RGB24 - ; - } else { - return QList(); - } -} - -bool CameraSurface::present(const QVideoFrame &frame) +void CameraSurface::onVideoFrameChanged(const QVideoFrame& frame) { - if (frame.isValid()) { - // Copy current frame. - QVideoFrame currentFrame(frame); + if (!frame.isValid()) + return; - if (currentFrame.map(QAbstractVideoBuffer::ReadOnly)) - { - QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(currentFrame.pixelFormat()); - if (imageFormat != QImage::Format_Invalid) { - _temporaryImage = QImage(currentFrame.bits(), - currentFrame.width(), - currentFrame.height(), - imageFormat); - } else { - int nbytes = currentFrame.mappedBytes(); - _temporaryImage = QImage::fromData(currentFrame.bits(), nbytes); - } - currentFrame.unmap(); - } + QImage img = frame.toImage().convertToFormat(QImage::Format_RGBA8888); + if (img.isNull()) + return; #ifdef Q_OS_WIN - _temporaryImage = QGLWidget::convertToGLFormat(_temporaryImage); + _temporaryImage = img; #else - // Convert to OpenGLformat and apply transforms to straighten. - _temporaryImage = QGLWidget::convertToGLFormat(_temporaryImage) - .mirrored(true, false) - .transformed(QTransform().rotate(180)); + // Straighten the image for OpenGL (bottom-left origin convention). + _temporaryImage = img.mirrored(true, false).transformed(QTransform().rotate(180)); #endif - - return true; - } - - return false; -} - -const uchar* CameraSurface::bits() -{ - return _temporaryImage.bits(); } } diff --git a/src/core/CameraSurface.h b/src/core/CameraSurface.h index f89072339..54943722e 100644 --- a/src/core/CameraSurface.h +++ b/src/core/CameraSurface.h @@ -41,28 +41,43 @@ #ifndef CAMERA_SURFACE_H_ #define CAMERA_SURFACE_H_ -#include -#include -#include -#include +#include +#include +#include +#include namespace mmp { -class CameraSurface : public QAbstractVideoSurface +/** + * Wraps a QVideoSink to receive camera frames and convert them to RGBA. + * CameraImpl connects its QMediaCaptureSession to videoSink() and reads + * frames via bits(). + */ +class CameraSurface : public QObject { Q_OBJECT public: - CameraSurface(QObject *parent = nullptr); + explicit CameraSurface(QObject *parent = nullptr); ~CameraSurface() override; - QList supportedPixelFormats( - QAbstractVideoBuffer::HandleType handleType) const override; - bool present(const QVideoFrame &frame) override; + /// The QVideoSink that should be connected to the QMediaCaptureSession. + QVideoSink* videoSink() const { return _videoSink; } - const uchar* bits(); + /// Returns true once at least one frame has been received. + bool isActive() const { return !_temporaryImage.isNull(); } + + /// Returns raw RGBA bytes of the latest camera frame. + const uchar* bits() const { return _temporaryImage.bits(); } + + int frameWidth() const { return _temporaryImage.width(); } + int frameHeight() const { return _temporaryImage.height(); } + +private slots: + void onVideoFrameChanged(const QVideoFrame& frame); private: - QImage _temporaryImage; + QVideoSink *_videoSink; + QImage _temporaryImage; }; } diff --git a/src/core/Element.cpp b/src/core/Element.cpp index 5f539f4df..12f9c2dae 100644 --- a/src/core/Element.cpp +++ b/src/core/Element.cpp @@ -68,24 +68,24 @@ void Element::setOpacity(float opacity) } } -void Element::read(const QDomElement& obj) +void Element::read(const QJsonObject& obj) { Serializable::read(obj); // Check id. - Q_ASSERT(_id == obj.attribute("id").toInt()); + Q_ASSERT(_id == obj["id"].toInt()); } -void Element::write(QDomElement& obj) +void Element::write(QJsonObject& obj) { Serializable::write(obj); // Set id. - obj.setAttribute("id", getId()); + obj["id"] = getId(); } void Element::_emitPropertyChanged(const QString& propertyName) { - emit propertyChanged(getId(), propertyName, property(propertyName.toAscii())); + emit propertyChanged(getId(), propertyName, property(propertyName.toLatin1())); } } diff --git a/src/core/Element.h b/src/core/Element.h index cf7b60f49..3a776fb5a 100644 --- a/src/core/Element.h +++ b/src/core/Element.h @@ -64,16 +64,13 @@ class Element : public Serializable virtual QIcon getIcon() const { return QIcon(); } - virtual void read(const QDomElement& obj); - virtual void write(QDomElement& obj); + virtual void read(const QJsonObject& obj); + virtual void write(QJsonObject& obj); signals: void propertyChanged(uid id, QString propertyName, QVariant value); protected: - virtual QList _propertiesAttributes() const - { return Serializable::_propertiesAttributes() << "name" << "locked"; } - void _emitPropertyChanged(const QString& propertyName); private: diff --git a/src/core/Mapping.cpp b/src/core/Mapping.cpp index 8cf4bf5f9..68f2cf11f 100644 --- a/src/core/Mapping.cpp +++ b/src/core/Mapping.cpp @@ -98,14 +98,12 @@ void Mapping::setPaintById(uid paintId) setPaint(MainWindow::window()->getMappingManager().getPaintById(paintId)); } -void Mapping::read(const QDomElement& obj) +void Mapping::read(const QJsonObject& obj) { - // Read basic data. Element::read(obj); - // // Read paint (stored in attributes for backward compatibility). - int paintId = obj.attribute(ProjectLabels::PAINT_ID).toInt(); - setPaintById(paintId); + int paintId = obj[ProjectLabels::SOURCE_ID].toInt(); + setPaintById(paintId); // Read output shape. _readShape(obj, true); @@ -115,16 +113,13 @@ void Mapping::read(const QDomElement& obj) { _readShape(obj, false); } - } -void Mapping::write(QDomElement& obj) +void Mapping::write(QJsonObject& obj) { - // Write basic data. Element::write(obj); - // // Write paint ID. - obj.setAttribute("paintId", getPaintId()); + obj[ProjectLabels::SOURCE_ID] = getPaintId(); // Write output shape. _writeShape(obj, true); @@ -136,49 +131,43 @@ void Mapping::write(QDomElement& obj) } } -void Mapping::_readShape(const QDomElement& obj, bool isOutput) +void Mapping::_readShape(const QJsonObject& obj, bool isOutput) { - QString tag = isOutput ? ProjectLabels::DESTINATION : ProjectLabels::SOURCE; + QString tag = isOutput ? ProjectLabels::DESTINATION : ProjectLabels::SOURCE; - QDomElement shapeObj = obj.firstChildElement(tag); + QJsonObject shapeObj = obj[tag].toObject(); - QString className = Serializable::classNameCleanToReal(shapeObj.attribute(ProjectLabels::CLASS_NAME)); + QString className = Serializable::classNameCleanToReal(shapeObj[ProjectLabels::CLASS_NAME].toString()); const QMetaObject* metaObject = MetaObjectRegistry::instance().getMetaObject(className); if (metaObject) { - // Create new instance. - MShape::ptr shape (qobject_cast(metaObject->newInstance())); + MShape::ptr shape(qobject_cast(metaObject->newInstance())); if (shape.isNull()) { - qDebug() << QObject::tr("Problem at creation of shape.") << endl; -// _xml.raiseError(QObject::tr("Problem at creation of paint.")); + qDebug() << QObject::tr("Problem at creation of shape.") << Qt::endl; } - // Read shape. shape->read(shapeObj); - // Set shape. if (isOutput) setShape(shape); else setInputShape(shape); } - else { - qDebug() << QObject::tr("Unable to create paint of type '%1'.").arg(className) << endl; + qDebug() << QObject::tr("Unable to create shape of type '%1'.").arg(className) << Qt::endl; } - } -void Mapping::_writeShape(QDomElement& obj, bool isOutput) +void Mapping::_writeShape(QJsonObject& obj, bool isOutput) { - QString tag = isOutput ? ProjectLabels::DESTINATION : ProjectLabels::SOURCE; + QString tag = isOutput ? ProjectLabels::DESTINATION : ProjectLabels::SOURCE; MShape::ptr shape = isOutput ? getShape() : getInputShape(); - QDomElement shapeObj = obj.ownerDocument().createElement(tag); + QJsonObject shapeObj; shape->write(shapeObj); - obj.appendChild(shapeObj); + obj[tag] = shapeObj; } bool ColorMapping::paintIsCompatible(Paint::ptr paint) const diff --git a/src/core/Mapping.h b/src/core/Mapping.h index 2c1302f27..194aec80b 100644 --- a/src/core/Mapping.h +++ b/src/core/Mapping.h @@ -152,15 +152,12 @@ class Mapping : public Element virtual void setShape(MShape::ptr s) { _shape = s; } virtual void setInputShape(MShape::ptr s) { _inputShape = s; } - virtual void read(const QDomElement& obj); - virtual void write(QDomElement& obj); + virtual void read(const QJsonObject& obj); + virtual void write(QJsonObject& obj); protected: - virtual QList _propertiesAttributes() const - { return Element::_propertiesAttributes() << "solo" << "visible" << "depth"; } - - void _readShape(const QDomElement& obj, bool isOutput); - void _writeShape(QDomElement& obj, bool isOutput); + void _readShape(const QJsonObject& obj, bool isOutput); + void _writeShape(QJsonObject& obj, bool isOutput); }; /** diff --git a/src/core/MappingManager.h b/src/core/MappingManager.h index 9bc74f37f..c8ec64140 100644 --- a/src/core/MappingManager.h +++ b/src/core/MappingManager.h @@ -23,6 +23,7 @@ #include #include +#include #include "Paint.h" #include "Mapping.h" @@ -163,10 +164,10 @@ class MappingManager QVector > _getElementsByNameRegExp(const QVector >& vector, QString namePattern) { QVector > matchedElems; - QRegExp regExp(namePattern, Qt::CaseSensitive, QRegExp::Wildcard); + QRegularExpression regExp(QRegularExpression::wildcardToRegularExpression(namePattern)); for (QSharedPointer it: vector) { - if (regExp.exactMatch(it->getName())) + if (regExp.match(it->getName()).hasMatch()) { matchedElems.push_back(it); } diff --git a/src/core/Paint.cpp b/src/core/Paint.cpp index b3f99bb64..4ad043130 100644 --- a/src/core/Paint.cpp +++ b/src/core/Paint.cpp @@ -20,10 +20,13 @@ #include "Paint.h" #include "VideoImpl.h" -#include "VideoUriDecodeBinImpl.h" +#include "VideoPlayerImpl.h" #include "CameraImpl.h" -#include "VideoShmSrcImpl.h" #include +#include +#include +#include +#include namespace mmp { @@ -37,24 +40,20 @@ void Texture::update() } } -void Texture::read(const QDomElement& obj) +void Texture::read(const QJsonObject& obj) { Paint::read(obj); - // Set x and y. - QDomElement e; - e = obj.firstChildElement("x"); - if (!e.isNull()) - setX(e.text().toDouble()); - e = obj.firstChildElement("y"); - if (!e.isNull()) - setY(e.text().toDouble()); + if (obj.contains("x")) + setX(obj["x"].toDouble()); + if (obj.contains("y")) + setY(obj["y"].toDouble()); } -void Texture::write(QDomElement& obj) +void Texture::write(QJsonObject& obj) { Paint::write(obj); - _writeNode(obj, "x", QString::number(getX())); - _writeNode(obj, "y", QString::number(getY())); + obj["x"] = getX(); + obj["y"] = getY(); } Paint::Paint(uid id) @@ -104,15 +103,13 @@ bool Image::setUri(const QString &uri) void Image::build() { - // Read all images. + // Read all images and convert to RGBA for direct upload to OpenGL. QImageReader reader(_uri); _images.clear(); - for (int i=0; iloadMovie(uri)) { - qDebug() << "Cannot load movie " << uri << "." << endl; + qDebug() << "Cannot load movie " << uri << "." << Qt::endl; return false; } @@ -324,13 +321,13 @@ bool Video::setUri(const QString &uri) // Wait for the first samples to be available to make sure we are ready. if (!_impl->waitForNextBits(ICON_TIMEOUT)) { - qDebug() << "No bits coming" << endl; + qDebug() << "No bits coming" << Qt::endl; return false; } if (_videoType != VIDEO_WEBCAM) { // Generated thumbnail if source type is not camera if (!_generateThumbnail()) - qDebug() << "Could not generate thumbnail for " << uri << ": using generic icon." << endl; + qDebug() << "Could not generate thumbnail for " << uri << ": using generic icon." << Qt::endl; } _emitPropertyChanged("uri"); @@ -379,7 +376,7 @@ bool Video::_generateThumbnail() const uchar* bits; if (!_impl->waitForNextBits(ICON_TIMEOUT, &bits)) { - qDebug() << "Second waiting wrong..." << endl; + qDebug() << "Second waiting wrong..." << Qt::endl; return false; } diff --git a/src/core/Paint.h b/src/core/Paint.h index a1066405b..605310334 100644 --- a/src/core/Paint.h +++ b/src/core/Paint.h @@ -23,10 +23,10 @@ #define PAINT_H_ #include -#include #include #include +#include #include #if __APPLE__ @@ -38,14 +38,14 @@ #include "Element.h" #include "Maths.h" -#include +#include +#include namespace mmp { typedef enum { VIDEO_URI, - VIDEO_WEBCAM, - VIDEO_SHMSRC + VIDEO_WEBCAM } VideoType; /** @@ -206,12 +206,15 @@ class Texture : public Paint virtual QRectF getRect() const { return QRectF(getX(), getY(), getWidth(), getHeight()); } - virtual void read(const QDomElement& obj); - virtual void write(QDomElement& obj); + virtual void read(const QJsonObject& obj); + virtual void write(QJsonObject& obj); - // Get Camera human-readable name from url + // Get Camera human-readable name from device ID QString getCameraNameFromUri(const QString &uri) { - return QCameraInfo(uri.toLocal8Bit()).description(); + for (const QCameraDevice& d : QMediaDevices::videoInputs()) + if (QString::fromUtf8(d.id()) == uri) + return d.description(); + return uri; } protected: @@ -367,10 +370,6 @@ class Video : public Texture QIcon _icon; VideoType _videoType; - /** - * Private implementation, so that GStreamer headers don't need - * to be included from every file in the project. - */ VideoImpl *_impl; }; diff --git a/src/core/ProjectLabels.cpp b/src/core/ProjectLabels.cpp index 08ff6097c..a3c81fe98 100644 --- a/src/core/ProjectLabels.cpp +++ b/src/core/ProjectLabels.cpp @@ -22,10 +22,10 @@ namespace mmp { const char* ProjectLabels::CLASS_NAME = "className"; -const char* ProjectLabels::PAINTS = "paints"; -const char* ProjectLabels::MAPPINGS = "mappings"; +const char* ProjectLabels::SOURCES = "sources"; +const char* ProjectLabels::LAYERS = "layers"; const char* ProjectLabels::ID = "id"; -const char* ProjectLabels::PAINT_ID = "paintId"; +const char* ProjectLabels::SOURCE_ID = "sourceId"; const char* ProjectLabels::NAME = "name"; const char* ProjectLabels::SOURCE = "source"; const char* ProjectLabels::DESTINATION = "destination"; diff --git a/src/core/ProjectLabels.h b/src/core/ProjectLabels.h index 28225aac1..34a4563db 100644 --- a/src/core/ProjectLabels.h +++ b/src/core/ProjectLabels.h @@ -27,12 +27,12 @@ namespace mmp { class ProjectLabels { public: static const char* CLASS_NAME; - static const char* PAINTS; - static const char* MAPPINGS; + static const char* SOURCES; + static const char* LAYERS; static const char* ID; static const char* NAME; - static const char* PAINT_ID; + static const char* SOURCE_ID; static const char* DESTINATION; static const char* SOURCE; diff --git a/src/core/ProjectReader.cpp b/src/core/ProjectReader.cpp index 0cd6e3896..d78105017 100644 --- a/src/core/ProjectReader.cpp +++ b/src/core/ProjectReader.cpp @@ -18,9 +18,7 @@ * along with this program. If not, see . */ #include "ProjectReader.h" -#include #include -#include namespace mmp { @@ -37,63 +35,52 @@ bool ProjectReader::isValidVersion(const QString& versionString) bool ProjectReader::readFile(QIODevice *device) { - QString errorStr; - int errorLine; - int errorColumn; - - QDomDocument doc; - if (!doc.setContent(device, false, &errorStr, &errorLine, &errorColumn)) { - std::cerr << "Error: Parse error at line " << errorLine << ", " - << "column " << errorColumn << ": " - << qPrintable(errorStr) << std::endl; + QJsonParseError parseError; + QJsonDocument doc = QJsonDocument::fromJson(device->readAll(), &parseError); + if (doc.isNull()) { + _errorString = QString("Parse error at offset %1: %2") + .arg(parseError.offset).arg(parseError.errorString()); return false; } - QDomElement root = doc.documentElement(); - QString projectVersion = root.attribute("version"); - // The handling of the version number will get fancier as we go. - if (root.tagName() != "project") { - _xml.raiseError(QObject::tr("The contents of this file does not look like a MapMap project.")); + QJsonObject root = doc.object(); + QString projectVersion = root["version"].toString(); + + if (projectVersion.isEmpty()) { + _errorString = QObject::tr("The contents of this file does not look like a MapMap project."); return false; - } else if (! this->isValidVersion(projectVersion)) { - _xml.raiseError( - QObject::tr("The version of MapMap %1 used to save this file is not readable by this MapMap version %2.").arg( - projectVersion, MM::VERSION)); + } else if (!isValidVersion(projectVersion)) { + _errorString = QObject::tr("The version of MapMap %1 used to save this file is not readable by this MapMap version %2.") + .arg(projectVersion, MM::VERSION); return false; } parseProject(root); - return (! _xml.hasError() ); + return _errorString.isEmpty(); } QString ProjectReader::errorString() const { - return QObject::tr("%1\nLine %2, column %3") - .arg(_xml.errorString()) - .arg(_xml.lineNumber()) - .arg(_xml.columnNumber()); + return _errorString; } - -void ProjectReader::parseProject(const QDomElement& project) +void ProjectReader::parseProject(const QJsonObject& project) { - // TODO: this is dangerous if we have MappingManager& manager = _window->getMappingManager(); manager.clearAll(); - QDomElement paints = project.firstChildElement(ProjectLabels::PAINTS); - QDomElement mappings = project.firstChildElement(ProjectLabels::MAPPINGS); + QJsonArray sources = project[ProjectLabels::SOURCES].toArray(); + QJsonArray layers = project[ProjectLabels::LAYERS].toArray(); - // Parse paints. - QDomNode paintNode = paints.firstChild(); - while (!paintNode.isNull()) + // Parse sources (formerly paints). + for (const auto& val : sources) { - Paint::ptr paint = parsePaint(paintNode.toElement()); + Paint::ptr paint = parsePaint(val.toObject()); if (paint.isNull()) { - qDebug() << "Problem creating paint." << endl; + qDebug() << "Problem creating source." << Qt::endl; } else { @@ -116,25 +103,21 @@ void ProjectReader::parseProject(const QDomElement& project) image->setUri(_window->locateMediaFile(image->getUri(), true)); } } - paintNode = paintNode.nextSibling(); } - // Parse mappings. - QDomNode mappingNode = mappings.firstChild(); + // Parse layers (formerly mappings). QVector allMappings; - while (!mappingNode.isNull()) + for (const auto& val : layers) { - Mapping::ptr mapping = parseMapping(mappingNode.toElement()); + Mapping::ptr mapping = parseMapping(val.toObject()); if (mapping.isNull()) { - qDebug() << "Problem creating mapping." << endl; + qDebug() << "Problem creating layer." << Qt::endl; } else { allMappings.push_back(mapping); } - - mappingNode = mappingNode.nextSibling(); } // Add all mappings in reverse order. @@ -146,64 +129,57 @@ void ProjectReader::parseProject(const QDomElement& project) } } -Paint::ptr ProjectReader::parsePaint(const QDomElement& paintElem) +Paint::ptr ProjectReader::parsePaint(const QJsonObject& obj) { - QString className = Serializable::classNameCleanToReal(paintElem.attribute(ProjectLabels::CLASS_NAME)); - int id = paintElem.attribute(ProjectLabels::ID, QString::number(NULL_UID)).toInt(); + QString className = Serializable::classNameCleanToReal(obj[ProjectLabels::CLASS_NAME].toString()); + int id = obj[ProjectLabels::ID].toInt(NULL_UID); - qDebug() << "Found paint with classname: " << className << endl; + qDebug() << "Found source with classname: " << className << Qt::endl; const QMetaObject* metaObject = MetaObjectRegistry::instance().getMetaObject(className); if (metaObject) { - // Create new instance. - Paint::ptr paint (qobject_cast(metaObject->newInstance( Q_ARG(int, id)) )); + Paint::ptr paint(qobject_cast(metaObject->newInstance(Q_ARG(int, id)))); if (paint.isNull()) { - qDebug() << QObject::tr("Problem at creation of paint.") << endl; -// _xml.raiseError(QObject::tr("Problem at creation of paint.")); + qDebug() << QObject::tr("Problem at creation of source.") << Qt::endl; } else qDebug() << "Created new instance with id: " << paint->getId(); - paint->read(paintElem); + paint->read(obj); return paint; } - else { - _xml.raiseError(QObject::tr("Unable to create paint of type '%1'.").arg(className)); + _errorString = QObject::tr("Unable to create source of type '%1'.").arg(className); return Paint::ptr(); } } -Mapping::ptr ProjectReader::parseMapping(const QDomElement& mappingElem) +Mapping::ptr ProjectReader::parseMapping(const QJsonObject& obj) { - // Get attributes. - QString className = Serializable::classNameCleanToReal(mappingElem.attribute(ProjectLabels::CLASS_NAME)); - int id = mappingElem.attribute(ProjectLabels::ID, QString::number(NULL_UID)).toInt(); + QString className = Serializable::classNameCleanToReal(obj[ProjectLabels::CLASS_NAME].toString()); + int id = obj[ProjectLabels::ID].toInt(NULL_UID); const QMetaObject* metaObject = MetaObjectRegistry::instance().getMetaObject(className); if (metaObject) { - // Create new instance. - Mapping::ptr mapping (qobject_cast(metaObject->newInstance( Q_ARG(int, id)) )); + Mapping::ptr mapping(qobject_cast(metaObject->newInstance(Q_ARG(int, id)))); if (mapping.isNull()) { - qDebug() << QObject::tr("Problem at creation of mapping.") << endl; -// _xml.raiseError(QObject::tr("Problem at creation of paint.")); + qDebug() << QObject::tr("Problem at creation of layer.") << Qt::endl; } - mapping->read(mappingElem); + mapping->read(obj); return mapping; } - else { - _xml.raiseError(QObject::tr("Unable to create paint of type '%1'.").arg(className)); + _errorString = QObject::tr("Unable to create layer of type '%1'.").arg(className); return Mapping::ptr(); } } diff --git a/src/core/ProjectReader.h b/src/core/ProjectReader.h index a0f9389d2..7aa407573 100644 --- a/src/core/ProjectReader.h +++ b/src/core/ProjectReader.h @@ -18,8 +18,10 @@ * along with this program. If not, see . */ -#include -#include +#include +#include +#include +#include #include "MainWindow.h" #include "Mapping.h" #include "Paint.h" @@ -37,17 +39,16 @@ class ProjectReader QString errorString() const; private: - void readProject(); - void parseProject(const QDomElement& project); - Paint::ptr parsePaint(const QDomElement& paint); - Mapping::ptr parseMapping(const QDomElement& mapping); + void parseProject(const QJsonObject& project); + Paint::ptr parsePaint(const QJsonObject& obj); + Mapping::ptr parseMapping(const QJsonObject& obj); /** * Checks if the version attribute of the project tag matches the regex of supported versions of MapMap. * Some older versions of MapMap might not be supported by this version. */ bool isValidVersion(const QString& versionString); - QXmlStreamReader _xml; + QString _errorString; MainWindow *_window; }; diff --git a/src/core/ProjectWriter.cpp b/src/core/ProjectWriter.cpp index afad0456e..6eef7a1d1 100644 --- a/src/core/ProjectWriter.cpp +++ b/src/core/ProjectWriter.cpp @@ -18,49 +18,42 @@ * along with this program. If not, see . */ #include "ProjectWriter.h" -#include namespace mmp { ProjectWriter::ProjectWriter(MainWindow *window) : _window(window) { - _xml.setAutoFormatting(true); } bool ProjectWriter::writeFile(QIODevice *device) { MappingManager& manager = _window->getMappingManager(); - QDomDocument doc; - QDomElement project = doc.createElement("project"); - project.setAttribute("version", MM::VERSION); + QJsonObject project; + project["version"] = MM::VERSION; - // Paints. - QDomElement paints = doc.createElement("paints"); + // Sources (formerly paints). + QJsonArray sources; for (int i=0; iwrite(paint); - paints.appendChild(paint); + QJsonObject source; + manager.getPaint(i)->write(source); + sources.append(source); } + project[ProjectLabels::SOURCES] = sources; - // Mappings. - QDomElement mappings = doc.createElement("mappings"); + // Layers (formerly mappings). + QJsonArray layers; for (int i=0; iwrite(mapping); - mappings.appendChild(mapping); + QJsonObject layer; + manager.getMapping(i)->write(layer); + layers.append(layer); } + project[ProjectLabels::LAYERS] = layers; - project.appendChild(paints); - project.appendChild(mappings); - doc.appendChild(project); - - QTextStream out(device); - out << "" << endl; - out << "" << endl; - out << doc.toString(2); + QJsonDocument doc(project); + device->write(doc.toJson(QJsonDocument::Indented)); return true; } diff --git a/src/core/ProjectWriter.h b/src/core/ProjectWriter.h index 1224ddc8a..af88fa763 100644 --- a/src/core/ProjectWriter.h +++ b/src/core/ProjectWriter.h @@ -20,7 +20,9 @@ #ifndef PROJECT_WRITER_H_ #define PROJECT_WRITER_H_ -#include +#include +#include +#include #include "MappingManager.h" #include "Mapping.h" #include "Paint.h" @@ -39,7 +41,6 @@ class ProjectWriter bool writeFile (QIODevice *device); private: - QXmlStreamWriter _xml; MainWindow *_window; }; diff --git a/src/core/Serializable.cpp b/src/core/Serializable.cpp index 20103131d..c790b445c 100644 --- a/src/core/Serializable.cpp +++ b/src/core/Serializable.cpp @@ -39,112 +39,54 @@ QString Serializable::classNameCleanToReal(const QString& cleanClassName) return MM::NAMESPACE_PREFIX + cleanClassName; } -void Serializable::read(const QDomElement& obj) +void Serializable::read(const QJsonObject& obj) { - QList attributeNames = _propertiesAttributes(); - QList specialNames = _propertiesSpecial(); + QList specialNames = _propertiesSpecial(); - // Fill up properties. int count = metaObject()->propertyCount(); for (int i=0; iproperty(i); + const char* propertyName = property.name(); - // Name of property. - const char* propertyName = property.name(); - - // Don't try to write special properties (leave it to children). if (specialNames.contains(propertyName)) continue; - // If property is writable, try to find it and rewrite it. if (property.isWritable()) { - - // Always ignore objectName default property. if (QString(propertyName) == QString("objectName")) continue; - // Check in attributes. - else if (attributeNames.contains(propertyName)) - { - if (obj.hasAttribute(propertyName)) - setProperty(propertyName, obj.attribute(propertyName)); - } - - // Check in children. - else - { - // Find element. - QDomElement propertyElem = obj.firstChildElement(propertyName); - if (!propertyElem.isNull()) - { - // Set property. - setProperty(propertyName, propertyElem.text()); - } - } + if (obj.contains(propertyName)) + setProperty(propertyName, obj[propertyName].toString()); } } } -void Serializable::write(QDomElement& obj) +void Serializable::write(QJsonObject& obj) { - QList attributeNames = _propertiesAttributes(); - QList specialNames = _propertiesSpecial(); + QList specialNames = _propertiesSpecial(); - // Write up classname. - obj.setAttribute(ProjectLabels::CLASS_NAME, cleanClassName()); + obj[ProjectLabels::CLASS_NAME] = cleanClassName(); - // Fill up properties. int count = metaObject()->propertyCount(); for (int i=0; iproperty(i); + const char* propertyName = property.name(); - // Name of property. - const char* propertyName = property.name(); - - // Don't try to write special properties (leave it to children). if (specialNames.contains(propertyName)) continue; - // Don't save unstored properties. - if (!property.isStored(this)) + if (!property.isStored()) continue; - // If property is writable, try to find it and rewrite it. if (property.isWritable() && property.isReadable()) { - qDebug() << "Read " << propertyName << " : " << property.read(this) << endl; - QString propertyValue = property.read(this).toString(); - - // Always ignore objectName default property. if (QString(propertyName) == QString("objectName")) continue; - // Add to attributes. - if (attributeNames.contains(propertyName)) - { - obj.setAttribute(propertyName, propertyValue); - } - - // Add to children. - else - { - _writeNode(obj, propertyName, propertyValue); - } + obj[propertyName] = property.read(this).toString(); } } } -void Serializable::_writeNode(QDomElement& obj, const QString& nodeName, const QString& nodeValue) -{ - QDomElement propertyNode = obj.ownerDocument().createElement(nodeName); - QDomText text = obj.ownerDocument().createTextNode(nodeValue); - propertyNode.appendChild(text); - obj.appendChild(propertyNode); -} - - - } diff --git a/src/core/Serializable.h b/src/core/Serializable.h index 981be9f5e..f7139bf3c 100644 --- a/src/core/Serializable.h +++ b/src/core/Serializable.h @@ -21,7 +21,8 @@ #define SERIALIZABLE_H_ #include -#include +#include +#include #include #include @@ -48,17 +49,12 @@ class Serializable : public QObject { static QString classNameRealToClean(const QString& realClassName); static QString classNameCleanToReal(const QString& cleanClassName); - virtual void read(const QDomElement& obj); - virtual void write(QDomElement& obj); + virtual void read(const QJsonObject& obj); + virtual void write(QJsonObject& obj); protected: - // Lists QProperties that should be represented as XML attributes, not as childen nodes. - virtual QList _propertiesAttributes() const { return QList(); } - // Lists QProperties that should NOT be parsed automatically. virtual QList _propertiesSpecial() const { return QList(); } - - void _writeNode(QDomElement& obj, const QString& nodeName, const QString& nodeValue); }; } diff --git a/src/core/Util.cpp b/src/core/Util.cpp index 29f880b14..b038fb753 100644 --- a/src/core/Util.cpp +++ b/src/core/Util.cpp @@ -19,12 +19,12 @@ */ #include "Util.h" -#include #include #include #include +#include #include -#include +#include namespace mmp { @@ -237,8 +237,8 @@ bool eraseSettings() bool isNumeric(const QString& text) { - QRegExp re("\\d*"); // a digit (\d), zero or more times (*) - return (re.exactMatch(text)); + QRegularExpression re("^\\d*$"); // a digit (\d), zero or more times (*) + return re.match(text).hasMatch(); } } // end of namespace diff --git a/src/core/VideoImpl.cpp b/src/core/VideoImpl.cpp index 2845827dc..8cca8322a 100644 --- a/src/core/VideoImpl.cpp +++ b/src/core/VideoImpl.cpp @@ -4,9 +4,6 @@ * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net * (c) 2012 Jean-Sebastien Senecal - * (c) 2004 Mathieu Guindon, Julien Keable - * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials * * 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,790 +19,150 @@ * along with this program. If not, see . */ #include "VideoImpl.h" -#include -#include +#include +#include +#include namespace mmp { -// -------- private implementation of VideoImpl ------- - bool VideoImpl::hasVideoSupport() { - static bool did_print_gst_version = false; - if (! did_print_gst_version) - { - qDebug() << "Using GStreamer version " << - GST_VERSION_MAJOR << "." << GST_VERSION_MINOR << "." << GST_VERSION_MICRO << endl; - did_print_gst_version = true; + static bool printed = false; + if (!printed) { + qDebug() << "Using Qt Multimedia" << QT_VERSION_STR; + printed = true; } - // TODO: actually check if we have it return true; } -int VideoImpl::getWidth() const -{ - return _width; -// Q_ASSERT(videoIsConnected()); -// return _padHandlerData.width; -} - -int VideoImpl::getHeight() const -{ - return _height; -// Q_ASSERT(videoIsConnected()); -// return _padHandlerData.height; -} +int VideoImpl::getWidth() const { return _width; } +int VideoImpl::getHeight() const { return _height; } +QString VideoImpl::getUri() const { return _uri; } const uchar* VideoImpl::getBits() { - // Reset bits changed. _bitsChanged = false; - - // Return data. - return (hasBits() ? _data : NULL); -} - -QString VideoImpl::getUri() const -{ - return _uri; + return _data; } void VideoImpl::setRate(double rate) { - if (rate == 0.0) - { - qDebug() << "Cannot set rate to zero, ignoring rate " << rate << endl; + if (rate == 0.0) { + qDebug() << "Cannot set rate to zero, ignoring."; return; } - - // Only update rate if needed. - if (_rate != rate) - { - _rate = rate; - - // Send seek events to activate rate. - if (_seekEnabled) - _updateRate(); - } + _rate = rate; } void VideoImpl::setVolume(double volume) { - // Only update volume if needed. - if (_volume != volume) - { - _volume = volume; - - // Set volume element property - if (audioIsSupported()) - { - g_object_set (_audiovolume0, "mute", (_volume <= 0), NULL); - g_object_set (_audiovolume0, "volume", _volume, NULL); - } - else - qWarning() << "Cannot change volume cause this video does not support audio." << endl; - } + _volume = volume; } void VideoImpl::build() { qDebug() << "Building video impl"; if (!loadMovie(_uri)) - { - qDebug() << "Cannot load movie " << _uri << "."; - } + qDebug() << "Cannot load movie" << _uri; +} + +VideoImpl::VideoImpl() + : _data(nullptr), + _bitsChanged(false), + _width(-1), + _height(-1), + _duration(0), + _videoIsConnected(false), + _audioIsConnected(false), + _seekEnabled(false), + _rate(1.0), + _volume(1.0), + _terminate(false), + _movieReady(false), + _playState(false), + _uri("") +{ + QSettings settings; + _playInLoop = settings.value("playInLoop", MM::PLAY_IN_LOOP).toBool(); } VideoImpl::~VideoImpl() { - // Free all resources. freeResources(); - - // Free mutex locker object. - delete _mutexLocker; -} - -bool VideoImpl::_eos() const -{ - if (_movieReady) - { - Q_ASSERT( _appsink0 ); - if (_rate > 0.0) - { - gboolean videoEos; - g_object_get (G_OBJECT (_appsink0), "eos", &videoEos, NULL); - return (bool) (videoEos); - } - else - { - /* Obtain the current position, needed for the seek event */ - gint64 position; - if (!gst_element_query_position (_pipeline, GST_FORMAT_TIME, &position)) { - g_printerr ("Unable to retrieve current position.\n"); - return false; - } - return (position == 0); - } - } - else - return false; -} - -GstFlowReturn VideoImpl::gstNewSampleCallback(GstElement*, VideoImpl *p) -{ - // Make it thread-safe. - p->lockMutex(); - - // Get next frame. - GstSample *sample = gst_app_sink_pull_sample(GST_APP_SINK(p->_appsink0)); - - // Unref last frame. - p->_freeCurrentSample(); - - // Set current frame. - p->_currentFrameSample = sample; - - // For live sources, video dimensions have not been set, because - // gstPadAddedCallback is never called. Fix dimensions from first sample / - // caps we receive. - if (( p->_width == -1 || - p->_height == -1)) { - GstCaps *caps = gst_sample_get_caps(sample); - GstStructure *structure; - structure = gst_caps_get_structure(caps, 0); - gst_structure_get_int(structure, "width", &p->_width); - gst_structure_get_int(structure, "height", &p->_height); - } - - // Try to retrieve data bits of frame. - GstMapInfo& map = p->_mapInfo; - GstBuffer *buffer = gst_sample_get_buffer( sample ); - if (gst_buffer_map(buffer, &map, GST_MAP_READ)) - { - p->_currentFrameBuffer = buffer; - // For debugging: - //gst_util_dump_mem(map.data, map.size) - - // Retrieve data from map info. - p->_data = map.data; - - // Bits have changed. - p->_bitsChanged = true; - } - - p->unlockMutex(); - - return GST_FLOW_OK; -} - -VideoImpl::VideoImpl() : -_width(-1), -_height(-1), -_duration(0), -_seekEnabled(false), -_pipeline(NULL), -_queue0(NULL), -_capsfilter0(NULL), -_videoscale0(NULL), -_videoconvert0(NULL), -_appsink0(NULL), -_audioqueue0(NULL), -_audioconvert0(NULL), -_audioresample0(NULL), -_audiovolume0(NULL), -_audiosink0(NULL), -_bus(NULL), -_currentFrameSample(NULL), -_currentFrameBuffer(NULL), -_bitsChanged(false), -_data(NULL), -//_isSeekable(false), -_rate(1.0), -_movieReady(false), -_playState(false), -_uri("") -{ - _mutexLocker = new QMutexLocker(&_mutex); - - QSettings settings; - _playInLoop = settings.value("playInLoop", MM::PLAY_IN_LOOP).toBool(); } void VideoImpl::unloadMovie() { - // Reset variables. _terminate = false; _seekEnabled = false; - - // Un-ready. _setMovieReady(false); setPlayState(false); - - // Free allocated resources / reinit. freeResources(); } void VideoImpl::freeResources() { - // Free resources. - if (_bus) - { - gst_object_unref (GST_OBJECT(_bus)); - _bus = NULL; - } - - if (_pipeline) - { - gst_element_set_state (_pipeline, GST_STATE_NULL); - gst_object_unref (GST_OBJECT(_pipeline)); - _pipeline = NULL; - } - - // Free all components. - _freeElement(&_queue0); - _freeElement(&_capsfilter0); - _freeElement(&_videoscale0); - _freeElement(&_videoconvert0); - _freeElement(&_appsink0); - - _freeElement(&_audioqueue0); - _freeElement(&_audioconvert0); - _freeElement(&_audioresample0); - _freeElement(&_audiovolume0); - _freeElement(&_audiosink0); - - qDebug() << "Freeing remaining samples/buffers" << endl; - - // Frees current sample and buffer. - _freeCurrentSample(); - - // Reset other informations. + _data = nullptr; + _currentFrame = QImage(); _bitsChanged = false; - _width = _height = (-1); + _width = _height = -1; _duration = 0; _videoIsConnected = false; _audioIsConnected = false; } -void VideoImpl::resetMovie() -{ - if (_seekEnabled) - { - if (_rate > 0.0) - { - seekTo((guint64) 0); - qWarning() << "update Rate" << endl; - _updateRate(); - } - else - { - // NOTE: Untested. - seekTo(_duration); - qWarning() << "update Rate" << endl; - _updateRate(); - } - } - else - { - qDebug() << "Seeking not enabled: reloading the movie" << endl; - loadMovie(_uri); - } -} - -bool VideoImpl::createVideoComponents() -{ - // Already supported? - if (videoIsSupported()) - return true; - - // Create the video elements. - _queue0 = gst_element_factory_make ("queue", "queue0"); - _videoconvert0 = gst_element_factory_make ("videoconvert", "videoconvert0"); - _videoscale0 = gst_element_factory_make ("videoscale", "videoscale0"); - _capsfilter0 = gst_element_factory_make ("capsfilter", "capsfilter0"); - _appsink0 = gst_element_factory_make ("appsink", "appsink0"); - - // Verify that they were created. - if (!_queue0 || !_videoconvert0 || ! _videoscale0 || ! _capsfilter0 || !_appsink0) - { - qWarning() << "Not all video elements could be created." << endl; - if (! _pipeline) g_printerr("_pipeline"); - if (! _queue0) g_printerr("_queue0"); - if (! _videoconvert0) g_printerr("_videoconvert0"); - if (! _videoscale0) g_printerr("videoscale0"); - if (! _capsfilter0) g_printerr("capsfilter0"); - if (! _appsink0) g_printerr("_appsink0"); - return false; - } - - // Add them to pipeline. - gst_bin_add_many (GST_BIN (_pipeline), - _queue0, _videoconvert0, _videoscale0, _capsfilter0, _appsink0, - NULL); - - // Link. - if (! gst_element_link_many (_queue0, _videoconvert0, _capsfilter0, _videoscale0, _appsink0, NULL)) - { - qWarning() << "Could not link video queue, colorspace converter, caps filter, scaler and app sink." << endl; - return false; - } - - // Configure video appsink. - GstCaps *videoCaps = gst_caps_from_string ("video/x-raw,format=RGBA"); - g_object_set (_capsfilter0, "caps", videoCaps, NULL); - - g_object_set (_appsink0, "emit-signals", TRUE, - "max-buffers", 1, // only one buffer (the last) is maintained in the queue - "drop", TRUE, // ... other buffers are dropped - "sync", TRUE, - NULL); - - g_signal_connect (_appsink0, "new-sample", G_CALLBACK (VideoImpl::gstNewSampleCallback), this); - gst_caps_unref (videoCaps); - - return true; -} - -bool VideoImpl::createAudioComponents() +bool VideoImpl::loadMovie(const QString& filename) { - // Already supported? - if (audioIsSupported()) - return true; - - // Create the audio elements. - _audioqueue0 = gst_element_factory_make ("queue", "audioqueue0"); - _audioconvert0 = gst_element_factory_make ("audioconvert", "audioconvert0"); - _audioresample0 = gst_element_factory_make ("audioresample", "audioresample0"); - _audiovolume0 = gst_element_factory_make ("volume", "audiovolume0"); - _audiosink0 = gst_element_factory_make ("autoaudiosink", "audiosink0"); - - // Verify that they were created. - if (!_audioqueue0 || !_audioconvert0 || !_audioresample0 || !_audiovolume0 || !_audiosink0) - { - qDebug() << "Not all audio elements could be created." << endl; - if (! _audioqueue0) g_printerr("_audioqueue0"); - if (! _audioconvert0) g_printerr("_audioconvert0"); - if (! _audioresample0) g_printerr("_audioresample0"); - if (! _audiovolume0) g_printerr("_audiovolume0"); - if (! _audiosink0) g_printerr("_audiosink0"); - return false; - } - - // Add them to pipeline. - gst_bin_add_many (GST_BIN (_pipeline), - _audioqueue0, _audioconvert0, _audioresample0, _audiovolume0, _audiosink0, - NULL); - - // Link. - if (! gst_element_link_many (_audioqueue0, _audioconvert0, _audioresample0, - _audiovolume0, _audiosink0, NULL)) - { - qDebug() << "Could not link audio queue, converter, resampler and audio sink." << endl; - return false; - } - - // Configure audio appsink. - // TODO: change from mono to stereo - // gchar* audioCapsText = g_strdup_printf ("audio/x-raw-float,channels=1,rate=%d,signed=(boolean)true,width=%d,depth=%d,endianness=BYTE_ORDER", - // Engine::signalInfo().sampleRate(), (int)(sizeof(Signal_T)*8), (int)(sizeof(Signal_T)*8) ); - //GstCaps* audioCaps = gst_caps_from_string (audioCapsText); - /* - GstCaps* audioCaps = gst_caps_from_string ("audio/xraw-float"); - g_object_set (_audioSink, "emit-signals", TRUE, - "caps", audioCaps, - "max-buffers", 1, // only one buffer (the last) is maintained in the queue - "drop", TRUE, // ... other buffers are dropped - "sync", TRUE, - NULL); - g_signal_connect (_audioSink, "new-buffer", G_CALLBACK (VideoImpl::gstNewAudioBufferCallback), this); - gst_caps_unref (audioCaps); - */ - // g_free (audioCapsText); - + _uri = filename; return true; } -void VideoImpl::update() -{ - // Check for end-of-stream or terminate. - if (_eos() || _terminate) - { - _setFinished(true); - if (_playInLoop) // Check if repeat mode is on - resetMovie(); - } - else - { - _setFinished(false); - } - -// // Check if movie is ready and connected. -// if (!isReady()) -// { -// _bitsChanged = false; -// } -// - // Check gstreamer messages on bus. - _checkMessages(); -} - - bool VideoImpl::loadMovie(const QString& filename) { - // Verify if file exists. - const gchar* filetestpath = (const gchar*) filename.toUtf8().constData(); - if (FALSE == g_file_test(filetestpath, G_FILE_TEST_EXISTS)) - { - qDebug() << "File " << filename << " does not exist" << endl; - return false; - } - - qDebug() << "Opening movie: " << filename << "."; - - // Assign URI. - _uri = filename; - - // Free previously allocated structures - unloadMovie(); - - // Prepare handler data. - _videoIsConnected = false; - _audioIsConnected = false; - - // Create the empty pipeline. - _pipeline = gst_pipeline_new ( "video-source-pipeline" ); - if (!_pipeline) - { - qWarning() << "Pipeline could not be created." << endl; - unloadMovie(); - return (-1); - } - - // Create and link video components. - if (!createVideoComponents()) - { - qWarning() << "Video components could not be initialized." << endl; - unloadMovie(); - return (-1); - } - - //setVolume(0); - - // Listen to the bus. - _bus = gst_element_get_bus (_pipeline); - - // Start playing. - - return true; - } - bool VideoImpl::setPlayState(bool play) { - if (_pipeline == NULL) - { - return false; - } - - // Change state. - GstStateChangeReturn ret = gst_element_set_state (_pipeline, (play ? GST_STATE_PLAYING : GST_STATE_PAUSED)); - -// // Wait until its done. -// GstStateChangeReturn ret = gst_element_get_state (_pipeline, NULL, NULL, -1); - if (ret == GST_STATE_CHANGE_FAILURE) - { - qDebug() << "Unable to set the pipeline to the playing state." << endl; - //unloadMovie(); // <-- calling this created an infinite recursion - return false; - } - else - { - _playState = play; - return true; - } + _playState = play; + return true; } bool VideoImpl::seekTo(double position) { - gint64 duration; - if (!gst_element_query_duration (_pipeline, GST_FORMAT_TIME, &duration)) - { - qDebug() << "Cannot get duration of file" << endl; + if (_duration <= 0) return false; - } - - // Make sure position is in [0,1]. position = qBound(0.0, position, 1.0); - - // Seek at position in nanoseconds. - return seekTo((guint64)(position*duration)); + return seekTo(qint64(position * _duration)); } -bool VideoImpl::seekTo(guint64 positionNanoSeconds) +void VideoImpl::resetMovie() { - if (!_appsink0 || !_seekEnabled) - { - return false; - } + if (_seekEnabled) + seekTo(qint64(0)); else - { - lockMutex(); - - // Free the current sample and reset. - _freeCurrentSample(); - _bitsChanged = false; - - // Seek to position. - bool result = gst_element_seek_simple( - _appsink0, GST_FORMAT_TIME, - GstSeekFlags( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ), - positionNanoSeconds); - - unlockMutex(); - - return result; - } -} - -//bool VideoImpl::_preRun() -//{ -// // Check for end-of-stream or terminate. -// if (_eos() || _terminate) -// { -// _setFinished(true); -// resetMovie(); -// } -// else -// { -// _setFinished(false); -// } -// if (!_movieReady || -// !_padHandlerData.videoIsConnected) -// { -// return false; -// } -// return true; -//} - -void VideoImpl::_checkMessages() -{ - if (_bus != NULL) - { - // Get message. - GstMessage *msg = gst_bus_timed_pop_filtered( - _bus, 0, - (GstMessageType) (GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_ASYNC_DONE)); - - if (msg != NULL) - { - GError *err; - gchar *debug_info; - - switch (GST_MESSAGE_TYPE (msg)) - { - // Error //////////////////////////////////////////////// - case GST_MESSAGE_ERROR: - gst_message_parse_error(msg, &err, &debug_info); - qWarning() << "Error received from element " << GST_OBJECT_NAME (msg->src) << ": " << err->message << endl; - qDebug() << "Debugging information: " << (debug_info ? debug_info : "none") << "." << endl; - g_clear_error(&err); - g_free(debug_info); - - if (!isLive()) - { - _terminate = true; - } - else - { - gst_element_set_state (_pipeline, GST_STATE_PAUSED); - gst_element_set_state (_pipeline, GST_STATE_NULL); - gst_element_set_state (_pipeline, GST_STATE_READY); - } - // _finish(); - break; - - // End-of-stream //////////////////////////////////////// - case GST_MESSAGE_EOS: - // Automatically loop back. - if (_playInLoop) // Check if repeat mode is on - resetMovie(); - // _terminate = true; - // _finish(); - break; - - // Pipeline has prerolled/ready to play /////////////// - case GST_MESSAGE_ASYNC_DONE: - if (!_isMovieReady()) - { - // Check if seeking is allowed. - gint64 start, end; - GstQuery *query = gst_query_new_seeking (GST_FORMAT_TIME); - if (gst_element_query (_pipeline, query)) - { - gst_query_parse_seeking (query, NULL, (gboolean*)&_seekEnabled, &start, &end); - if (_seekEnabled) - { -#ifdef VIDEO_IMPL_VERBOSE - qDebug() << "Seeking is ENABLED from " << start << " to " << end << "." << endl; -#endif - } - else - { - qDebug() << "Seeking is DISABLED for this stream." << endl; - } - } - else - { - qWarning() << "Seeking query failed." << endl; - } - - gst_query_unref (query); - - // Movie is ready! -#ifdef VIDEO_IMPL_VERBOSE - qDebug() << "Preroll done: movie is ready." << endl; -#endif // ifdef - _setMovieReady(true); - } - - break; - - case GST_MESSAGE_STATE_CHANGED: - // We are only interested in state-changed messages from the pipeline. - if (GST_MESSAGE_SRC (msg) == GST_OBJECT (_pipeline)) - { - GstState oldState, newState, pendingState; - gst_message_parse_state_changed(msg, &oldState, &newState, &pendingState); -#ifdef VIDEO_IMPL_VERBOSE - qDebug() << "Pipeline state for movie " << _uri - << " changed from " << gst_element_state_get_name(oldState) - << " to " << gst_element_state_get_name(newState) << endl; -#endif - } - break; - - default: - // We should not reach here. - qWarning() << "Unexpected message received." << endl; - break; - } - gst_message_unref(msg); - } - } -} - -void VideoImpl::_setMovieReady(bool ready) -{ - _movieReady = ready; -} - -void VideoImpl::_setFinished(bool finished) -{ - Q_UNUSED(finished); - // qDebug() << "Clip " << (finished ? "finished" : "not finished"); -} - -void VideoImpl::_updateRate() -{ - // Check different things. - if (_pipeline == NULL) - { - qWarning() << "Cannot set rate: no pipeline!" << endl; - return; - } - - if (!_seekEnabled) - { - qWarning() << "Cannot set rate: seek not working" << endl; - return; - } - - if (!_isMovieReady()) - { - qWarning() << "Movie is not yet ready to play, cannot seek yet." << endl; - } - - // Obtain the current position, needed for the seek event. - gint64 position; - if (!gst_element_query_position (_pipeline, GST_FORMAT_TIME, &position)) { - qWarning() << "Unable to retrieve current position." << endl; - return; - } - - // Create the seek event. - GstEvent *seekEvent; - if (_rate > 0.0) { - // Rate is positive (playing the video in normal direction) - // Set new rate as a first argument. Provide position 0 so that we go to 0:00 - seekEvent = gst_event_new_seek (_rate, GST_FORMAT_TIME, GstSeekFlags( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ), - GST_SEEK_TYPE_SET, position, GST_SEEK_TYPE_NONE, 0); // Go to 0:00 - } else { - // Rate is negative - // Set new rate as a first arguemnt. Provide the position we were already at. - seekEvent = gst_event_new_seek (_rate, GST_FORMAT_TIME, GstSeekFlags( GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE ), - GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, position); - } - - // If we have not done so, obtain the sink through which we will send the seek events. - if (_appsink0 == NULL) { - g_object_get (_pipeline, "video-sink", &_appsink0, NULL); - } - - // Send the event. - if (!gst_element_send_event (_appsink0, seekEvent)) { - qWarning() << "Cannot perform seek event" << endl; - } - - qDebug() << "Current rate: " << _rate << "." << endl; -} - -void VideoImpl::_freeCurrentSample() { - if (_currentFrameBuffer != NULL) - { - gst_buffer_unmap(_currentFrameBuffer, &_mapInfo); - } - - if (_currentFrameSample != NULL) - { - gst_sample_unref(_currentFrameSample); - } - - _currentFrameSample = NULL; - _currentFrameBuffer = NULL; - _data = NULL; + loadMovie(_uri); } -void VideoImpl::_freeElement(GstElement** element) +void VideoImpl::update() { - if (*element) - { - *element = NULL; + // Subclasses set _terminate via their own EOS detection. + if (_terminate) { + if (_playInLoop) + resetMovie(); + _terminate = false; } } -void VideoImpl::lockMutex() -{ - _mutexLocker->relock(); -} - -void VideoImpl::unlockMutex() -{ - _mutexLocker->unlock(); -} +void VideoImpl::lockMutex() { _mutex.lock(); } +void VideoImpl::unlockMutex() { _mutex.unlock(); } bool VideoImpl::waitForNextBits(int timeout, const uchar** bits) { - QTime time; - time.start(); - while (time.elapsed() < timeout) - { - // Bits available. - if (hasBits() && bitsHaveChanged()) - { + QElapsedTimer timer; + timer.start(); + while (timer.elapsed() < timeout) { + if (hasBits() && bitsHaveChanged()) { if (bits) *bits = getBits(); return true; } } - - // Timed out. return false; } diff --git a/src/core/VideoImpl.h b/src/core/VideoImpl.h index 75124dba4..7a226ec6f 100644 --- a/src/core/VideoImpl.h +++ b/src/core/VideoImpl.h @@ -6,7 +6,6 @@ * (c) 2012 Jean-Sebastien Senecal * (c) 2004 Mathieu Guindon, Julien Keable * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials * * 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,111 +24,61 @@ #ifndef VIDEO_IMPL_H_ #define VIDEO_IMPL_H_ -// GStreamer includes. -#include -#include -#include - -// Other includes. #include "MM.h" -#include +#include #include #include -#include -#if __APPLE__ -#include -#else -#include -#endif - namespace mmp { /** - * Private declaration of the video player. - * This is to prevent the GStreamer header to be included in the whole project. - * (it just needs to be included in this file). + * Abstract base class for video playback implementations. + * Subclasses supply frames via Qt 6 Multimedia (QMediaPlayer, QCamera). + * The _data pointer always points into _currentFrame.bits() so that + * callers can pass it directly to glTexImage2D. */ class VideoImpl { public: - /** - * Constructor. - * This media player works for both video files and shared memory sockets. - * If live is true, it's a shared memory socket. - */ VideoImpl(); virtual ~VideoImpl(); - - -// void setUri(const QString uri); - /** - * Returns whether or not GStreamer video support is ok. - */ + /// Returns whether Qt Multimedia video support is available. static bool hasVideoSupport(); - /** - * Sets up the player. - * Basically calls loadMovie(). - */ + /// Sets up the player (calls loadMovie with the stored URI). void build(); - /** - * Returns the width of the video image. - */ virtual int getWidth() const; - - /** - * Returns the height of the video image. - */ virtual int getHeight() const; - /** - * Returns the path to the media file being played. - */ QString getUri() const; - /** - * Returns the raw image of the last video frame. - * It is currently unused! - */ + /// Returns raw RGBA bytes of the latest video frame (or NULL if none yet). virtual const uchar* getBits(); - /// Returns true iff bits have started flowing (ie. if there is at least a first sample available). - virtual bool hasBits() const { return (_currentFrameSample != NULL); } + /// Returns true once at least one frame has been received. + virtual bool hasBits() const { return (_data != nullptr); } - /// Returns true iff bits have changed since last call to getBits(). + /// Returns true if a new frame arrived since the last getBits() call. virtual bool bitsHaveChanged() const { return _bitsChanged; } - /** - * Checks if the pipeline is ready. - * - * Returns whether or not the elements in the pipeline are connected, - * and if we are using shmsrc, if the shared memory socket is being read. - */ - bool isReady() const { return _isMovieReady() && videoIsConnected(); } + /// Returns true when the pipeline is ready to deliver frames. + bool isReady() const { return _movieReady && _videoIsConnected; } bool videoIsConnected() const { return _videoIsConnected; } void videoConnect() { _videoIsConnected = true; } - bool videoIsSupported() const { return _queue0 != NULL; } bool audioIsConnected() const { return _audioIsConnected; } void audioConnect() { _audioIsConnected = true; } - bool audioIsSupported() const { return _audioqueue0 != NULL; } - /** - * Performs regular updates (checks if movie is ready and checks messages). - */ - void update(); + /// Performs regular updates (handles loop restart on end-of-stream). + virtual void update(); + + /// True for live sources (camera, etc.) that cannot be sought. virtual bool isLive() = 0; - /** - * Loads a new video stream - * - * Creates a new GStreamer pipeline, opens a movie, webcam or shmsrc socket, - * depending on subclass. - */ + /// Loads a new media source. Subclasses override to set up their player. virtual bool loadMovie(const QString& filename); bool setPlayState(bool play); @@ -137,147 +86,64 @@ class VideoImpl bool seekIsEnabled() const { return _seekEnabled; } + /// Seek to a fractional position in [0, 1]. bool seekTo(double position); - bool seekTo(guint64 positionNanoSeconds); + /// Seek to an absolute position in milliseconds. + virtual bool seekTo(qint64 positionMs) = 0; - void setRate(double rate=1.0); + virtual void setRate(double rate = 1.0); double getRate() const { return _rate; } - void setVolume(double rate=0.0); + virtual void setVolume(double volume = 0.0); double getVolume() const { return _volume; } void resetMovie(); -protected: - virtual bool createVideoComponents(); - virtual bool createAudioComponents(); - - void unloadMovie(); - void freeResources(); - -private: - /** - * Checks if we reached the end of the video file. - * - * Returns false if the pipeline is not ready yet. - */ - bool _eos() const; - - // void _finish(); - // void _init(); - -// bool _preRun(); - void _checkMessages(); - void _setMovieReady(bool ready); - bool _isMovieReady() const { return _movieReady; } - void _setFinished(bool finished); - - // Sends the appropriate seek events to adjust to rate. - void _updateRate(); - - void _freeCurrentSample(); - - void _freeElement(GstElement** element); - -public: - // GStreamer callback that simply sets the #newSample# flag to point to TRUE. - static GstFlowReturn gstNewSampleCallback(GstElement*, VideoImpl *p); - //static GstFlowReturn gstNewPreRollCallback (GstAppSink * appsink, gpointer user_data); - - // GStreamer callback that plugs the audio/video pads into the proper elements when they - // are made available by the source. - //static void gstPadAddedCallback(GstElement *src, GstPad *newPad, VideoImpl* p); - - /// Locks mutex (default = no effect). + /// Locks mutex. void lockMutex(); - - /// Unlocks mutex (default = no effect). + /// Unlocks mutex. void unlockMutex(); - /// Wait until first data samples are available (blocking). - bool waitForNextBits(int timeout, const uchar** bits = 0); + /// Blocks until new bits are available (up to timeout ms). Returns false on timeout. + bool waitForNextBits(int timeout, const uchar** bits = nullptr); protected: + void unloadMovie(); + virtual void freeResources(); + + void _setMovieReady(bool ready) { _movieReady = ready; } + + // Latest decoded frame — always Format_RGBA8888. + QImage _currentFrame; + /// Raw pointer into _currentFrame.bits(); kept for ABI with getBits(). + uchar *_data; + bool _bitsChanged; + int _width; int _height; - guint64 _duration; // duration (in nanoseconds) (unused for now) + /// Duration in milliseconds (0 if unknown). + qint64 _duration; bool _videoIsConnected; bool _audioIsConnected; bool _seekEnabled; - GstElement *_pipeline; - - GstElement *_queue0; - GstElement *_capsfilter0; - GstElement *_videoscale0; - GstElement *_videoconvert0; - GstElement *_appsink0; - - GstElement *_audioqueue0; - GstElement *_audioconvert0; - GstElement *_audioresample0; - GstElement *_audiovolume0; - GstElement *_audiosink0; - - // gstreamer elements - GstBus *_bus; - - /** - * Temporary contains the image data of the last frame. - */ - GstSample *_currentFrameSample; - GstBuffer *_currentFrameBuffer; - GstMapInfo _mapInfo; - bool _bitsChanged; - - /** - * Contains meta informations about current file. - */ - - /// Raw image data of the last video frame. - uchar *_data; - - /// Is seek enabled on the current pipeline? - - - /// Playback rate (negative ==> reverse). double _rate; - /// Audio playback volume (0.0 ==> 1.0). double _volume; - /// Whether or not we are reading video from a shmsrc. - bool _isSharedMemorySource; - - - - // unused bool _terminate; - - /// Is the movie (or rather pipeline) ready to play. bool _movieReady; - - /// Is the movie playing (as opposed to paused). bool _playState; - /// Main mutex. QMutex _mutex; - /// Main mutex locker (for the lockMutex() / unlockMutex() methods). - QMutexLocker* _mutexLocker; + bool _playInLoop; private: - /** - * Path of the movie file being played. - */ QString _uri; - - static const int MAX_SAMPLES_IN_BUFFER_QUEUES = 30; - - bool _playInLoop; }; } -#endif /* ifndef */ +#endif /* VIDEO_IMPL_H_ */ diff --git a/src/core/VideoPlayerImpl.cpp b/src/core/VideoPlayerImpl.cpp new file mode 100644 index 000000000..f3df955af --- /dev/null +++ b/src/core/VideoPlayerImpl.cpp @@ -0,0 +1,163 @@ +/* + * VideoPlayerImpl.cpp + * + * (c) 2024 MapMap contributors + * + * 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. + */ + +#include "VideoPlayerImpl.h" +#include +#include + +namespace mmp { + +VideoPlayerImpl::VideoPlayerImpl() + : _player(nullptr), + _audioOutput(nullptr), + _videoSink(nullptr), + _eos(false) +{ +} + +VideoPlayerImpl::~VideoPlayerImpl() +{ + if (_player) { + _player->stop(); + delete _player; + } + delete _audioOutput; + delete _videoSink; +} + +bool VideoPlayerImpl::loadMovie(const QString& path) +{ + // Store URI in base class. + VideoImpl::loadMovie(path); + + // Tear down any previous player. + if (_player) { + _player->stop(); + delete _player; + delete _audioOutput; + delete _videoSink; + } + + _eos = false; + freeResources(); + + _player = new QMediaPlayer(this); + _audioOutput = new QAudioOutput(this); + _videoSink = new QVideoSink(this); + + _player->setAudioOutput(_audioOutput); + _player->setVideoSink(_videoSink); + + connect(_videoSink, &QVideoSink::videoFrameChanged, + this, &VideoPlayerImpl::onVideoFrameChanged); + connect(_player, &QMediaPlayer::mediaStatusChanged, + this, &VideoPlayerImpl::onMediaStatusChanged); + + _player->setSource(QUrl::fromLocalFile(path)); + + if (_playInLoop) + _player->setLoops(QMediaPlayer::Infinite); + + // Seek is always enabled for file sources in Qt 6. + _seekEnabled = true; + _videoIsConnected = true; + _audioIsConnected = true; + + _player->setPlaybackRate(_rate); + _audioOutput->setVolume(_volume); + _player->play(); + _playState = true; + + return true; +} + +void VideoPlayerImpl::onVideoFrameChanged(const QVideoFrame& frame) +{ + if (!frame.isValid()) + return; + + lockMutex(); + + QImage img = frame.toImage().convertToFormat(QImage::Format_RGBA8888); + if (!img.isNull()) { + _currentFrame = img; + _width = _currentFrame.width(); + _height = _currentFrame.height(); + _data = _currentFrame.bits(); + _bitsChanged = true; + _videoIsConnected = true; + } + + unlockMutex(); +} + +void VideoPlayerImpl::onMediaStatusChanged(QMediaPlayer::MediaStatus status) +{ + switch (status) { + case QMediaPlayer::LoadedMedia: + _duration = _player->duration(); + _setMovieReady(true); + break; + case QMediaPlayer::EndOfMedia: + _eos = true; + break; + case QMediaPlayer::InvalidMedia: + qWarning() << "Invalid media:" << _player->errorString(); + break; + default: + break; + } +} + +bool VideoPlayerImpl::setPlayState(bool play) +{ + if (!_player) + return false; + if (play) + _player->play(); + else + _player->pause(); + _playState = play; + return true; +} + +bool VideoPlayerImpl::seekTo(qint64 positionMs) +{ + if (!_player || !_seekEnabled) + return false; + _player->setPosition(positionMs); + return true; +} + +void VideoPlayerImpl::setRate(double rate) +{ + _rate = rate; + if (_player) + _player->setPlaybackRate(rate); +} + +void VideoPlayerImpl::setVolume(double volume) +{ + _volume = volume; + if (_audioOutput) + _audioOutput->setVolume(volume); +} + +void VideoPlayerImpl::update() +{ + if (_eos) { + _eos = false; + if (_playInLoop) + resetMovie(); + } +} + +} diff --git a/src/core/VideoPlayerImpl.h b/src/core/VideoPlayerImpl.h new file mode 100644 index 000000000..70398af00 --- /dev/null +++ b/src/core/VideoPlayerImpl.h @@ -0,0 +1,63 @@ +/* + * VideoPlayerImpl.h + * + * (c) 2024 MapMap contributors + * + * Qt 6 Multimedia video playback using QMediaPlayer + QVideoSink + QAudioOutput. + * + * 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. + */ + +#ifndef VIDEO_PLAYER_IMPL_H_ +#define VIDEO_PLAYER_IMPL_H_ + +#include "VideoImpl.h" + +#include +#include +#include +#include +#include + +namespace mmp { + +/** + * File/URI video playback using Qt 6 QMediaPlayer. + * Delivers RGBA frames via QVideoSink into VideoImpl::_data so that + * callers (ShapeGraphicsItem etc.) can upload them to OpenGL unchanged. + */ +class VideoPlayerImpl : public QObject, public VideoImpl +{ + Q_OBJECT + +public: + VideoPlayerImpl(); + ~VideoPlayerImpl() override; + + bool loadMovie(const QString& path) override; + bool isLive() override { return false; } + + bool setPlayState(bool play); + bool seekTo(qint64 positionMs) override; + void setRate(double rate) override; + void setVolume(double volume) override; + + void update() override; + +private slots: + void onVideoFrameChanged(const QVideoFrame& frame); + void onMediaStatusChanged(QMediaPlayer::MediaStatus status); + +private: + QMediaPlayer *_player; + QAudioOutput *_audioOutput; + QVideoSink *_videoSink; + bool _eos; +}; + +} + +#endif // VIDEO_PLAYER_IMPL_H_ diff --git a/src/core/VideoShmSrcImpl.cpp b/src/core/VideoShmSrcImpl.cpp deleted file mode 100644 index 01a778c45..000000000 --- a/src/core/VideoShmSrcImpl.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * VideoShmSrcImpl.cpp - * - * (c) 2016 Vasilis Liaskovitis -- vliaskov@gmail.com - * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com - * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net - * (c) 2012 Jean-Sebastien Senecal - * (c) 2004 Mathieu Guindon, Julien Keable - * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "VideoShmSrcImpl.h" -#include -#include - -namespace mmp { - -VideoShmSrcImpl::VideoShmSrcImpl() : -_shmsrc0(NULL), -_gdpdepay0(NULL), -_pollSource(NULL), -_attached(false) -{ -} - -bool VideoShmSrcImpl::getAttached() -{ - return _attached; -} - -void VideoShmSrcImpl::setAttached(bool attach) -{ - _attached = attach; -} - -gboolean -gstPollShmsrc (void *user_data) -{ - VideoShmSrcImpl *p = (VideoShmSrcImpl*) user_data; - if (g_file_test(p->getUri().toUtf8().constData(), G_FILE_TEST_EXISTS) && - ! p->getAttached()) - { - if (! p->setPlayState(true)) - { - qDebug() << "tried to attach, but starting pipeline failed!" << endl; - return false; - } - p->setAttached(true); - } - return true; -} - -bool VideoShmSrcImpl::loadMovie(const QString& path) { - - VideoImpl::loadMovie(path); - - _shmsrc0 = gst_element_factory_make ("shmsrc", "shmsrc0"); - _gdpdepay0 = gst_element_factory_make ("gdpdepay", "gdpdepay0"); - _pollSource = g_timeout_source_new (500); - - g_source_set_callback (_pollSource, - gstPollShmsrc, - this, - NULL); - g_source_attach (_pollSource, g_main_context_default()); - g_source_unref (_pollSource); - - if (! _shmsrc0 || ! _gdpdepay0) - { - qWarning() << "Not all elements could be created." << endl; - if (! _shmsrc0) g_printerr("_shmsrc0"); - if (! _gdpdepay0) g_printerr("_gdpdepay0"); - unloadMovie(); - return -1; - } - - gst_bin_add_many (GST_BIN(_pipeline), _shmsrc0, _gdpdepay0, NULL); - if (! gst_element_link_many (_shmsrc0, _gdpdepay0, _queue0, NULL)) - { - qWarning() << "Could not link shmsrc, deserializer and video queue." << endl; - } - - QByteArray ba = path.toLocal8Bit(); - gchar* uri = (gchar*) path.toUtf8().constData(); - uri = (gchar*) ba.data(); - - //qDebug() << "LIVE mode" << uri; - g_object_set (_shmsrc0, "socket-path", uri, NULL); - g_object_set (_shmsrc0, "is-live", TRUE, NULL); - _videoIsConnected = true; - - return TRUE; -} - -VideoShmSrcImpl::~VideoShmSrcImpl() -{ - // Unref the shmsrc poller. - if (_pollSource) - { - g_source_unref(_pollSource); - _pollSource = NULL; - } -} - -} diff --git a/src/core/VideoShmSrcImpl.h b/src/core/VideoShmSrcImpl.h deleted file mode 100644 index 191612236..000000000 --- a/src/core/VideoShmSrcImpl.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * VideoShmSrcImpl.h - * - * (c) 2016 Vasilis Liaskovitis -- vliaskov@gmail.com - * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com - * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net - * (c) 2012 Jean-Sebastien Senecal - * (c) 2004 Mathieu Guindon, Julien Keable - * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials - * - * 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 . - */ - -#ifndef VIDEO_SHMSRC_IMPL_H_ -#define VIDEO_SHMSRC_IMPL_H_ - -// GStreamer includes. -#include -#include -#include - -// Other includes. -#include "MM.h" -#include -#include -#include - -#include -#if __APPLE__ -#include -#else -#include -#endif - -#include "VideoImpl.h" - -namespace mmp { - -class VideoShmSrcImpl : public VideoImpl -{ - public: - VideoShmSrcImpl(); - ~VideoShmSrcImpl(); - bool loadMovie(const QString& path); - bool isLive() {return true;} - bool getAttached(); - void setAttached(bool attach); - - private: - GstElement *_shmsrc0; - GstElement *_gdpdepay0; - /** - * shmsrc socket poller. - */ - GSource *_pollSource; - /// Whether or not we are attached to a shmsrc. - bool _attached; -}; - -} -#endif /* ifndef */ diff --git a/src/core/VideoUriDecodeBinImpl.cpp b/src/core/VideoUriDecodeBinImpl.cpp deleted file mode 100644 index 4a8dd594d..000000000 --- a/src/core/VideoUriDecodeBinImpl.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * VideoUriDecodeBinImpl.cpp - * - * (c) 2016 Vasilis Liaskovitis -- vliaskov@gmail.com - * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com - * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net - * (c) 2012 Jean-Sebastien Senecal - * (c) 2004 Mathieu Guindon, Julien Keable - * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "VideoUriDecodeBinImpl.h" -#include -#include - -namespace mmp { - -VideoUriDecodeBinImpl::VideoUriDecodeBinImpl() : -_uridecodebin0(NULL) -{ -} - -void VideoUriDecodeBinImpl::gstPadAddedCallback(GstElement *src, GstPad *newPad, VideoUriDecodeBinImpl* p) -{ - Q_UNUSED(src); -#ifdef VIDEO_IMPL_VERBOSE -#ifndef Q_OS_OSX - // NOTE: This line was causing a problem on Mac OSX: it caused the software to freeze when loading a new movie. - qDebug() << "Received new pad '" << GST_PAD_NAME(newPad) << "' from '" << GST_ELEMENT_NAME (src) << "'." << endl; -#endif -#endif - - GstPad *sinkPad = NULL; - - // Check the new pad's type. - GstCaps *newPadCaps = gst_pad_query_caps (newPad, NULL); - GstStructure *newPadStruct = gst_caps_get_structure (newPadCaps, 0); - const gchar *newPadType = gst_structure_get_name (newPadStruct); - gchar *newPadStructStr = gst_structure_to_string(newPadStruct); -#ifdef VIDEO_IMPL_VERBOSE - qDebug() << "Structure is " << newPadStructStr << "." << endl; -#endif - g_free(newPadStructStr); - - bool isVideoPad = g_str_has_prefix (newPadType, "video/x-raw"); - bool isAudioPad = g_str_has_prefix (newPadType, "audio/x-raw"); - - // Check for video pads. - if (isVideoPad) - { - sinkPad = gst_element_get_static_pad (p->_queue0, "sink"); - gst_structure_get_int(newPadStruct, "width", &p->_width); - gst_structure_get_int(newPadStruct, "height", &p->_height); - } - - // Check for audio pads. - else if (isAudioPad) - { - if (!p->createAudioComponents()) - { - qWarning() << "Problem creating audio components." << endl; - goto exit; - } - sinkPad = gst_element_get_static_pad (p->_audioqueue0, "sink"); - } - - // Other types: ignore. - else { - qDebug() << " It has type '" << newPadType << "' which is not raw audio/video: ignored." << endl; - goto exit; - } - - - // If our converter is already linked, we have nothing to do here. - if (gst_pad_is_linked (sinkPad)) - { - // Best prefixes. - if (isVideoPad || isAudioPad) - { - qDebug() << " Found a better pad." << endl; - GstPad* oldPad = gst_pad_get_peer(sinkPad); - gst_pad_unlink(oldPad, sinkPad); - g_object_unref(oldPad); - } - else - { -#ifdef VIDEO_IMPL_VERBOSE - qDebug() << " We are already linked: ignoring." << endl; -#endif - goto exit; - } - } - - // Attempt the link. - if (GST_PAD_LINK_FAILED (gst_pad_link (newPad, sinkPad))) - { -#ifdef VIDEO_IMPL_VERBOSE - qDebug() << " Type is '" << newPadType << "' but link failed." << endl; -#endif // ifdef - goto exit; - } - else - { - if (isVideoPad) - p->videoConnect(); - else if (isAudioPad) - p->audioConnect(); - else - qWarning() << "Error: this pad is neither valid audio or video." << endl; -#ifdef VIDEO_IMPL_VERBOSE - qDebug() << " Link succeeded (type '" << newPadType << "')." << endl; -#endif // ifdef - } - -exit: - // Unreference the new pad's caps, if we got them. - if (newPadCaps != NULL) - { - gst_caps_unref (newPadCaps); - } - - // Unreference the sink pad. - if (sinkPad != NULL) - { - gst_object_unref (sinkPad); - } -} - -bool VideoUriDecodeBinImpl::loadMovie(const QString& path) { - VideoImpl::loadMovie(path); - - _uridecodebin0 = gst_element_factory_make("uridecodebin", NULL); - - if ( !_uridecodebin0) - { - qWarning() << "Not all elements could be created." << endl; - unloadMovie(); - return (-1); - } - - // Build the pipeline. Note that we are NOT linking the source at this - // point. We will do it later. - gst_bin_add_many (GST_BIN (_pipeline), - _uridecodebin0, - NULL); - - // Process URI. - QByteArray ba = path.toLocal8Bit(); - gchar *filename_tmp = g_strdup((gchar*) path.toUtf8().constData()); - gchar* uri = (gchar*) path.toUtf8().constData(); - if (! gst_uri_is_valid(uri)) - { - // Try to convert filename to URI. - GError* error = NULL; - qDebug() << "Calling gst_filename_to_uri : " << uri << endl; - uri = gst_filename_to_uri(filename_tmp, &error); - if (error) - { - qDebug() << "Filename to URI error: " << error->message << endl; - g_clear_error(&error); - gst_object_unref (uri); - freeResources(); - return false; - } - } - g_free(filename_tmp); - -// Connect to the pad-added signal - // Extract meta info. - GError* error = NULL; - GstDiscoverer* discoverer = gst_discoverer_new(5*GST_SECOND, &error); - if (!discoverer) - { - qDebug() << "Error creating discoverer: " << error->message << endl; - g_clear_error (&error); - return false; - } - - GstDiscovererInfo* info = gst_discoverer_discover_uri(discoverer, uri, &error); - - if (!info) - { - qDebug() << "Error getting discoverer info: " << error->message << endl; - g_clear_error (&error); - return false; - } - - GstDiscovererResult result = gst_discoverer_info_get_result(info); - - switch (result) { - case GST_DISCOVERER_URI_INVALID: - qDebug()<< "Invalid URI '" << uri << "'" << endl; - break; - case GST_DISCOVERER_ERROR: - qDebug()<< "Discoverer error: " << error->message << endl; - break; - case GST_DISCOVERER_TIMEOUT: - qDebug() << "Timeout" << endl; - break; - case GST_DISCOVERER_BUSY: - qDebug() << "Busy" << endl; - break; - case GST_DISCOVERER_MISSING_PLUGINS:{ - const GstStructure *s; - gchar *str; - - s = gst_discoverer_info_get_misc (info); - str = gst_structure_to_string (s); - - qDebug() << "Missing plugins: " << str << endl; - g_free (str); - break; - } - case GST_DISCOVERER_OK: - qDebug() << "Discovered '" << uri << "'" << endl; - break; - } - - g_clear_error (&error); - - if (result != GST_DISCOVERER_OK) { - qDebug() << "This URI cannot be played" << endl; - return false; - } - - // Gather info from video. - GList *videoStreams = gst_discoverer_info_get_video_streams (info); - if (!videoStreams) - { - qDebug() << "This URI does not contain any video streams" << endl; - return false; - } - - // Retrieve meta-info. - _width = gst_discoverer_video_info_get_width((GstDiscovererVideoInfo*)videoStreams->data); - _height = gst_discoverer_video_info_get_height((GstDiscovererVideoInfo*)videoStreams->data); - _duration = gst_discoverer_info_get_duration(info); - _seekEnabled = gst_discoverer_info_get_seekable(info); - - // Free everything. - g_object_unref(discoverer); - gst_discoverer_info_unref(info); - gst_discoverer_stream_info_list_free(videoStreams); - - // Connect pad signal. - g_signal_connect (_uridecodebin0, "pad-added", G_CALLBACK (VideoUriDecodeBinImpl::gstPadAddedCallback), this); - - // Set uri of decoder. - g_object_set (_uridecodebin0, "uri", uri, NULL); - - setPlayState(true); - - return true; -} - -VideoUriDecodeBinImpl::~VideoUriDecodeBinImpl() -{ -} - -} diff --git a/src/core/VideoUriDecodeBinImpl.h b/src/core/VideoUriDecodeBinImpl.h deleted file mode 100644 index 397c00f88..000000000 --- a/src/core/VideoUriDecodeBinImpl.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * VideoUriDecodeBinImpl.h - * - * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com - * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net - * (c) 2012 Jean-Sebastien Senecal - * (c) 2004 Mathieu Guindon, Julien Keable - * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials - * - * 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 . - */ - -#ifndef VIDEO_URIDECODEBIN_IMPL_H_ -#define VIDEO_URIDECODEBIN_IMPL_H_ - -// GStreamer includes. -#include -#include -#include - -// Other includes. -#include "MM.h" -#include -#include -#include - -#include -#if __APPLE__ -#include -#else -#include -#endif - -#include "VideoImpl.h" - -namespace mmp { - -class VideoUriDecodeBinImpl : public VideoImpl -{ - public: - VideoUriDecodeBinImpl(); - ~VideoUriDecodeBinImpl(); - static void gstPadAddedCallback(GstElement *src, GstPad *newPad, VideoUriDecodeBinImpl* p); - bool loadMovie(const QString& path); - bool isLive() {return false;} - - private: - GstElement *_uridecodebin0; - //bool _videoIsConnected; -}; - -} - -#endif /* ifndef */ diff --git a/src/core/VideoV4l2SrcImpl.cpp b/src/core/VideoV4l2SrcImpl.cpp deleted file mode 100644 index f68a20a3f..000000000 --- a/src/core/VideoV4l2SrcImpl.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * VideoV4l2SrcImpl.cpp - * - * (c) 2016 Vasilis Liaskovitis -- vliaskov@gmail.com - * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com - * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net - * (c) 2012 Jean-Sebastien Senecal - * (c) 2004 Mathieu Guindon, Julien Keable - * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "VideoV4l2SrcImpl.h" -#include -#include - -namespace mmp { - -VideoV4l2SrcImpl::VideoV4l2SrcImpl() : -_v4l2src0(NULL) -{ -} - - -bool VideoV4l2SrcImpl::loadMovie(const QString& path) { - VideoImpl::loadMovie(path); - - _v4l2src0 = gst_element_factory_make("v4l2src", NULL); - - if ( !_v4l2src0) - { - qWarning() << "Not all elements could be created." << endl; - unloadMovie(); - return (-1); - } - - // Build the pipeline. Note that we are NOT linking the source at this - // point. We will do it later. - gst_bin_add_many (GST_BIN (_pipeline), - _v4l2src0, - NULL); - - if (! gst_element_link_many (_v4l2src0, _queue0, NULL)) - { - qDebug() << "Could not link v4l2src" << endl; - unloadMovie(); - return false; - } - - // Configure video appsink. - GstCaps *videoCaps = gst_caps_from_string ("video/x-raw,format=RGBA,width=640,height=480"); - g_object_set (_capsfilter0, "caps", videoCaps, NULL); - gst_caps_unref (videoCaps); - - // Retrieve meta-info. - _width = 640; - _height = 480; - //_duration = ; - _seekEnabled = false; - - setPlayState(true); - return TRUE; -} - -VideoV4l2SrcImpl::~VideoV4l2SrcImpl() -{ -} -} diff --git a/src/core/VideoV4l2SrcImpl.h b/src/core/VideoV4l2SrcImpl.h deleted file mode 100644 index fd4d1f9b4..000000000 --- a/src/core/VideoV4l2SrcImpl.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * VideoV4l2SrcImpl.h - * - * (c) 2016 Vasilis Liaskovitis -- vliaskov@gmail.com - * (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com - * (c) 2013 Alexandre Quessy -- alexandre(@)quessy(.)net - * (c) 2012 Jean-Sebastien Senecal - * (c) 2004 Mathieu Guindon, Julien Keable - * Based on code from Drone http://github.com/sofian/drone - * Based on code from the GStreamer Tutorials http://docs.gstreamer.com/display/GstSDK/Tutorials - * - * 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 . - */ - -#ifndef VIDEO_V4L2SRC_IMPL_H_ -#define VIDEO_V4L2SRC_IMPL_H_ - -// GStreamer includes. -#include -#include -#include - -// Other includes. -#include "MM.h" -#include -#include -#include - -#include -#if __APPLE__ -#include -#else -#include -#endif - -#include "VideoImpl.h" - -namespace mmp { - -class VideoV4l2SrcImpl : public VideoImpl -{ - public: - VideoV4l2SrcImpl(); - ~VideoV4l2SrcImpl(); - bool loadMovie(const QString& path); - bool isLive() {return true;} - - private: - GstElement *_v4l2src0; -}; - -} - -#endif /* ifndef */ diff --git a/src/core/core.pri b/src/core/core.pri index 2a1a24f75..eecfdddc5 100644 --- a/src/core/core.pri +++ b/src/core/core.pri @@ -17,9 +17,7 @@ HEADERS += $$PWD/Commands.h \ $$PWD/Serializable.h \ $$PWD/UidAllocator.h \ $$PWD/VideoImpl.h \ - $$PWD/VideoShmSrcImpl.h \ - $$PWD/VideoUriDecodeBinImpl.h \ - $$PWD/VideoV4l2SrcImpl.h \ + $$PWD/VideoPlayerImpl.h \ $$PWD/Util.h SOURCES += $$PWD/Commands.cpp \ @@ -37,7 +35,5 @@ SOURCES += $$PWD/Commands.cpp \ $$PWD/Serializable.cpp \ $$PWD/UidAllocator.cpp \ $$PWD/VideoImpl.cpp \ - $$PWD/VideoShmSrcImpl.cpp \ - $$PWD/VideoUriDecodeBinImpl.cpp \ - $$PWD/VideoV4l2SrcImpl.cpp \ + $$PWD/VideoPlayerImpl.cpp \ $$PWD/Util.cpp diff --git a/src/gui/AboutDialog.cpp b/src/gui/AboutDialog.cpp index 82595ba03..c1dd03a0e 100644 --- a/src/gui/AboutDialog.cpp +++ b/src/gui/AboutDialog.cpp @@ -85,11 +85,11 @@ void AboutDialog::createAboutTab() // License short notice QFile licenseShortFile(":/license-short"); licenseShortFile.open(QIODevice::ReadOnly | QIODevice::Text); - QString licenseNoticeText = Qt::convertFromPlainText(QTextCodec::codecForName("UTF-8")->toUnicode(licenseShortFile.readAll()), Qt::WhiteSpaceNormal); + QString licenseNoticeText = Qt::convertFromPlainText(QString::fromUtf8(licenseShortFile.readAll()), Qt::WhiteSpaceNormal); // About projection mapping QFile aboutMappingFile(":/projection-mapping"); aboutMappingFile.open(QIODevice::ReadOnly | QIODevice::Text); - QString aboutMappingText = QTextCodec::codecForName("UTF-8")->toUnicode(aboutMappingFile.readAll()); + QString aboutMappingText = QString::fromUtf8(aboutMappingFile.readAll()); // Visit our website for more information QString projectWebsiteText = "

" + tr("See the ") + QString("").arg(MM::ORGANIZATION_DOMAIN) + tr("%1 website").arg(MM::APPLICATION_NAME) + " for more information on this software.

"; @@ -113,15 +113,9 @@ void AboutDialog::createChangelogTab() QTextBrowser *changelogTextBrowser = new QTextBrowser; changelogTextBrowser->setOpenExternalLinks(true); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QFile changelogFile(":/changelog_md"); changelogFile.open(QIODevice::ReadOnly | QIODevice::Text); - changelogTextBrowser->setMarkdown(QTextCodec::codecForName("UTF-8")->toUnicode(changelogFile.readAll())); -#else - QFile changelogFile(":/changelog"); - changelogFile.open(QIODevice::ReadOnly | QIODevice::Text); - changelogTextBrowser->setText(QTextCodec::codecForName("UTF-8")->toUnicode(changelogFile.readAll())); -#endif + changelogTextBrowser->setMarkdown(QString::fromUtf8(changelogFile.readAll())); _tabWidget->addTab(changelogTextBrowser, tr("Changelog")); } @@ -131,14 +125,9 @@ void AboutDialog::createLibrariesTab() librariesTextBrowser->setOpenExternalLinks(true); QString qtVersionText = QString("

Qt %1

").arg(QT_VERSION_STR); - QString gstreamerVersionText = QString("

%1

").arg(gst_version_string()); - // TODO: ifdef HAVE_OSC - //QString libloVersionText = QString("

%1

").arg(lo_version('str', 0, 0, 0, 0, 0, 0, 0, 0)); QString librairiesText; librairiesText.append(qtVersionText); - librairiesText.append(gstreamerVersionText); - //librairiesText.append(libloVersionText); // Set librairies main text librariesTextBrowser->setText(librairiesText); @@ -150,15 +139,9 @@ void AboutDialog::createContributorsTab() QTextBrowser *contributorsTextBrowser = new QTextBrowser; contributorsTextBrowser->setOpenExternalLinks(true); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QFile contributorsFile(":/contributors_md"); contributorsFile.open(QIODevice::ReadOnly | QIODevice::Text); - contributorsTextBrowser->setMarkdown(QTextCodec::codecForName("UTF-8")->toUnicode(contributorsFile.readAll())); -#else - QFile contributorsFile(":/contributors"); - contributorsFile.open(QIODevice::ReadOnly | QIODevice::Text); - contributorsTextBrowser->setText(QTextCodec::codecForName("UTF-8")->toUnicode(contributorsFile.readAll())); -#endif + contributorsTextBrowser->setMarkdown(QString::fromUtf8(contributorsFile.readAll())); _tabWidget->addTab(contributorsTextBrowser, tr("Contributors")); } @@ -169,7 +152,7 @@ void AboutDialog::createLicenseTab() QFile licenseFile(":/license"); licenseFile.open(QIODevice::ReadOnly | QIODevice::Text); - licenseTextBrowser->setText(QTextCodec::codecForName("UTF-8")->toUnicode(licenseFile.readAll())); + licenseTextBrowser->setText(QString::fromUtf8(licenseFile.readAll())); _tabWidget->addTab(licenseTextBrowser, tr("License")); } @@ -180,15 +163,9 @@ void AboutDialog::createOscTab() QTextBrowser *oscBrowser = new QTextBrowser; oscBrowser->setOpenExternalLinks(true); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QFile oscFile(":/osc-documentation_md"); oscFile.open(QIODevice::ReadOnly | QIODevice::Text); - oscBrowser->setMarkdown(QTextCodec::codecForName("UTF-8")->toUnicode(oscFile.readAll())); -#else - QFile oscFile(":/osc-documentation"); - oscFile.open(QIODevice::ReadOnly | QIODevice::Text); - oscBrowser->setText(QTextCodec::codecForName("UTF-8")->toUnicode(oscFile.readAll())); -#endif + oscBrowser->setMarkdown(QString::fromUtf8(oscFile.readAll())); _tabWidget->addTab(oscBrowser, tr("OSC Commands")); } diff --git a/src/gui/AboutDialog.h b/src/gui/AboutDialog.h index 7c0937389..aaabe76f1 100644 --- a/src/gui/AboutDialog.h +++ b/src/gui/AboutDialog.h @@ -22,11 +22,6 @@ #include -#include -#ifdef HAVE_OSC -#include "lo/lo.h" -#endif - #include "GuiForward.h" #include "MM.h" diff --git a/src/gui/ConsoleWindow.cpp b/src/gui/ConsoleWindow.cpp index 5b7311651..ab8151338 100644 --- a/src/gui/ConsoleWindow.cpp +++ b/src/gui/ConsoleWindow.cpp @@ -88,7 +88,7 @@ void ConsoleWindow::writeLogFile(const QString &message) QFile logFile(logFilePath); logFile.open(QIODevice::Append); QTextStream stream(&logFile); - stream << message << endl; + stream << message << Qt::endl; } void ConsoleWindow::printMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg) @@ -111,11 +111,9 @@ void ConsoleWindow::printMessage(QtMsgType type, const QMessageLogContext &conte case QtDebugMsg: output = time + " | " + debug + " " + QString(message.constData()) + " - " + contexts + ""; break; -#if QT_VERSION >= 0x050500 case QtInfoMsg: output = time + " | " + info + " " + QString(message.constData()) + " - " + contexts + ""; break; -#endif case QtWarningMsg: output = time + " | " + warning + " " + QString(message.constData()) + " - " + contexts + ""; break; @@ -130,7 +128,7 @@ void ConsoleWindow::printMessage(QtMsgType type, const QMessageLogContext &conte _console->appendHtml(output); // Write also on log file - writeLogFile(output.remove(QRegExp("<[^>]*>"))); + writeLogFile(output.remove(QRegularExpression("<[^>]*>"))); } void ConsoleWindow::closeEvent(QCloseEvent *event) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index c2793f615..de35a04cb 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -28,6 +28,9 @@ #include "ProjectReader.h" #include #include +#include +#include +#include namespace mmp { @@ -111,9 +114,7 @@ MainWindow::~MainWindow() { delete mappingManager; // delete _facade; -#ifdef HAVE_OSC delete osc_timer; -#endif // ifdef delete systemTimer; } @@ -434,7 +435,7 @@ void MainWindow::dragEnterEvent(QDragEnterEvent *event) bool allowDrag = true; if (mimeData->hasUrls()) { - foreach (QUrl url, mimeData->urls()) { + for (const QUrl& url : mimeData->urls()) { QString fileName = url.toLocalFile(); // Don't allow drag if file is not supported if (!fileSupported(fileName, MM::FILE_EXTENSION) && @@ -465,7 +466,7 @@ void MainWindow::dropEvent(QDropEvent *event) if (mimeData->hasUrls()) { // In case that dragged many files - foreach (QUrl url, mimeData->urls()) { + for (const QUrl& url : mimeData->urls()) { QString fileName = url.toLocalFile(); if (!fileName.isEmpty()) { @@ -638,17 +639,17 @@ void MainWindow::openCameraDevice() pause(!pauseAction->isVisible()); QString device; - QList cameras = QCameraInfo::availableCameras(); + QList cameras = QMediaDevices::videoInputs(); if (cameras.count() > 1) { QStringList devicesList; QMap devices; - for (const QCameraInfo &cameraInfo: cameras) + for (const QCameraDevice &cameraInfo: cameras) { devicesList << cameraInfo.description(); - devices.insert(cameraInfo.description(), cameraInfo.deviceName()); + devices.insert(cameraInfo.description(), QString::fromUtf8(cameraInfo.id())); } bool ok; @@ -665,14 +666,14 @@ void MainWindow::openCameraDevice() else { - if (QCameraInfo::defaultCamera().isNull()) + if (QMediaDevices::defaultVideoInput().isNull()) { QMessageBox::warning(this, tr("No camera available"), tr("You can not use this feature!\nNo camera available in your system")); } else { - device = QCameraInfo::defaultCamera().deviceName(); + device = QString::fromUtf8(QMediaDevices::defaultVideoInput().id()); } } @@ -888,7 +889,7 @@ void MainWindow::deleteItem() } else { - qCritical() << "Selected item neither a mapping nor a paint." << endl; + qCritical() << "Selected item neither a mapping nor a paint." << Qt::endl; } } } @@ -901,7 +902,7 @@ void MainWindow::duplicateMappingItem() } else { - qCritical() << "No selected mapping" << endl; + qCritical() << "No selected mapping" << Qt::endl; } } @@ -913,7 +914,7 @@ void MainWindow::deleteMappingItem() } else { - qCritical() << "No selected mapping" << endl; + qCritical() << "No selected mapping" << Qt::endl; } } @@ -1035,7 +1036,7 @@ void MainWindow::deletePaintItem() } else { - qCritical() << "No selected source" << endl; + qCritical() << "No selected source" << Qt::endl; } } @@ -1223,7 +1224,7 @@ uid MainWindow::createMeshTextureMapping(uid mappingId, { Paint::ptr paint = mappingManager->getPaintById(paintId); int nVertices = nColumns * nRows; - qDebug() << nVertices << " vs " << nColumns << "x" << nRows << " vs " << src.size() << " " << dst.size() << endl; + qDebug() << nVertices << " vs " << nColumns << "x" << nRows << " vs " << src.size() << " " << dst.size() << Qt::endl; Q_ASSERT(src.size() == nVertices && dst.size() == nVertices); MShape::ptr inputMesh( new Mesh(src, nColumns, nRows)); @@ -1396,7 +1397,7 @@ void MainWindow::setMappingVisible(uid mappingId, bool visible) if (mapping.isNull()) { - qDebug() << "No such mapping id" << endl; + qDebug() << "No such mapping id" << Qt::endl; } else { @@ -1560,7 +1561,7 @@ void MainWindow::createLayout() sourceLayout->addWidget(sourceCanvasToolbar, 0, Qt::AlignRight); sourcePanel->setLayout(sourceLayout); - destinationCanvas = new MapperGLCanvas(this, true, nullptr, static_cast(sourceCanvas->viewport())); + destinationCanvas = new MapperGLCanvas(this, true, nullptr, qobject_cast(sourceCanvas->viewport())); destinationCanvas->setFocusPolicy(Qt::ClickFocus); destinationCanvas->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); destinationCanvas->setMinimumSize(CANVAS_MINIMUM_WIDTH, CANVAS_MINIMUM_HEIGHT); @@ -1720,7 +1721,7 @@ void MainWindow::createActions() // Import Media. importMediaAction = new QAction(tr("&Import Media File..."), this); - importMediaAction->setShortcut(Qt::CTRL + Qt::Key_I); + importMediaAction->setShortcut(Qt::CTRL | Qt::Key_I); importMediaAction->setIcon(QIcon(":/add-video")); importMediaAction->setToolTip(tr("Import a video or image file...")); importMediaAction->setIconVisibleInMenu(false); @@ -1730,7 +1731,7 @@ void MainWindow::createActions() // Open camera. AddCameraAction = new QAction(tr("Open &Camera Device..."), this); - AddCameraAction->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C); + AddCameraAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_C); AddCameraAction->setIcon(QIcon(":/add-camera")); AddCameraAction->setIconVisibleInMenu(false); AddCameraAction->setToolTip(tr("Choose your camera device...")); @@ -1740,7 +1741,7 @@ void MainWindow::createActions() // Add color. addColorAction = new QAction(tr("Add &Color Source..."), this); - addColorAction->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_A); + addColorAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_A); addColorAction->setIcon(QIcon(":/add-color")); addColorAction->setToolTip(tr("Add a color paint...")); addColorAction->setIconVisibleInMenu(false); @@ -1781,7 +1782,7 @@ void MainWindow::createActions() // Duplicate. duplicateMappingAction = new QAction(tr("Duplicate Layer"), this); - duplicateMappingAction->setShortcut(Qt::CTRL + Qt::Key_D); + duplicateMappingAction->setShortcut(Qt::CTRL | Qt::Key_D); duplicateMappingAction->setToolTip(tr("Duplicate layer item")); duplicateMappingAction->setIconVisibleInMenu(false); duplicateMappingAction->setEnabled(false); @@ -1946,7 +1947,7 @@ void MainWindow::createActions() // Preferences... preferencesAction = new QAction(tr("&Preferences..."), this); //preferencesAction->setIcon(QIcon(":/preferences")); - preferencesAction->setShortcut(Qt::CTRL + Qt::Key_Comma); + preferencesAction->setShortcut(Qt::CTRL | Qt::Key_Comma); preferencesAction->setToolTip(tr("Configure preferences...")); //preferencesAction->setIconVisibleInMenu(false); preferencesAction->setShortcutContext(Qt::ApplicationShortcut); @@ -1955,7 +1956,7 @@ void MainWindow::createActions() // Add mesh. addMeshAction = new QAction(tr("Add &Mesh Layer"), this); - addMeshAction->setShortcut(Qt::CTRL + Qt::Key_M); + addMeshAction->setShortcut(Qt::CTRL | Qt::Key_M); addMeshAction->setIcon(QIcon(":/add-mesh")); addMeshAction->setToolTip(tr("Add mesh layer")); addMeshAction->setIconVisibleInMenu(false); @@ -1966,7 +1967,7 @@ void MainWindow::createActions() // Add triangle. addTriangleAction = new QAction(tr("Add &Triangle Layer"), this); - addTriangleAction->setShortcut(Qt::CTRL + Qt::Key_T); + addTriangleAction->setShortcut(Qt::CTRL | Qt::Key_T); addTriangleAction->setIcon(QIcon(":/add-triangle")); addTriangleAction->setToolTip(tr("Add triangle layer")); addTriangleAction->setIconVisibleInMenu(false); @@ -1977,7 +1978,7 @@ void MainWindow::createActions() // Add ellipse. addEllipseAction = new QAction(tr("Add &Ellipse Layer"), this); - addEllipseAction->setShortcut(Qt::CTRL + Qt::Key_E); + addEllipseAction->setShortcut(Qt::CTRL | Qt::Key_E); addEllipseAction->setIcon(QIcon(":/add-ellipse")); addEllipseAction->setToolTip(tr("Add ellipse layer")); addEllipseAction->setIconVisibleInMenu(false); @@ -1987,7 +1988,7 @@ void MainWindow::createActions() addEllipseAction->setEnabled(false); // Play. - const QKeySequence PLAY_PAUSE_KEY_SEQUENCE = Qt::CTRL + Qt::SHIFT + Qt::Key_P; + const QKeySequence PLAY_PAUSE_KEY_SEQUENCE = Qt::CTRL | Qt::SHIFT | Qt::Key_P; playAction = new QAction(tr("Play"), this); playAction->setShortcut(PLAY_PAUSE_KEY_SEQUENCE); playAction->setIcon(QIcon(":/play")); @@ -2011,7 +2012,7 @@ void MainWindow::createActions() // Rewind. rewindAction = new QAction(tr("Restart"), this); - rewindAction->setShortcut(Qt::CTRL + Qt::Key_R); + rewindAction->setShortcut(Qt::CTRL | Qt::Key_R); rewindAction->setIcon(QIcon(":/rewind")); rewindAction->setToolTip(tr("Restart")); rewindAction->setIconVisibleInMenu(false); @@ -2021,7 +2022,7 @@ void MainWindow::createActions() // Toggle display of output window. outputFullScreenAction = new QAction(tr("Toggle &Fullscreen"), this); - outputFullScreenAction->setShortcut(Qt::CTRL + Qt::Key_F); + outputFullScreenAction->setShortcut(Qt::CTRL | Qt::Key_F); outputFullScreenAction->setIcon(QIcon(":/fullscreen")); outputFullScreenAction->setToolTip(tr("Toggle Fullscreen")); outputFullScreenAction->setIconVisibleInMenu(false); @@ -2032,7 +2033,8 @@ void MainWindow::createActions() addAction(outputFullScreenAction); // Manage fullscreen/modal show of GL output window. connect(outputFullScreenAction, SIGNAL(toggled(bool)), outputWindow, SLOT(setFullScreen(bool))); - connect(QApplication::desktop(), SIGNAL(screenCountChanged(int)), this, SLOT(updateScreenCount())); + connect(qApp, &QGuiApplication::screenAdded, this, [this](QScreen*){ updateScreenCount(); }); + connect(qApp, &QGuiApplication::screenRemoved, this, [this](QScreen*){ updateScreenCount(); }); // Create hiden action for closing output window QAction *closeOutput = new QAction(this); closeOutput->setShortcut(Qt::Key_Escape); @@ -2042,7 +2044,7 @@ void MainWindow::createActions() // Toggle display of canvas controls. displayControlsAction = new QAction(tr("&Display Controls"), this); - displayControlsAction->setShortcut(Qt::ALT + Qt::Key_C); + displayControlsAction->setShortcut(Qt::ALT | Qt::Key_C); displayControlsAction->setIcon(QIcon(":/control-points")); displayControlsAction->setToolTip(tr("Display canvas controls")); displayControlsAction->setIconVisibleInMenu(false); @@ -2056,7 +2058,7 @@ void MainWindow::createActions() // Toggle display of canvas controls. displayPaintControlsAction = new QAction(tr("&Display Controls of Layers of a Source"), this); - //displayPaintControlsAction->setShortcut(Qt::ALT + Qt::Key_C); + //displayPaintControlsAction->setShortcut(Qt::ALT | Qt::Key_C); displayPaintControlsAction->setIcon(QIcon(":/control-points")); displayPaintControlsAction->setToolTip(tr("Display all canvas controls related to current source")); displayPaintControlsAction->setIconVisibleInMenu(false); @@ -2071,7 +2073,7 @@ void MainWindow::createActions() // Toggle sticky vertices stickyVerticesAction = new QAction(tr("&Sticky Vertices"), this); - stickyVerticesAction->setShortcut(Qt::ALT + Qt::Key_S); + stickyVerticesAction->setShortcut(Qt::ALT | Qt::Key_S); stickyVerticesAction->setIcon(QIcon(":/control-points")); stickyVerticesAction->setToolTip(tr("Enable sticky vertices")); stickyVerticesAction->setIconVisibleInMenu(false); @@ -2083,7 +2085,7 @@ void MainWindow::createActions() connect(stickyVerticesAction, SIGNAL(toggled(bool)), this, SLOT(enableStickyVertices(bool))); displayTestSignalAction = new QAction(tr("Show &Test Signal"), this); - displayTestSignalAction->setShortcut(Qt::ALT + Qt::Key_T); + displayTestSignalAction->setShortcut(Qt::ALT | Qt::Key_T); displayTestSignalAction->setIcon(QIcon(":/toggle-test-signal")); displayTestSignalAction->setToolTip(tr("Show Test signal")); displayTestSignalAction->setIconVisibleInMenu(false); @@ -2097,7 +2099,7 @@ void MainWindow::createActions() // Toggle display of Undo History displayUndoHistoryAction = new QAction(tr("Display &Undo History"), this); - displayUndoHistoryAction->setShortcut(Qt::ALT + Qt::Key_U); + displayUndoHistoryAction->setShortcut(Qt::ALT | Qt::Key_U); displayUndoHistoryAction->setCheckable(true); displayUndoHistoryAction->setChecked(_displayUndoStack); displayUndoHistoryAction->setShortcutContext(Qt::ApplicationShortcut); @@ -2107,7 +2109,7 @@ void MainWindow::createActions() // Toggle display of Console output openConsoleAction = new QAction(tr("Open Conso&le"), this); - openConsoleAction->setShortcut(Qt::ALT + Qt::Key_L); + openConsoleAction->setShortcut(Qt::ALT | Qt::Key_L); openConsoleAction->setCheckable(true); openConsoleAction->setChecked(false); openConsoleAction->setShortcutContext(Qt::ApplicationShortcut); @@ -2118,7 +2120,7 @@ void MainWindow::createActions() // Toggle display of zoom tool buttons displayZoomToolAction = new QAction(tr("Display &Zoom Toolbar"), this); - displayZoomToolAction->setShortcut(Qt::ALT + Qt::Key_Z); + displayZoomToolAction->setShortcut(Qt::ALT | Qt::Key_Z); displayZoomToolAction->setCheckable(true); displayZoomToolAction->setChecked(true); displayZoomToolAction->setShortcutContext(Qt::ApplicationShortcut); @@ -2137,21 +2139,21 @@ void MainWindow::createActions() mainViewAction = new QAction(tr("Main Layout"), this); mainViewAction->setCheckable(true); mainViewAction->setChecked(true); - mainViewAction->setShortcut(Qt::CTRL + Qt::Key_1); + mainViewAction->setShortcut(Qt::CTRL | Qt::Key_1); mainViewAction->setToolTip(tr("Switch to the Main layout.")); connect(mainViewAction, SIGNAL(triggered(bool)), canvasSplitter->widget(0), SLOT(setVisible(bool))); connect(mainViewAction, SIGNAL(triggered(bool)), canvasSplitter->widget(1), SLOT(setVisible(bool))); // Source Only sourceViewAction = new QAction(tr("Input editor Layout"), this); sourceViewAction->setCheckable(true); - sourceViewAction->setShortcut(Qt::CTRL + Qt::Key_2); + sourceViewAction->setShortcut(Qt::CTRL | Qt::Key_2); sourceViewAction->setToolTip(tr("Switch to the Input editor Layout.")); connect(sourceViewAction, SIGNAL(triggered(bool)), canvasSplitter->widget(0), SLOT(setVisible(bool))); connect(sourceViewAction, SIGNAL(triggered(bool)), canvasSplitter->widget(1), SLOT(setHidden(bool))); // Destination Only destViewAction = new QAction(tr("Output Editor Layout"), this); destViewAction->setCheckable(true); - destViewAction->setShortcut(Qt::CTRL + Qt::Key_3); + destViewAction->setShortcut(Qt::CTRL | Qt::Key_3); destViewAction->setToolTip(tr("Switch to the Output Editors Layout.")); connect(destViewAction, SIGNAL(triggered(bool)), canvasSplitter->widget(0), SLOT(setHidden(bool))); connect(destViewAction, SIGNAL(triggered(bool)), canvasSplitter->widget(1), SLOT(setVisible(bool))); @@ -2178,7 +2180,7 @@ void MainWindow::createActions() connect(zoomOutAction, SIGNAL(triggered()), destinationCanvas, SLOT(decreaseZoomLevel())); // Reset zoom resetZoomAction = new QAction(tr("Original Size"), this); - resetZoomAction->setShortcut(Qt::CTRL + Qt::Key_0); + resetZoomAction->setShortcut(Qt::CTRL | Qt::Key_0); resetZoomAction->setToolTip(tr("Reset zoom to original size")); resetZoomAction->setEnabled(false); connect(resetZoomAction, SIGNAL(triggered()), sourceCanvas, SLOT(resetZoomLevel())); @@ -2205,7 +2207,7 @@ void MainWindow::createActions() connect(feedbackAction, SIGNAL(triggered()), this, SLOT(sendFeedback())); // Keyboard shortcuts shortcutAction = new QAction(tr("&Keyboard shortcuts"), this); - shortcutAction->setShortcut(Qt::CTRL + Qt::Key_K); + shortcutAction->setShortcut(Qt::CTRL | Qt::Key_K); connect(shortcutAction, SIGNAL(triggered()), this, SLOT(openShortcutWindow())); // All available screen as action @@ -2844,16 +2846,11 @@ bool MainWindow::importMediaFile(const QString &fileName, bool isImage, bool isC } if (!isCamera && !file.open(QIODevice::ReadOnly)) { - if (file.isSequential()) { - type = VIDEO_SHMSRC; - } - else { - QMessageBox::warning(this, tr("MapMap Project"), - tr("Cannot read file %1:\n%2.") - .arg(file.fileName()) - .arg(file.errorString())); - return false; - } + QMessageBox::warning(this, tr("MapMap Project"), + tr("Cannot read file %1:\n%2.") + .arg(file.fileName()) + .arg(file.errorString())); + return false; } QApplication::setOverrideCursor(Qt::WaitCursor); @@ -3706,7 +3703,7 @@ bool MainWindow::setOscPort(int port) { if (port <= 1023 || port > 65535) { - qWarning() << "OSC port is out of range: " << port << endl; + qWarning() << "OSC port is out of range: " << port << Qt::endl; return false; } oscListeningPort = port; @@ -3729,7 +3726,7 @@ bool MainWindow::setOscPort(QString portNumber) } else { - qWarning() << "OSC port is not a number: " << portNumber << endl; + qWarning() << "OSC port is not a number: " << portNumber << Qt::endl; return false; } return true; diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index a59f78f45..c09d300a0 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -23,10 +23,9 @@ #define MAIN_WINDOW_H_ #include -#if QT_VERSION >= 0x050500 - #include - #include -#endif +#include +#include +#include #include #include #include diff --git a/src/gui/MapperGLCanvas.cpp b/src/gui/MapperGLCanvas.cpp index e294bc5c2..704be27b6 100644 --- a/src/gui/MapperGLCanvas.cpp +++ b/src/gui/MapperGLCanvas.cpp @@ -25,10 +25,13 @@ #include "MainWindow.h" #include "Commands.h" +#include +#include + namespace mmp { MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, - bool isOutput, QWidget* parent, const QGLWidget * shareWidget, + bool isOutput, QWidget* parent, QOpenGLWidget* shareWidget, QGraphicsScene* scene) : QGraphicsView(parent), _mainWindow(mainWindow), @@ -46,7 +49,7 @@ MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, setDragMode(QGraphicsView::NoDrag); setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | - QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform); + QPainter::SmoothPixmapTransform); // Dont need to always see scroll bar setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); @@ -67,7 +70,11 @@ MapperGLCanvas::MapperGLCanvas(MainWindow* mainWindow, // setAcceptDrops(true); // Render with OpenGL. - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers), this, shareWidget)); + QOpenGLWidget* glw = new QOpenGLWidget(this); + QSurfaceFormat fmt; + fmt.setSamples(4); // replaces QGL::SampleBuffers + glw->setFormat(fmt); + setViewport(glw); setViewportUpdateMode(QGraphicsView::FullViewportUpdate); // TODO: do we need to delete scene (or call new QGraphicsScene(this)?) @@ -170,7 +177,7 @@ void MapperGLCanvas::applyZoomToView() // Re-bound zoom (for consistency). qreal zoomFactor = getZoomFactor(); // Resets the view transformation matrix - resetMatrix(); + resetTransform(); // Scale the current view scale(zoomFactor, zoomFactor); // And update @@ -819,7 +826,7 @@ void MapperGLCanvas::fitShapeToView() setSceneRect(scene()->itemsBoundingRect()); centerOn(this->scene()->itemsBoundingRect().center()); // Get the horizontal scaling factor - _scalingFactor = matrix().m11(); + _scalingFactor = transform().m11(); // Adapt shape _shapeIsAdapted = true; diff --git a/src/gui/MapperGLCanvas.h b/src/gui/MapperGLCanvas.h index 08b76c784..e11e1fcca 100644 --- a/src/gui/MapperGLCanvas.h +++ b/src/gui/MapperGLCanvas.h @@ -21,7 +21,7 @@ #ifndef MAPPERGLCANVAS_H_ #define MAPPERGLCANVAS_H_ -#include +#include #include #include #include @@ -52,7 +52,7 @@ class MapperGLCanvas: public QGraphicsView Q_OBJECT public: /// Constructor. - MapperGLCanvas(MainWindow* mainWindow, bool isOutput, QWidget* parent = 0, const QGLWidget* shareWidget = 0, QGraphicsScene* scene = 0); + MapperGLCanvas(MainWindow* mainWindow, bool isOutput, QWidget* parent = 0, QOpenGLWidget* shareWidget = 0, QGraphicsScene* scene = 0); virtual ~MapperGLCanvas() {} /// Returns shape associated with mapping id. diff --git a/src/gui/MapperGLCanvasToolbar.cpp b/src/gui/MapperGLCanvasToolbar.cpp index 258b7341e..8d473fcf6 100644 --- a/src/gui/MapperGLCanvasToolbar.cpp +++ b/src/gui/MapperGLCanvasToolbar.cpp @@ -18,6 +18,10 @@ */ #include "MapperGLCanvasToolbar.h" +#include +#include +#include +#include namespace mmp { diff --git a/src/gui/MapperGLCanvasToolbar.h b/src/gui/MapperGLCanvasToolbar.h index 60be1fd9b..04a3d53db 100644 --- a/src/gui/MapperGLCanvasToolbar.h +++ b/src/gui/MapperGLCanvasToolbar.h @@ -23,6 +23,12 @@ #include "MM.h" #include "MapperGLCanvas.h" +#include +#include +#include + +class QHBoxLayout; + namespace mmp { class MapperGLCanvasToolbar : public QWidget { diff --git a/src/gui/MappingGui.cpp b/src/gui/MappingGui.cpp index c13a854d7..249fb5662 100644 --- a/src/gui/MappingGui.cpp +++ b/src/gui/MappingGui.cpp @@ -287,7 +287,7 @@ TextureMappingGui::TextureMappingGui(QSharedPointer mapping) // Input shape. _inputItem = _variantManager->addProperty(QtVariantPropertyManager::groupTypeId(), QObject::tr("Input shape")); - _buildShapeProperty(_inputItem, inputShape.data()); + _buildShapeProperty(_inputItem, inputShape.toStrongRef().data()); _propertyBrowser->insertProperty(_inputItem, _paintItem); // insert // Collapse input shape. diff --git a/src/gui/MappingListModel.cpp b/src/gui/MappingListModel.cpp index 75d28311a..c4ae06fd8 100644 --- a/src/gui/MappingListModel.cpp +++ b/src/gui/MappingListModel.cpp @@ -18,6 +18,7 @@ */ #include "MappingListModel.h" +#include namespace mmp { @@ -241,10 +242,9 @@ void MappingListModel::updateModel() void MappingListModel::clear() { - for (auto it = mappingList.end() - 1; it >= mappingList.begin(); --it) { - mappingList.erase(it); - updateModel(); - } + beginResetModel(); + mappingList.clear(); + endResetModel(); } QModelIndex MappingListModel::getIndexFromRow(int row) diff --git a/src/gui/OutputGLCanvas.cpp b/src/gui/OutputGLCanvas.cpp index c1d115b9e..aa0911354 100644 --- a/src/gui/OutputGLCanvas.cpp +++ b/src/gui/OutputGLCanvas.cpp @@ -22,9 +22,13 @@ #include "OutputGLCanvas.h" #include "MainWindow.h" +#include +#include +#include + namespace mmp { -OutputGLCanvas::OutputGLCanvas(MainWindow* mainWindow, QWidget* parent, const QGLWidget* shareWidget, QGraphicsScene* scene) +OutputGLCanvas::OutputGLCanvas(MainWindow* mainWindow, QWidget* parent, QOpenGLWidget* shareWidget, QGraphicsScene* scene) : MapperGLCanvas(mainWindow, true, parent, shareWidget, scene), _displayCrosshair(false), _displayTestSignal(false), @@ -51,7 +55,6 @@ void OutputGLCanvas::drawForeground(QPainter *painter , const QRectF &rect) { // Draw the preferred signal test card int testCard = settings.value("signalTestCard", MM::DEFAULT_TEST_CARD).toInt(); - glPushMatrix(); painter->translate(rect.x(), rect.y()); painter->setRenderHint(QPainter::Antialiasing); painter->save(); @@ -69,7 +72,6 @@ void OutputGLCanvas::drawForeground(QPainter *painter , const QRectF &rect) break; } painter->restore(); - glPopMatrix(); } else if (!controlOnMouseOver || (MainWindow::window()->displayControls() && _windowIsHovered)) { @@ -80,12 +82,12 @@ void OutputGLCanvas::drawForeground(QPainter *painter , const QRectF &rect) { #ifdef Q_OS_OSX QPoint globalCursorPos = QCursor::pos(); - int mouseScreen = QApplication::desktop()->screenNumber(globalCursorPos); - QRect mouseScreenGeometry = QApplication::desktop()->screen(mouseScreen)->geometry(); + QScreen* mouseScreenPtr = QGuiApplication::screenAt(globalCursorPos); + QRect mouseScreenGeometry = mouseScreenPtr ? mouseScreenPtr->geometry() : QRect(); QPoint localCursorPos = globalCursorPos - mouseScreenGeometry.topLeft(); QPointF cursorPosition = mapToScene(localCursorPos); // qDebug() << "Cursor pos " << globalCursorPos << " " << cursorPosition << " " << localCursorPos << mouseScreen << endl; - if (rect.contains(cursorPosition) && getMainWindow()->getPreferredScreen() == mouseScreen) + if (rect.contains(cursorPosition) && getMainWindow()->getPreferredScreen() == QGuiApplication::screens().indexOf(mouseScreenPtr)) // qDebug() << "Cursor pos " << mapToScene(mapFromGlobal(QCursor::pos(QApplication::screens()[1]))); #else QPointF cursorPosition = mapToScene(mapFromGlobal(cursor().pos()));// - rect.topLeft();//(QCursor::pos());///*this->mapFromGlobal(*/QCursor::pos()/*)*/; @@ -110,7 +112,7 @@ void OutputGLCanvas::drawForeground(QPainter *painter , const QRectF &rect) } -void OutputGLCanvas::enterEvent(QEvent *event) +void OutputGLCanvas::enterEvent(QEnterEvent *event) { _windowIsHovered = true; QGraphicsView::enterEvent(event); diff --git a/src/gui/OutputGLCanvas.h b/src/gui/OutputGLCanvas.h index 21b1e3f4e..a62c38833 100644 --- a/src/gui/OutputGLCanvas.h +++ b/src/gui/OutputGLCanvas.h @@ -31,7 +31,7 @@ class OutputGLCanvas: public MapperGLCanvas Q_OBJECT public: - OutputGLCanvas(MainWindow* mainWindow, QWidget* parent = 0, const QGLWidget* shareWidget = 0, QGraphicsScene* scene = 0); + OutputGLCanvas(MainWindow* mainWindow, QWidget* parent = 0, QOpenGLWidget* shareWidget = 0, QGraphicsScene* scene = 0); virtual ~OutputGLCanvas() {} // Adjust viewable scene to correspond to absolute coordinates. @@ -70,7 +70,7 @@ class OutputGLCanvas: public MapperGLCanvas void wheelEvent(QWheelEvent *event); void mouseMoveEvent(QMouseEvent *event); - void enterEvent(QEvent * event); + void enterEvent(QEnterEvent * event); void leaveEvent(QEvent *event); }; diff --git a/src/gui/OutputGLWindow.cpp b/src/gui/OutputGLWindow.cpp index d3aca959d..95858075f 100644 --- a/src/gui/OutputGLWindow.cpp +++ b/src/gui/OutputGLWindow.cpp @@ -23,13 +23,17 @@ #include "MainWindow.h" +#include +#include +#include + namespace mmp { OutputGLWindow:: OutputGLWindow(QWidget* parent, const MapperGLCanvas* canvas_) : QDialog(parent) { resize(MainWindow::OUTPUT_WINDOW_MINIMUM_WIDTH, MainWindow::OUTPUT_WINDOW_MINIMUM_HEIGHT); - canvas = new OutputGLCanvas(canvas_->getMainWindow(), this, (const QGLWidget*)canvas_->viewport(), canvas_->scene()); + canvas = new OutputGLCanvas(canvas_->getMainWindow(), this, qobject_cast(canvas_->viewport()), canvas_->scene()); canvas->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); canvas->setMinimumSize(MainWindow::OUTPUT_WINDOW_MINIMUM_WIDTH, MainWindow::OUTPUT_WINDOW_MINIMUM_HEIGHT); @@ -105,7 +109,9 @@ void OutputGLWindow::_updateToPreferredScreen() // Check if user is on multiple screen (always pre int screen = getPreferredScreen(); //Move window to second screen before fullscreening it. - setGeometry(QApplication::desktop()->screenGeometry(screen)); + const QList screens = QGuiApplication::screens(); + if (screen < screens.size()) + setGeometry(screens.at(screen)->geometry()); } void OutputGLWindow::_setFullScreen(bool fullscreen) diff --git a/src/gui/PreferenceDialog.cpp b/src/gui/PreferenceDialog.cpp index ffaab357d..5ed88b935 100644 --- a/src/gui/PreferenceDialog.cpp +++ b/src/gui/PreferenceDialog.cpp @@ -308,8 +308,8 @@ void PreferenceDialog::createControlsPage() bold.setWeight(QFont::Bold); // Set IP Address validator QString octet("(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"); - QRegExp rx(octet + "\\." + octet + "\\." + octet + "\\." + octet); - QRegExpValidator *ipValidator = new QRegExpValidator(rx); + QRegularExpression rx(octet + "\\." + octet + "\\." + octet + "\\." + octet); + QRegularExpressionValidator *ipValidator = new QRegularExpressionValidator(rx); QMargins margins(40, 0, 0, 0); // _sendMessageBox = new QCheckBox; diff --git a/src/gui/ShapeGraphicsItem.cpp b/src/gui/ShapeGraphicsItem.cpp index 37d94e832..09ab48c67 100644 --- a/src/gui/ShapeGraphicsItem.cpp +++ b/src/gui/ShapeGraphicsItem.cpp @@ -136,7 +136,7 @@ PolygonColorGraphicsItem::PolygonColorGraphicsItem(Mapping::ptr mapping, bool ou QPainterPath PolygonColorGraphicsItem::shape() const { QPainterPath path; - Polygon* poly = static_cast(_shape.data()); + Polygon* poly = static_cast(_shape.toStrongRef().data()); Q_ASSERT(poly); path.addPolygon(poly->toPolygon()); return mapFromScene(path); @@ -146,7 +146,7 @@ void PolygonColorGraphicsItem::_doPaint(QPainter *painter, const QStyleOptionGraphicsItem *option) { Q_UNUSED(option); - Polygon* poly = static_cast(_shape.data()); + Polygon* poly = static_cast(_shape.toStrongRef().data()); Q_ASSERT(poly); painter->drawPolygon(mapFromScene(poly->toPolygon())); } @@ -162,7 +162,7 @@ void MeshColorGraphicsItem::_doPaint(QPainter *painter, { Q_UNUSED(option); - Mesh* mesh = static_cast(_shape.data()); + Mesh* mesh = static_cast(_shape.toStrongRef().data()); QVector > quads = mesh->getQuads2d(); // Go through the mesh quad by quad. @@ -186,7 +186,7 @@ QPainterPath EllipseColorGraphicsItem::shape() const { // Create path for ellipse. QPainterPath path; - Ellipse* ellipse = static_cast(_shape.data()); + Ellipse* ellipse = static_cast(_shape.toStrongRef().data()); Q_ASSERT(ellipse); QTransform transform; transform.translate(ellipse->getCenter().x(), ellipse->getCenter().y()); @@ -319,7 +319,7 @@ QSharedPointer TextureGraphicsItem::_getTexture() QPainterPath PolygonTextureGraphicsItem::shape() const { QPainterPath path; - Polygon* poly = static_cast(_shape.data()); + Polygon* poly = static_cast(_shape.toStrongRef().data()); Q_ASSERT(poly); path.addPolygon(poly->toPolygon()); return mapFromScene(path); @@ -563,7 +563,7 @@ QPainterPath EllipseTextureGraphicsItem::shape() const { // Create path for ellipse. QPainterPath path; - Ellipse* ellipse = static_cast(_shape.data()); + Ellipse* ellipse = static_cast(_shape.toStrongRef().data()); Q_ASSERT(ellipse); QTransform transform; transform.translate(ellipse->getCenter().x(), ellipse->getCenter().y()); diff --git a/src/gui/ShapeGraphicsItem.h b/src/gui/ShapeGraphicsItem.h index 3428e867f..c01795b09 100644 --- a/src/gui/ShapeGraphicsItem.h +++ b/src/gui/ShapeGraphicsItem.h @@ -34,6 +34,8 @@ #include "Shapes.h" +#include +#include #include "Paint.h" #include "Mapping.h" #include "MapperGLCanvas.h" diff --git a/src/gui/ShortcutWindow.cpp b/src/gui/ShortcutWindow.cpp index a8d2375cb..e46961461 100644 --- a/src/gui/ShortcutWindow.cpp +++ b/src/gui/ShortcutWindow.cpp @@ -70,7 +70,7 @@ void ShortcutWindow::reload() QFile cssFile(":/shortcut-css"); if (cssFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - htmlContent.append(QTextCodec::codecForName("UTF-8")->toUnicode(cssFile.readAll())); + htmlContent.append(QString::fromUtf8(cssFile.readAll())); } htmlContent.append("\n\n"); htmlContent.append("\n"); @@ -79,7 +79,7 @@ void ShortcutWindow::reload() QFile htmlFile(":/index-html"); if (htmlFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - htmlContent.append(QTextCodec::codecForName("UTF-8")->toUnicode(htmlFile.readAll())); + htmlContent.append(QString::fromUtf8(htmlFile.readAll())); } htmlContent.append(""); diff --git a/src/gui/ShortcutWindow.h b/src/gui/ShortcutWindow.h index 1a4f15a37..2bd21de4f 100644 --- a/src/gui/ShortcutWindow.h +++ b/src/gui/ShortcutWindow.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "MM.h" diff --git a/src/gui/contrib/qtpropertybrowser-extension/fileedit.cpp b/src/gui/contrib/qtpropertybrowser-extension/fileedit.cpp index 12bac1621..60ae7d703 100644 --- a/src/gui/contrib/qtpropertybrowser-extension/fileedit.cpp +++ b/src/gui/contrib/qtpropertybrowser-extension/fileedit.cpp @@ -31,7 +31,7 @@ FileEdit::FileEdit(QWidget *parent) : QWidget(parent) { QHBoxLayout *layout = new QHBoxLayout(this); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); theLineEdit = new QLineEdit(this); theLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred)); diff --git a/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.cpp b/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.cpp index c9a371dad..4e2a2cebf 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.cpp +++ b/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.cpp @@ -975,7 +975,7 @@ class QtLineEditFactoryPrivate : public EditorFactoryPrivate public: void slotPropertyChanged(QtProperty *property, const QString &value); - void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotRegExpChanged(QtProperty *property, const QRegularExpression ®Exp); void slotSetValue(const QString &value); void slotEchoModeChanged(QtProperty *, int); void slotReadOnlyChanged(QtProperty *, bool); @@ -999,7 +999,7 @@ void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property, } void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property, - const QRegExp ®Exp) + const QRegularExpression ®Exp) { if (!m_createdEditors.contains(property)) return; @@ -1015,7 +1015,7 @@ void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property, const QValidator *oldValidator = editor->validator(); QValidator *newValidator = 0; if (regExp.isValid()) { - newValidator = new QRegExpValidator(regExp, editor); + newValidator = new QRegularExpressionValidator(regExp, editor); } editor->setValidator(newValidator); if (oldValidator) @@ -1115,8 +1115,8 @@ void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager) { connect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); - connect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), - this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); + connect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegularExpression &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegularExpression &))); connect(manager, SIGNAL(echoModeChanged(QtProperty*, int)), this, SLOT(slotEchoModeChanged(QtProperty *, int))); connect(manager, SIGNAL(readOnlyChanged(QtProperty*, bool)), @@ -1135,9 +1135,9 @@ QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager, QLineEdit *editor = d_ptr->createEditor(property, parent); editor->setEchoMode((EchoMode)manager->echoMode(property)); editor->setReadOnly(manager->isReadOnly(property)); - QRegExp regExp = manager->regExp(property); + QRegularExpression regExp = manager->regExp(property); if (regExp.isValid()) { - QValidator *validator = new QRegExpValidator(regExp, editor); + QValidator *validator = new QRegularExpressionValidator(regExp, editor); editor->setValidator(validator); } editor->setText(manager->value(property)); @@ -1158,8 +1158,8 @@ void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager *manag { disconnect(manager, SIGNAL(valueChanged(QtProperty *, const QString &)), this, SLOT(slotPropertyChanged(QtProperty *, const QString &))); - disconnect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), - this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); + disconnect(manager, SIGNAL(regExpChanged(QtProperty *, const QRegularExpression &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegularExpression &))); disconnect(manager, SIGNAL(echoModeChanged(QtProperty*,int)), this, SLOT(slotEchoModeChanged(QtProperty *, int))); disconnect(manager, SIGNAL(readOnlyChanged(QtProperty*, bool)), @@ -1670,7 +1670,7 @@ QtCharEdit::QtCharEdit(QWidget *parent) { QHBoxLayout *layout = new QHBoxLayout(this); layout->addWidget(m_lineEdit); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); m_lineEdit->installEventFilter(this); m_lineEdit->setReadOnly(true); m_lineEdit->setFocusProxy(this); @@ -1794,7 +1794,7 @@ void QtCharEdit::keyReleaseEvent(QKeyEvent *e) void QtCharEdit::paintEvent(QPaintEvent *) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } @@ -2330,11 +2330,9 @@ void QtColorEditWidget::setValue(const QColor &c) void QtColorEditWidget::buttonClicked() { - bool ok = false; - QRgb oldRgba = m_color.rgba(); - QRgb newRgba = QColorDialog::getRgba(oldRgba, &ok, this); - if (ok && newRgba != oldRgba) { - setValue(QColor::fromRgba(newRgba)); + QColor newColor = QColorDialog::getColor(m_color, this, QString(), QColorDialog::ShowAlphaChannel); + if (newColor.isValid() && newColor != m_color) { + setValue(newColor); emit valueChanged(m_color); } } @@ -2366,7 +2364,7 @@ bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev) void QtColorEditWidget::paintEvent(QPaintEvent *) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } @@ -2588,7 +2586,7 @@ bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev) void QtFontEditWidget::paintEvent(QPaintEvent *) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.h b/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.h index cbb2077d2..c258ae7be 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.h +++ b/src/gui/contrib/qtpropertybrowser/src/qteditorfactory.h @@ -188,7 +188,7 @@ class QT_QTPROPERTYBROWSER_EXPORT QtLineEditFactory : public QtAbstractEditorFac Q_DECLARE_PRIVATE(QtLineEditFactory) Q_DISABLE_COPY(QtLineEditFactory) Q_PRIVATE_SLOT(d_func(), void slotPropertyChanged(QtProperty *, const QString &)) - Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegularExpression &)) Q_PRIVATE_SLOT(d_func(), void slotEchoModeChanged(QtProperty *, int)) Q_PRIVATE_SLOT(d_func(), void slotReadOnlyChanged(QtProperty *, bool)) Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QString &)) diff --git a/src/gui/contrib/qtpropertybrowser/src/qtpropertybrowserutils.cpp b/src/gui/contrib/qtpropertybrowser/src/qtpropertybrowserutils.cpp index f1cd61291..e6e806d4e 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qtpropertybrowserutils.cpp +++ b/src/gui/contrib/qtpropertybrowser/src/qtpropertybrowserutils.cpp @@ -286,7 +286,7 @@ void QtBoolEdit::mousePressEvent(QMouseEvent *event) void QtBoolEdit::paintEvent(QPaintEvent *) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } @@ -298,7 +298,7 @@ QtKeySequenceEdit::QtKeySequenceEdit(QWidget *parent) { QHBoxLayout *layout = new QHBoxLayout(this); layout->addWidget(m_lineEdit); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); m_lineEdit->installEventFilter(this); m_lineEdit->setReadOnly(true); m_lineEdit->setFocusProxy(this); @@ -432,7 +432,7 @@ void QtKeySequenceEdit::keyReleaseEvent(QKeyEvent *e) void QtKeySequenceEdit::paintEvent(QPaintEvent *) { QStyleOption opt; - opt.init(this); + opt.initFrom(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } diff --git a/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.cpp b/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.cpp index e50cafc45..4c08c5abc 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.cpp +++ b/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.cpp @@ -1303,12 +1303,12 @@ class QtStringPropertyManagerPrivate struct Data { - Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard), + Data() : regExp(QRegularExpression::wildcardToRegularExpression(QString(QLatin1Char('*')))), echoMode(QLineEdit::Normal), readOnly(false) { } QString val; - QRegExp regExp; + QRegularExpression regExp; int echoMode; bool readOnly; }; @@ -1348,7 +1348,7 @@ class QtStringPropertyManagerPrivate */ /*! - \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegExp ®Exp) + \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegularExpression ®Exp) This signal is emitted whenever a property created by this manager changes its currenlty set regular expression, passing a pointer to @@ -1397,9 +1397,9 @@ QString QtStringPropertyManager::value(const QtProperty *property) const \sa setRegExp() */ -QRegExp QtStringPropertyManager::regExp(const QtProperty *property) const +QRegularExpression QtStringPropertyManager::regExp(const QtProperty *property) const { - return getData(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegExp()); + return getData(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegularExpression()); } /*! @@ -1470,7 +1470,7 @@ void QtStringPropertyManager::setValue(QtProperty *property, const QString &val) if (data.val == val) return; - if (data.regExp.isValid() && !data.regExp.exactMatch(val)) + if (data.regExp.isValid() && !data.regExp.match(val).hasMatch()) return; data.val = val; @@ -1486,7 +1486,7 @@ void QtStringPropertyManager::setValue(QtProperty *property, const QString &val) \sa regExp(), setValue(), regExpChanged() */ -void QtStringPropertyManager::setRegExp(QtProperty *property, const QRegExp ®Exp) +void QtStringPropertyManager::setRegExp(QtProperty *property, const QRegularExpression ®Exp) { const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property); if (it == d_ptr->m_values.end()) @@ -6060,7 +6060,7 @@ void QtFontPropertyManager::setValue(QtProperty *property, const QFont &val) return; const QFont oldVal = it.value(); - if (oldVal == val && oldVal.resolve() == val.resolve()) + if (oldVal == val && oldVal.resolveMask() == val.resolveMask()) return; it.value() = val; diff --git a/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.h b/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.h index d6b94ccf1..7620cbbaa 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.h +++ b/src/gui/contrib/qtpropertybrowser/src/qtpropertymanager.h @@ -184,19 +184,19 @@ class QT_QTPROPERTYBROWSER_EXPORT QtStringPropertyManager : public QtAbstractPro ~QtStringPropertyManager(); QString value(const QtProperty *property) const; - QRegExp regExp(const QtProperty *property) const; + QRegularExpression regExp(const QtProperty *property) const; EchoMode echoMode(const QtProperty *property) const; bool isReadOnly(const QtProperty *property) const; public Q_SLOTS: void setValue(QtProperty *property, const QString &val); - void setRegExp(QtProperty *property, const QRegExp ®Exp); + void setRegExp(QtProperty *property, const QRegularExpression ®Exp); void setEchoMode(QtProperty *property, EchoMode echoMode); void setReadOnly(QtProperty *property, bool readOnly); Q_SIGNALS: void valueChanged(QtProperty *property, const QString &val); - void regExpChanged(QtProperty *property, const QRegExp ®Exp); + void regExpChanged(QtProperty *property, const QRegularExpression ®Exp); void echoModeChanged(QtProperty *property, const int); void readOnlyChanged(QtProperty *property, bool); diff --git a/src/gui/contrib/qtpropertybrowser/src/qttreepropertybrowser.cpp b/src/gui/contrib/qtpropertybrowser/src/qttreepropertybrowser.cpp index 97818e1c8..0ccecde44 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qttreepropertybrowser.cpp +++ b/src/gui/contrib/qtpropertybrowser/src/qttreepropertybrowser.cpp @@ -146,7 +146,7 @@ QtPropertyEditorView::QtPropertyEditorView(QWidget *parent) : void QtPropertyEditorView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { - QStyleOptionViewItemV3 opt = option; + QStyleOptionViewItem opt = option; bool hasValue = true; if (m_editorPrivate) { QtProperty *property = m_editorPrivate->indexToProperty(index); @@ -348,7 +348,7 @@ void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewIt if (property) hasValue = property->hasValue(); } - QStyleOptionViewItemV3 opt = option; + QStyleOptionViewItem opt = option; if ((m_editorPrivate && index.column() == 0) || !hasValue) { QtProperty *property = m_editorPrivate->indexToProperty(index); if (property && property->isModified()) { @@ -362,7 +362,7 @@ void QtPropertyEditorDelegate::paint(QPainter *painter, const QStyleOptionViewIt opt.palette.setColor(QPalette::Text, opt.palette.color(QPalette::BrightText)); } else { c = m_editorPrivate->calculatedBackgroundColor(m_editorPrivate->indexToBrowserItem(index)); - if (c.isValid() && (opt.features & QStyleOptionViewItemV2::Alternate)) + if (c.isValid() && (opt.features & QStyleOptionViewItem::Alternate)) c = c.lighter(112); } if (c.isValid()) @@ -466,7 +466,7 @@ static QIcon drawIndicatorIcon(const QPalette &palette, QStyle *style) void QtTreePropertyBrowserPrivate::init(QWidget *parent) { QHBoxLayout *layout = new QHBoxLayout(parent); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); m_treeWidget = new QtPropertyEditorView(parent); m_treeWidget->setEditorPrivate(this); m_treeWidget->setIconSize(QSize(18, 18)); @@ -483,8 +483,8 @@ void QtTreePropertyBrowserPrivate::init(QWidget *parent) m_delegate = new QtPropertyEditorDelegate(parent); m_delegate->setEditorPrivate(this); m_treeWidget->setItemDelegate(m_delegate); - m_treeWidget->header()->setMovable(false); - m_treeWidget->header()->setResizeMode(QHeaderView::Stretch); + m_treeWidget->header()->setSectionsMovable(false); + m_treeWidget->header()->setSectionResizeMode(QHeaderView::Stretch); m_expandIcon = drawIndicatorIcon(q_ptr->palette(), q_ptr->style()); @@ -589,7 +589,7 @@ void QtTreePropertyBrowserPrivate::propertyInserted(QtBrowserItem *index, QtBrow m_indexToItem[index] = newItem; newItem->setFlags(newItem->flags() | Qt::ItemIsEditable); - m_treeWidget->setItemExpanded(newItem, true); + newItem->setExpanded(true); updateItem(newItem); } @@ -896,7 +896,7 @@ void QtTreePropertyBrowser::setResizeMode(QtTreePropertyBrowser::ResizeMode mode case QtTreePropertyBrowser::Stretch: default: m = QHeaderView::Stretch; break; } - d_ptr->m_treeWidget->header()->setResizeMode(m); + d_ptr->m_treeWidget->header()->setSectionResizeMode(m); } /*! diff --git a/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.cpp b/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.cpp index d7fe11192..f1233a295 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.cpp +++ b/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #if defined(Q_CC_MSVC) # pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ @@ -315,7 +316,7 @@ class QtVariantPropertyManagerPrivate void slotDecimalsChanged(QtProperty *property, int prec); void slotValueChanged(QtProperty *property, bool val); void slotValueChanged(QtProperty *property, const QString &val); - void slotRegExpChanged(QtProperty *property, const QRegExp ®Exp); + void slotRegExpChanged(QtProperty *property, const QRegularExpression ®Exp); void slotEchoModeChanged(QtProperty *property, int); void slotValueChanged(QtProperty *property, const QDate &val); void slotRangeChanged(QtProperty *property, const QDate &min, const QDate &max); @@ -541,7 +542,7 @@ void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, con valueChanged(property, QVariant(val)); } -void QtVariantPropertyManagerPrivate::slotRegExpChanged(QtProperty *property, const QRegExp ®Exp) +void QtVariantPropertyManagerPrivate::slotRegExpChanged(QtProperty *property, const QRegularExpression ®Exp) { if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) emit q_ptr->attributeChanged(varProp, m_regExpAttribute, QVariant(regExp)); @@ -591,7 +592,7 @@ void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, con void QtVariantPropertyManagerPrivate::slotValueChanged(QtProperty *property, const QKeySequence &val) { QVariant v; - qVariantSetValue(v, val); + v.setValue(val); valueChanged(property, v); } @@ -678,7 +679,7 @@ void QtVariantPropertyManagerPrivate::slotEnumIconsChanged(QtProperty *property, { if (QtVariantProperty *varProp = m_internalToProperty.value(property, 0)) { QVariant v; - qVariantSetValue(v, enumIcons); + v.setValue(enumIcons); emit q_ptr->attributeChanged(varProp, m_enumIconsAttribute, v); } } @@ -855,7 +856,7 @@ void QtVariantPropertyManagerPrivate::slotFlagNamesChanged(QtProperty *property, \row \o QString \o regExp - \o QVariant::RegExp + \o QMetaType::QRegularExpression \row \o \o echoMode @@ -1017,7 +1018,7 @@ QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent) d_ptr->m_typeToPropertyManager[QVariant::String] = stringPropertyManager; d_ptr->m_typeToValueType[QVariant::String] = QVariant::String; d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_regExpAttribute] = - QVariant::RegExp; + QMetaType::QRegularExpression; d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_echoModeAttribute] = QVariant::Int; d_ptr->m_typeToAttributeToAttributeType[QVariant::String][d_ptr->m_readOnlyAttribute] = @@ -1025,8 +1026,8 @@ QtVariantPropertyManager::QtVariantPropertyManager(QObject *parent) connect(stringPropertyManager, SIGNAL(valueChanged(QtProperty *, const QString &)), this, SLOT(slotValueChanged(QtProperty *, const QString &))); - connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty *, const QRegExp &)), - this, SLOT(slotRegExpChanged(QtProperty *, const QRegExp &))); + connect(stringPropertyManager, SIGNAL(regExpChanged(QtProperty *, const QRegularExpression &)), + this, SLOT(slotRegExpChanged(QtProperty *, const QRegularExpression &))); connect(stringPropertyManager, SIGNAL(echoModeChanged(QtProperty*,int)), this, SLOT(slotEchoModeChanged(QtProperty*, int))); connect(stringPropertyManager, SIGNAL(readOnlyChanged(QtProperty*, bool)), @@ -1569,7 +1570,7 @@ QVariant QtVariantPropertyManager::attributeValue(const QtProperty *property, co return enumManager->enumNames(internProp); if (attribute == d_ptr->m_enumIconsAttribute) { QVariant v; - qVariantSetValue(v, enumManager->enumIcons(internProp)); + v.setValue(enumManager->enumIcons(internProp)); return v; } return QVariant(); @@ -1649,73 +1650,73 @@ void QtVariantPropertyManager::setValue(QtProperty *property, const QVariant &va QtAbstractPropertyManager *manager = internProp->propertyManager(); if (QtIntPropertyManager *intManager = qobject_cast(manager)) { - intManager->setValue(internProp, qVariantValue(val)); + intManager->setValue(internProp, val.value()); return; } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { - doubleManager->setValue(internProp, qVariantValue(val)); + doubleManager->setValue(internProp, val.value()); return; } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { - boolManager->setValue(internProp, qVariantValue(val)); + boolManager->setValue(internProp, val.value()); return; } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { - stringManager->setValue(internProp, qVariantValue(val)); + stringManager->setValue(internProp, val.value()); return; } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { - dateManager->setValue(internProp, qVariantValue(val)); + dateManager->setValue(internProp, val.value()); return; } else if (QtTimePropertyManager *timeManager = qobject_cast(manager)) { - timeManager->setValue(internProp, qVariantValue(val)); + timeManager->setValue(internProp, val.value()); return; } else if (QtDateTimePropertyManager *dateTimeManager = qobject_cast(manager)) { - dateTimeManager->setValue(internProp, qVariantValue(val)); + dateTimeManager->setValue(internProp, val.value()); return; } else if (QtKeySequencePropertyManager *keySequenceManager = qobject_cast(manager)) { - keySequenceManager->setValue(internProp, qVariantValue(val)); + keySequenceManager->setValue(internProp, val.value()); return; } else if (QtCharPropertyManager *charManager = qobject_cast(manager)) { - charManager->setValue(internProp, qVariantValue(val)); + charManager->setValue(internProp, val.value()); return; } else if (QtLocalePropertyManager *localeManager = qobject_cast(manager)) { - localeManager->setValue(internProp, qVariantValue(val)); + localeManager->setValue(internProp, val.value()); return; } else if (QtPointPropertyManager *pointManager = qobject_cast(manager)) { - pointManager->setValue(internProp, qVariantValue(val)); + pointManager->setValue(internProp, val.value()); return; } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { - pointFManager->setValue(internProp, qVariantValue(val)); + pointFManager->setValue(internProp, val.value()); return; } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { - sizeManager->setValue(internProp, qVariantValue(val)); + sizeManager->setValue(internProp, val.value()); return; } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { - sizeFManager->setValue(internProp, qVariantValue(val)); + sizeFManager->setValue(internProp, val.value()); return; } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { - rectManager->setValue(internProp, qVariantValue(val)); + rectManager->setValue(internProp, val.value()); return; } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { - rectFManager->setValue(internProp, qVariantValue(val)); + rectFManager->setValue(internProp, val.value()); return; } else if (QtColorPropertyManager *colorManager = qobject_cast(manager)) { - colorManager->setValue(internProp, qVariantValue(val)); + colorManager->setValue(internProp, val.value()); return; } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { - enumManager->setValue(internProp, qVariantValue(val)); + enumManager->setValue(internProp, val.value()); return; } else if (QtSizePolicyPropertyManager *sizePolicyManager = qobject_cast(manager)) { - sizePolicyManager->setValue(internProp, qVariantValue(val)); + sizePolicyManager->setValue(internProp, val.value()); return; } else if (QtFontPropertyManager *fontManager = qobject_cast(manager)) { - fontManager->setValue(internProp, qVariantValue(val)); + fontManager->setValue(internProp, val.value()); return; #ifndef QT_NO_CURSOR } else if (QtCursorPropertyManager *cursorManager = qobject_cast(manager)) { - cursorManager->setValue(internProp, qVariantValue(val)); + cursorManager->setValue(internProp, val.value()); return; #endif } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { - flagManager->setValue(internProp, qVariantValue(val)); + flagManager->setValue(internProp, val.value()); return; } } @@ -1753,81 +1754,81 @@ void QtVariantPropertyManager::setAttribute(QtProperty *property, QtAbstractPropertyManager *manager = internProp->propertyManager(); if (QtIntPropertyManager *intManager = qobject_cast(manager)) { if (attribute == d_ptr->m_maximumAttribute) - intManager->setMaximum(internProp, qVariantValue(value)); + intManager->setMaximum(internProp, value.value()); else if (attribute == d_ptr->m_minimumAttribute) - intManager->setMinimum(internProp, qVariantValue(value)); + intManager->setMinimum(internProp, value.value()); else if (attribute == d_ptr->m_singleStepAttribute) - intManager->setSingleStep(internProp, qVariantValue(value)); + intManager->setSingleStep(internProp, value.value()); else if (attribute == d_ptr->m_readOnlyAttribute) - intManager->setReadOnly(internProp, qVariantValue(value)); + intManager->setReadOnly(internProp, value.value()); return; } else if (QtDoublePropertyManager *doubleManager = qobject_cast(manager)) { if (attribute == d_ptr->m_maximumAttribute) - doubleManager->setMaximum(internProp, qVariantValue(value)); + doubleManager->setMaximum(internProp, value.value()); if (attribute == d_ptr->m_minimumAttribute) - doubleManager->setMinimum(internProp, qVariantValue(value)); + doubleManager->setMinimum(internProp, value.value()); if (attribute == d_ptr->m_singleStepAttribute) - doubleManager->setSingleStep(internProp, qVariantValue(value)); + doubleManager->setSingleStep(internProp, value.value()); if (attribute == d_ptr->m_decimalsAttribute) - doubleManager->setDecimals(internProp, qVariantValue(value)); + doubleManager->setDecimals(internProp, value.value()); if (attribute == d_ptr->m_readOnlyAttribute) - doubleManager->setReadOnly(internProp, qVariantValue(value)); + doubleManager->setReadOnly(internProp, value.value()); return; } else if (QtBoolPropertyManager *boolManager = qobject_cast(manager)) { if (attribute == d_ptr->m_textVisibleAttribute) - boolManager->setTextVisible(internProp, qVariantValue(value)); + boolManager->setTextVisible(internProp, value.value()); return; } else if (QtStringPropertyManager *stringManager = qobject_cast(manager)) { if (attribute == d_ptr->m_regExpAttribute) - stringManager->setRegExp(internProp, qVariantValue(value)); + stringManager->setRegExp(internProp, value.value()); if (attribute == d_ptr->m_echoModeAttribute) - stringManager->setEchoMode(internProp, (EchoMode)qVariantValue(value)); + stringManager->setEchoMode(internProp, (EchoMode)value.value()); if (attribute == d_ptr->m_readOnlyAttribute) - stringManager->setReadOnly(internProp, (EchoMode)qVariantValue(value)); + stringManager->setReadOnly(internProp, (EchoMode)value.value()); return; } else if (QtDatePropertyManager *dateManager = qobject_cast(manager)) { if (attribute == d_ptr->m_maximumAttribute) - dateManager->setMaximum(internProp, qVariantValue(value)); + dateManager->setMaximum(internProp, value.value()); if (attribute == d_ptr->m_minimumAttribute) - dateManager->setMinimum(internProp, qVariantValue(value)); + dateManager->setMinimum(internProp, value.value()); return; } else if (QtPointFPropertyManager *pointFManager = qobject_cast(manager)) { if (attribute == d_ptr->m_decimalsAttribute) - pointFManager->setDecimals(internProp, qVariantValue(value)); + pointFManager->setDecimals(internProp, value.value()); return; } else if (QtSizePropertyManager *sizeManager = qobject_cast(manager)) { if (attribute == d_ptr->m_maximumAttribute) - sizeManager->setMaximum(internProp, qVariantValue(value)); + sizeManager->setMaximum(internProp, value.value()); if (attribute == d_ptr->m_minimumAttribute) - sizeManager->setMinimum(internProp, qVariantValue(value)); + sizeManager->setMinimum(internProp, value.value()); return; } else if (QtSizeFPropertyManager *sizeFManager = qobject_cast(manager)) { if (attribute == d_ptr->m_maximumAttribute) - sizeFManager->setMaximum(internProp, qVariantValue(value)); + sizeFManager->setMaximum(internProp, value.value()); if (attribute == d_ptr->m_minimumAttribute) - sizeFManager->setMinimum(internProp, qVariantValue(value)); + sizeFManager->setMinimum(internProp, value.value()); if (attribute == d_ptr->m_decimalsAttribute) - sizeFManager->setDecimals(internProp, qVariantValue(value)); + sizeFManager->setDecimals(internProp, value.value()); return; } else if (QtRectPropertyManager *rectManager = qobject_cast(manager)) { if (attribute == d_ptr->m_constraintAttribute) - rectManager->setConstraint(internProp, qVariantValue(value)); + rectManager->setConstraint(internProp, value.value()); return; } else if (QtRectFPropertyManager *rectFManager = qobject_cast(manager)) { if (attribute == d_ptr->m_constraintAttribute) - rectFManager->setConstraint(internProp, qVariantValue(value)); + rectFManager->setConstraint(internProp, value.value()); if (attribute == d_ptr->m_decimalsAttribute) - rectFManager->setDecimals(internProp, qVariantValue(value)); + rectFManager->setDecimals(internProp, value.value()); return; } else if (QtEnumPropertyManager *enumManager = qobject_cast(manager)) { if (attribute == d_ptr->m_enumNamesAttribute) - enumManager->setEnumNames(internProp, qVariantValue(value)); + enumManager->setEnumNames(internProp, value.value()); if (attribute == d_ptr->m_enumIconsAttribute) - enumManager->setEnumIcons(internProp, qVariantValue(value)); + enumManager->setEnumIcons(internProp, value.value()); return; } else if (QtFlagPropertyManager *flagManager = qobject_cast(manager)) { if (attribute == d_ptr->m_flagNamesAttribute) - flagManager->setFlagNames(internProp, qVariantValue(value)); + flagManager->setFlagNames(internProp, value.value()); return; } } @@ -2089,87 +2090,87 @@ QtVariantEditorFactory::~QtVariantEditorFactory() */ void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *manager) { - QList intPropertyManagers = qFindChildren(manager); + QList intPropertyManagers = manager->findChildren(); QListIterator itInt(intPropertyManagers); while (itInt.hasNext()) d_ptr->m_spinBoxFactory->addPropertyManager(itInt.next()); - QList doublePropertyManagers = qFindChildren(manager); + QList doublePropertyManagers = manager->findChildren(); QListIterator itDouble(doublePropertyManagers); while (itDouble.hasNext()) d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itDouble.next()); - QList boolPropertyManagers = qFindChildren(manager); + QList boolPropertyManagers = manager->findChildren(); QListIterator itBool(boolPropertyManagers); while (itBool.hasNext()) d_ptr->m_checkBoxFactory->addPropertyManager(itBool.next()); - QList stringPropertyManagers = qFindChildren(manager); + QList stringPropertyManagers = manager->findChildren(); QListIterator itString(stringPropertyManagers); while (itString.hasNext()) d_ptr->m_lineEditFactory->addPropertyManager(itString.next()); - QList datePropertyManagers = qFindChildren(manager); + QList datePropertyManagers = manager->findChildren(); QListIterator itDate(datePropertyManagers); while (itDate.hasNext()) d_ptr->m_dateEditFactory->addPropertyManager(itDate.next()); - QList timePropertyManagers = qFindChildren(manager); + QList timePropertyManagers = manager->findChildren(); QListIterator itTime(timePropertyManagers); while (itTime.hasNext()) d_ptr->m_timeEditFactory->addPropertyManager(itTime.next()); - QList dateTimePropertyManagers = qFindChildren(manager); + QList dateTimePropertyManagers = manager->findChildren(); QListIterator itDateTime(dateTimePropertyManagers); while (itDateTime.hasNext()) d_ptr->m_dateTimeEditFactory->addPropertyManager(itDateTime.next()); - QList keySequencePropertyManagers = qFindChildren(manager); + QList keySequencePropertyManagers = manager->findChildren(); QListIterator itKeySequence(keySequencePropertyManagers); while (itKeySequence.hasNext()) d_ptr->m_keySequenceEditorFactory->addPropertyManager(itKeySequence.next()); - QList charPropertyManagers = qFindChildren(manager); + QList charPropertyManagers = manager->findChildren(); QListIterator itChar(charPropertyManagers); while (itChar.hasNext()) d_ptr->m_charEditorFactory->addPropertyManager(itChar.next()); - QList localePropertyManagers = qFindChildren(manager); + QList localePropertyManagers = manager->findChildren(); QListIterator itLocale(localePropertyManagers); while (itLocale.hasNext()) d_ptr->m_comboBoxFactory->addPropertyManager(itLocale.next()->subEnumPropertyManager()); - QList pointPropertyManagers = qFindChildren(manager); + QList pointPropertyManagers = manager->findChildren(); QListIterator itPoint(pointPropertyManagers); while (itPoint.hasNext()) d_ptr->m_spinBoxFactory->addPropertyManager(itPoint.next()->subIntPropertyManager()); - QList pointFPropertyManagers = qFindChildren(manager); + QList pointFPropertyManagers = manager->findChildren(); QListIterator itPointF(pointFPropertyManagers); while (itPointF.hasNext()) d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itPointF.next()->subDoublePropertyManager()); - QList sizePropertyManagers = qFindChildren(manager); + QList sizePropertyManagers = manager->findChildren(); QListIterator itSize(sizePropertyManagers); while (itSize.hasNext()) d_ptr->m_spinBoxFactory->addPropertyManager(itSize.next()->subIntPropertyManager()); - QList sizeFPropertyManagers = qFindChildren(manager); + QList sizeFPropertyManagers = manager->findChildren(); QListIterator itSizeF(sizeFPropertyManagers); while (itSizeF.hasNext()) d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itSizeF.next()->subDoublePropertyManager()); - QList rectPropertyManagers = qFindChildren(manager); + QList rectPropertyManagers = manager->findChildren(); QListIterator itRect(rectPropertyManagers); while (itRect.hasNext()) d_ptr->m_spinBoxFactory->addPropertyManager(itRect.next()->subIntPropertyManager()); - QList rectFPropertyManagers = qFindChildren(manager); + QList rectFPropertyManagers = manager->findChildren(); QListIterator itRectF(rectFPropertyManagers); while (itRectF.hasNext()) d_ptr->m_doubleSpinBoxFactory->addPropertyManager(itRectF.next()->subDoublePropertyManager()); - QList colorPropertyManagers = qFindChildren(manager); + QList colorPropertyManagers = manager->findChildren(); QListIterator itColor(colorPropertyManagers); while (itColor.hasNext()) { QtColorPropertyManager *manager = itColor.next(); @@ -2177,12 +2178,12 @@ void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *ma d_ptr->m_spinBoxFactory->addPropertyManager(manager->subIntPropertyManager()); } - QList enumPropertyManagers = qFindChildren(manager); + QList enumPropertyManagers = manager->findChildren(); QListIterator itEnum(enumPropertyManagers); while (itEnum.hasNext()) d_ptr->m_comboBoxFactory->addPropertyManager(itEnum.next()); - QList sizePolicyPropertyManagers = qFindChildren(manager); + QList sizePolicyPropertyManagers = manager->findChildren(); QListIterator itSizePolicy(sizePolicyPropertyManagers); while (itSizePolicy.hasNext()) { QtSizePolicyPropertyManager *manager = itSizePolicy.next(); @@ -2190,7 +2191,7 @@ void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *ma d_ptr->m_comboBoxFactory->addPropertyManager(manager->subEnumPropertyManager()); } - QList fontPropertyManagers = qFindChildren(manager); + QList fontPropertyManagers = manager->findChildren(); QListIterator itFont(fontPropertyManagers); while (itFont.hasNext()) { QtFontPropertyManager *manager = itFont.next(); @@ -2200,12 +2201,12 @@ void QtVariantEditorFactory::connectPropertyManager(QtVariantPropertyManager *ma d_ptr->m_checkBoxFactory->addPropertyManager(manager->subBoolPropertyManager()); } - QList cursorPropertyManagers = qFindChildren(manager); + QList cursorPropertyManagers = manager->findChildren(); QListIterator itCursor(cursorPropertyManagers); while (itCursor.hasNext()) d_ptr->m_cursorEditorFactory->addPropertyManager(itCursor.next()); - QList flagPropertyManagers = qFindChildren(manager); + QList flagPropertyManagers = manager->findChildren(); QListIterator itFlag(flagPropertyManagers); while (itFlag.hasNext()) d_ptr->m_checkBoxFactory->addPropertyManager(itFlag.next()->subBoolPropertyManager()); @@ -2233,87 +2234,87 @@ QWidget *QtVariantEditorFactory::createEditor(QtVariantPropertyManager *manager, */ void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager *manager) { - QList intPropertyManagers = qFindChildren(manager); + QList intPropertyManagers = manager->findChildren(); QListIterator itInt(intPropertyManagers); while (itInt.hasNext()) d_ptr->m_spinBoxFactory->removePropertyManager(itInt.next()); - QList doublePropertyManagers = qFindChildren(manager); + QList doublePropertyManagers = manager->findChildren(); QListIterator itDouble(doublePropertyManagers); while (itDouble.hasNext()) d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itDouble.next()); - QList boolPropertyManagers = qFindChildren(manager); + QList boolPropertyManagers = manager->findChildren(); QListIterator itBool(boolPropertyManagers); while (itBool.hasNext()) d_ptr->m_checkBoxFactory->removePropertyManager(itBool.next()); - QList stringPropertyManagers = qFindChildren(manager); + QList stringPropertyManagers = manager->findChildren(); QListIterator itString(stringPropertyManagers); while (itString.hasNext()) d_ptr->m_lineEditFactory->removePropertyManager(itString.next()); - QList datePropertyManagers = qFindChildren(manager); + QList datePropertyManagers = manager->findChildren(); QListIterator itDate(datePropertyManagers); while (itDate.hasNext()) d_ptr->m_dateEditFactory->removePropertyManager(itDate.next()); - QList timePropertyManagers = qFindChildren(manager); + QList timePropertyManagers = manager->findChildren(); QListIterator itTime(timePropertyManagers); while (itTime.hasNext()) d_ptr->m_timeEditFactory->removePropertyManager(itTime.next()); - QList dateTimePropertyManagers = qFindChildren(manager); + QList dateTimePropertyManagers = manager->findChildren(); QListIterator itDateTime(dateTimePropertyManagers); while (itDateTime.hasNext()) d_ptr->m_dateTimeEditFactory->removePropertyManager(itDateTime.next()); - QList keySequencePropertyManagers = qFindChildren(manager); + QList keySequencePropertyManagers = manager->findChildren(); QListIterator itKeySequence(keySequencePropertyManagers); while (itKeySequence.hasNext()) d_ptr->m_keySequenceEditorFactory->removePropertyManager(itKeySequence.next()); - QList charPropertyManagers = qFindChildren(manager); + QList charPropertyManagers = manager->findChildren(); QListIterator itChar(charPropertyManagers); while (itChar.hasNext()) d_ptr->m_charEditorFactory->removePropertyManager(itChar.next()); - QList localePropertyManagers = qFindChildren(manager); + QList localePropertyManagers = manager->findChildren(); QListIterator itLocale(localePropertyManagers); while (itLocale.hasNext()) d_ptr->m_comboBoxFactory->removePropertyManager(itLocale.next()->subEnumPropertyManager()); - QList pointPropertyManagers = qFindChildren(manager); + QList pointPropertyManagers = manager->findChildren(); QListIterator itPoint(pointPropertyManagers); while (itPoint.hasNext()) d_ptr->m_spinBoxFactory->removePropertyManager(itPoint.next()->subIntPropertyManager()); - QList pointFPropertyManagers = qFindChildren(manager); + QList pointFPropertyManagers = manager->findChildren(); QListIterator itPointF(pointFPropertyManagers); while (itPointF.hasNext()) d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itPointF.next()->subDoublePropertyManager()); - QList sizePropertyManagers = qFindChildren(manager); + QList sizePropertyManagers = manager->findChildren(); QListIterator itSize(sizePropertyManagers); while (itSize.hasNext()) d_ptr->m_spinBoxFactory->removePropertyManager(itSize.next()->subIntPropertyManager()); - QList sizeFPropertyManagers = qFindChildren(manager); + QList sizeFPropertyManagers = manager->findChildren(); QListIterator itSizeF(sizeFPropertyManagers); while (itSizeF.hasNext()) d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itSizeF.next()->subDoublePropertyManager()); - QList rectPropertyManagers = qFindChildren(manager); + QList rectPropertyManagers = manager->findChildren(); QListIterator itRect(rectPropertyManagers); while (itRect.hasNext()) d_ptr->m_spinBoxFactory->removePropertyManager(itRect.next()->subIntPropertyManager()); - QList rectFPropertyManagers = qFindChildren(manager); + QList rectFPropertyManagers = manager->findChildren(); QListIterator itRectF(rectFPropertyManagers); while (itRectF.hasNext()) d_ptr->m_doubleSpinBoxFactory->removePropertyManager(itRectF.next()->subDoublePropertyManager()); - QList colorPropertyManagers = qFindChildren(manager); + QList colorPropertyManagers = manager->findChildren(); QListIterator itColor(colorPropertyManagers); while (itColor.hasNext()) { QtColorPropertyManager *manager = itColor.next(); @@ -2321,12 +2322,12 @@ void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager d_ptr->m_spinBoxFactory->removePropertyManager(manager->subIntPropertyManager()); } - QList enumPropertyManagers = qFindChildren(manager); + QList enumPropertyManagers = manager->findChildren(); QListIterator itEnum(enumPropertyManagers); while (itEnum.hasNext()) d_ptr->m_comboBoxFactory->removePropertyManager(itEnum.next()); - QList sizePolicyPropertyManagers = qFindChildren(manager); + QList sizePolicyPropertyManagers = manager->findChildren(); QListIterator itSizePolicy(sizePolicyPropertyManagers); while (itSizePolicy.hasNext()) { QtSizePolicyPropertyManager *manager = itSizePolicy.next(); @@ -2334,7 +2335,7 @@ void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager d_ptr->m_comboBoxFactory->removePropertyManager(manager->subEnumPropertyManager()); } - QList fontPropertyManagers = qFindChildren(manager); + QList fontPropertyManagers = manager->findChildren(); QListIterator itFont(fontPropertyManagers); while (itFont.hasNext()) { QtFontPropertyManager *manager = itFont.next(); @@ -2344,12 +2345,12 @@ void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager d_ptr->m_checkBoxFactory->removePropertyManager(manager->subBoolPropertyManager()); } - QList cursorPropertyManagers = qFindChildren(manager); + QList cursorPropertyManagers = manager->findChildren(); QListIterator itCursor(cursorPropertyManagers); while (itCursor.hasNext()) d_ptr->m_cursorEditorFactory->removePropertyManager(itCursor.next()); - QList flagPropertyManagers = qFindChildren(manager); + QList flagPropertyManagers = manager->findChildren(); QListIterator itFlag(flagPropertyManagers); while (itFlag.hasNext()) d_ptr->m_checkBoxFactory->removePropertyManager(itFlag.next()->subBoolPropertyManager()); diff --git a/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.h b/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.h index 2c09fe9eb..35082c4a7 100644 --- a/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.h +++ b/src/gui/contrib/qtpropertybrowser/src/qtvariantproperty.h @@ -126,7 +126,7 @@ public Q_SLOTS: Q_PRIVATE_SLOT(d_func(), void slotDecimalsChanged(QtProperty *, int)) Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, bool)) Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QString &)) - Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegExp &)) + Q_PRIVATE_SLOT(d_func(), void slotRegExpChanged(QtProperty *, const QRegularExpression &)) Q_PRIVATE_SLOT(d_func(), void slotEchoModeChanged(QtProperty *, int)) Q_PRIVATE_SLOT(d_func(), void slotValueChanged(QtProperty *, const QDate &)) Q_PRIVATE_SLOT(d_func(), void slotRangeChanged(QtProperty *, const QDate &, const QDate &)) diff --git a/src/shape/Mesh.cpp b/src/shape/Mesh.cpp index cab48b7b1..f7e03cf21 100644 --- a/src/shape/Mesh.cpp +++ b/src/shape/Mesh.cpp @@ -18,6 +18,7 @@ */ #include "Mesh.h" +#include namespace mmp { @@ -480,7 +481,7 @@ void Mesh::copyFrom(const MShape& shape) for (int i=0; i<_nColumns; i++) { _vertices2d[i].resize(_nRows); - qCopy(mesh->_vertices2d[i].begin(), mesh->_vertices2d[i].end(), _vertices2d[i].begin()); + std::copy(mesh->_vertices2d[i].begin(), mesh->_vertices2d[i].end(), _vertices2d[i].begin()); } _reorderVertices(); diff --git a/src/shape/Polygon.cpp b/src/shape/Polygon.cpp index d194b2fb4..0184904ea 100644 --- a/src/shape/Polygon.cpp +++ b/src/shape/Polygon.cpp @@ -81,8 +81,8 @@ void Polygon::_constrainVertex(const QPolygonF& polygon, int i, QPointF& v) j != wrapAround(idx+1, segments.size())) { QPointF intersection; - if (segments[idx].intersect(segments[j], &intersection) == QLineF::BoundedIntersection || - originalToNew.intersect(segments[j], &intersection) == QLineF::BoundedIntersection) + if (segments[idx].intersects(segments[j], &intersection) == QLineF::BoundedIntersection || + originalToNew.intersects(segments[j], &intersection) == QLineF::BoundedIntersection) { // Rearrange segments with new position at intersection point. // Create small vector pointing in same direction as segment. diff --git a/src/shape/Shape.cpp b/src/shape/Shape.cpp index be83e1259..51f80ad49 100644 --- a/src/shape/Shape.cpp +++ b/src/shape/Shape.cpp @@ -101,48 +101,38 @@ QPointF MShape::getCenter() const return center; } -void MShape::read(const QDomElement& obj) +void MShape::read(const QJsonObject& obj) { - // Read basic data. Serializable::read(obj); // Read vertices. - QDomElement verticesObj = obj.firstChildElement("vertices"); - QDomNode vertexNode = verticesObj.firstChild(); + QJsonArray verticesArray = obj["vertices"].toArray(); QVector vertices; - while (!vertexNode.isNull()) + for (const auto& v : verticesArray) { - const QDomElement& vertexElem = vertexNode.toElement(); - qreal x = vertexElem.attribute("x").toDouble(); - qreal y = vertexElem.attribute("y").toDouble(); - vertices.append(QPointF(x, y)); - - vertexNode = vertexNode.nextSibling(); + QJsonArray vertex = v.toArray(); + vertices.append(QPointF(vertex[0].toDouble(), vertex[1].toDouble())); } - // Set the vertices. setVertices(vertices); - - // Rebuild. build(); } -void MShape::write(QDomElement& obj) +void MShape::write(QJsonObject& obj) { - // Write basic data. Serializable::write(obj); // Write vertices. - QDomElement verticesObj = obj.ownerDocument().createElement("vertices"); + QJsonArray verticesArray; for (int i=0; i #include #include @@ -144,7 +145,7 @@ class MShape : public Serializable { // Deep copy. vertices.resize(vertices_.size()); - qCopy(vertices_.begin(), vertices_.end(), vertices.begin()); + std::copy(vertices_.begin(), vertices_.end(), vertices.begin()); } // Returns true iff vertex index is considered a major (external) control point. @@ -153,8 +154,8 @@ class MShape : public Serializable // Returns center of object. virtual QPointF getCenter() const; - virtual void read(const QDomElement& obj); - virtual void write(QDomElement& obj); + virtual void read(const QJsonObject& obj); + virtual void write(QJsonObject& obj); protected: QVector vertices; diff --git a/src/src.pri b/src/src.pri index 687136ebb..460b050c6 100644 --- a/src/src.pri +++ b/src/src.pri @@ -1,14 +1,11 @@ QT += gui QT += opengl -QT += xml +QT += openglwidgets QT += core QT += network QT += multimedia - -greaterThan(QT_MAJOR_VERSION, 4) { - QT -= gui # using widgets instead gui in Qt5 - QT += widgets -} +QT += multimediawidgets +QT += widgets #Includes common configuration for all subdirectory .pro files. INCLUDEPATH += $$PWD/core \ @@ -20,11 +17,6 @@ INCLUDEPATH += $$PWD/core \ #Linux-specific: unix:!macx { DEFINES += UNIX - CONFIG += link_pkgconfig - INCLUDE_PATH += - PKGCONFIG += \ - gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-pbutils-1.0 \ - gl x11 QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-result -Wno-unused-parameter \ -Wno-unused-variable -Wno-switch -Wno-comment \ -Wno-unused-but-set-variable @@ -36,9 +28,6 @@ macx { DEFINES += MACOSX QMAKE_CXXFLAGS += -D__MACOSX_CORE__ QMAKE_CXXFLAGS += -stdlib=libc++ - CONFIG += link_pkgconfig - PKGCONFIG += \ - gstreamer-1.0 gstreamer-base-1.0 gstreamer-app-1.0 gstreamer-pbutils-1.0 LIBS += -framework OpenGL -framework GLUT # With Xcode Tools > 1.5, to reduce the size of your binary even more: # LIBS += -dead_strip @@ -53,28 +42,8 @@ macx { win32 { DEFINES += WIN32 TARGET = ../../../MapMap/MapMap # Just for release - GST_HOME = $$quote($$(GSTREAMER_1_0_ROOT_X86)) - isEmpty(GST_HOME) { - message(\"GSTREAMER_1_0_ROOT_X86\" not detected ...) - } - else { - message(\"GSTREAMER_1_0_ROOT_X86\" detected in \"$${GST_HOME}\") - } - - INCLUDEPATH += $${GST_HOME}/lib/gstreamer-1.0/include \ - $${GST_HOME}/include/glib-2.0 \ - $${GST_HOME}/lib/glib-2.0/include \ - $${GST_HOME}/include/gstreamer-1.0 - LIBS += $${GST_HOME}/lib/gstapp-1.0.lib \ - $${GST_HOME}/lib/gstbase-1.0.lib \ - $${GST_HOME}/lib/gstpbutils-1.0.lib \ - $${GST_HOME}/lib/gstreamer-1.0.lib \ - $${GST_HOME}/lib/gobject-2.0.lib \ - $${GST_HOME}/lib/glib-2.0.lib \ - $${GST_HOME}/lib/gstaudio-1.0.lib \ - $${GST_HOME}/lib/gstvideo-1.0.lib \ - -lopengl32 + LIBS += -lopengl32 CONFIG -= debug CONFIG += release