summaryrefslogtreecommitdiffstats
path: root/examples/network
diff options
context:
space:
mode:
Diffstat (limited to 'examples/network')
-rw-r--r--examples/network/CMakeLists.txt19
-rw-r--r--examples/network/blockingfortuneclient/CMakeLists.txt33
-rw-r--r--examples/network/blockingfortuneclient/blockingclient.cpp9
-rw-r--r--examples/network/blockingfortuneclient/fortunethread.cpp2
-rw-r--r--examples/network/broadcastreceiver/CMakeLists.txt33
-rw-r--r--examples/network/broadcastreceiver/receiver.cpp3
-rw-r--r--examples/network/broadcastsender/CMakeLists.txt33
-rw-r--r--examples/network/broadcastsender/sender.cpp2
-rw-r--r--examples/network/dnslookup/CMakeLists.txt29
-rw-r--r--examples/network/dnslookup/dnslookup.cpp163
-rw-r--r--examples/network/doc/images/blockingfortuneclient-example.pngbin9199 -> 7013 bytes
-rw-r--r--examples/network/doc/images/dnslookup-example.webpbin0 -> 7532 bytes
-rw-r--r--examples/network/doc/images/fortuneclient-example.pngbin8282 -> 7814 bytes
-rw-r--r--examples/network/doc/images/fortuneserver-example.pngbin7883 -> 6167 bytes
-rw-r--r--examples/network/doc/images/googlesuggest-example.pngbin21272 -> 0 bytes
-rw-r--r--examples/network/doc/images/http-example.pngbin8099 -> 0 bytes
-rw-r--r--examples/network/doc/images/http-example.webpbin0 -> 8250 bytes
-rw-r--r--examples/network/doc/images/loopback-example.pngbin6195 -> 0 bytes
-rw-r--r--examples/network/doc/images/multi-stream-client-example.webpbin0 -> 27060 bytes
-rw-r--r--examples/network/doc/images/multi-stream-server-example.webpbin0 -> 19164 bytes
-rw-r--r--examples/network/doc/images/multicastreceiver-example.pngbin13042 -> 0 bytes
-rw-r--r--examples/network/doc/images/multicastreceiver-example.webpbin0 -> 3280 bytes
-rw-r--r--examples/network/doc/images/multicastsender-example.pngbin21092 -> 0 bytes
-rw-r--r--examples/network/doc/images/multicastsender-example.webpbin0 -> 3502 bytes
-rw-r--r--examples/network/doc/images/network-chat-example.pngbin17453 -> 0 bytes
-rw-r--r--examples/network/doc/images/network-chat-example.webpbin0 -> 11864 bytes
-rw-r--r--examples/network/doc/images/rsslisting.pngbin0 -> 19739 bytes
-rw-r--r--examples/network/doc/images/securesocketclient-example.webpbin0 -> 86522 bytes
-rw-r--r--examples/network/doc/images/securesocketclient.pngbin12056 -> 0 bytes
-rw-r--r--examples/network/doc/images/securesocketclient2.pngbin15532 -> 0 bytes
-rw-r--r--examples/network/doc/images/threadedfortuneserver-example.pngbin16232 -> 5558 bytes
-rw-r--r--examples/network/doc/images/torrent-example.pngbin18915 -> 11343 bytes
-rw-r--r--examples/network/doc/src/blockingfortuneclient.qdoc10
-rw-r--r--examples/network/doc/src/broadcastreceiver.qdoc4
-rw-r--r--examples/network/doc/src/broadcastsender.qdoc4
-rw-r--r--examples/network/doc/src/dnslookup.qdoc17
-rw-r--r--examples/network/doc/src/fortuneclient.qdoc10
-rw-r--r--examples/network/doc/src/fortuneserver.qdoc10
-rw-r--r--examples/network/doc/src/googlesuggest.qdoc153
-rw-r--r--examples/network/doc/src/http.qdoc7
-rw-r--r--examples/network/doc/src/loopback.qdoc14
-rw-r--r--examples/network/doc/src/multicastreceiver.qdoc8
-rw-r--r--examples/network/doc/src/multicastsender.qdoc6
-rw-r--r--examples/network/doc/src/multistreamclient.qdoc15
-rw-r--r--examples/network/doc/src/multistreamserver.qdoc16
-rw-r--r--examples/network/doc/src/network-chat.qdoc6
-rw-r--r--examples/network/doc/src/network-download.qdoc17
-rw-r--r--examples/network/doc/src/network-downloadmanager.qdoc17
-rw-r--r--examples/network/doc/src/rsslisting.qdoc129
-rw-r--r--examples/network/doc/src/securesocketclient.qdoc7
-rw-r--r--examples/network/doc/src/secureudpclient.qdoc1
-rw-r--r--examples/network/doc/src/secureudpserver.qdoc1
-rw-r--r--examples/network/doc/src/threadedfortuneserver.qdoc7
-rw-r--r--examples/network/doc/src/torrent.qdoc1
-rw-r--r--examples/network/download/CMakeLists.txt30
-rw-r--r--examples/network/download/download.pro8
-rw-r--r--examples/network/download/main.cpp166
-rw-r--r--examples/network/downloadmanager/CMakeLists.txt32
-rw-r--r--examples/network/downloadmanager/downloadmanager.cpp165
-rw-r--r--examples/network/downloadmanager/downloadmanager.h46
-rw-r--r--examples/network/downloadmanager/downloadmanager.pro17
-rw-r--r--examples/network/downloadmanager/main.cpp35
-rw-r--r--examples/network/downloadmanager/textprogressbar.cpp60
-rw-r--r--examples/network/downloadmanager/textprogressbar.h24
-rw-r--r--examples/network/fortuneclient/CMakeLists.txt33
-rw-r--r--examples/network/fortuneclient/client.cpp17
-rw-r--r--examples/network/fortuneserver/CMakeLists.txt33
-rw-r--r--examples/network/fortuneserver/server.cpp12
-rw-r--r--examples/network/googlesuggest/CMakeLists.txt39
-rw-r--r--examples/network/googlesuggest/googlesuggest.cpp184
-rw-r--r--examples/network/googlesuggest/googlesuggest.h37
-rw-r--r--examples/network/googlesuggest/googlesuggest.pro8
-rw-r--r--examples/network/googlesuggest/main.cpp14
-rw-r--r--examples/network/googlesuggest/searchbox.cpp35
-rw-r--r--examples/network/googlesuggest/searchbox.h28
-rw-r--r--examples/network/http/CMakeLists.txt34
-rw-r--r--examples/network/http/httpwindow.cpp62
-rw-r--r--examples/network/http/httpwindow.h6
-rw-r--r--examples/network/http/main.cpp4
-rw-r--r--examples/network/loopback/CMakeLists.txt38
-rw-r--r--examples/network/loopback/dialog.cpp155
-rw-r--r--examples/network/loopback/dialog.h51
-rw-r--r--examples/network/loopback/loopback.pro9
-rw-r--r--examples/network/loopback/main.cpp14
-rw-r--r--examples/network/multicastreceiver/CMakeLists.txt33
-rw-r--r--examples/network/multicastreceiver/receiver.cpp4
-rw-r--r--examples/network/multicastsender/CMakeLists.txt33
-rw-r--r--examples/network/multistreamclient/CMakeLists.txt33
-rw-r--r--examples/network/multistreamserver/CMakeLists.txt33
-rw-r--r--examples/network/network-chat/CMakeLists.txt38
-rw-r--r--examples/network/network-chat/chatdialog.cpp10
-rw-r--r--examples/network/network-chat/chatdialog.h2
-rw-r--r--examples/network/network-chat/client.cpp52
-rw-r--r--examples/network/network-chat/client.h8
-rw-r--r--examples/network/network-chat/connection.cpp57
-rw-r--r--examples/network/network-chat/connection.h25
-rw-r--r--examples/network/network-chat/main.cpp4
-rw-r--r--examples/network/network-chat/network-chat.pro1
-rw-r--r--examples/network/network-chat/peermanager.cpp46
-rw-r--r--examples/network/network-chat/peermanager.h8
-rw-r--r--examples/network/network-chat/server.cpp2
-rw-r--r--examples/network/network-chat/server.h2
-rw-r--r--examples/network/network.pro19
-rw-r--r--examples/network/rsslisting/CMakeLists.txt39
-rw-r--r--examples/network/rsslisting/main.cpp16
-rw-r--r--examples/network/rsslisting/rsslisting.cpp126
-rw-r--r--examples/network/rsslisting/rsslisting.h54
-rw-r--r--examples/network/rsslisting/rsslisting.pro8
-rw-r--r--examples/network/securesocketclient/CMakeLists.txt34
-rw-r--r--examples/network/securesocketclient/certificateinfo.cpp24
-rw-r--r--examples/network/securesocketclient/main.cpp2
-rw-r--r--examples/network/securesocketclient/sslclient.cpp2
-rw-r--r--examples/network/secureudpclient/CMakeLists.txt34
-rw-r--r--examples/network/secureudpclient/addressdialog.h6
-rw-r--r--examples/network/secureudpclient/association.cpp4
-rw-r--r--examples/network/secureudpclient/association.h4
-rw-r--r--examples/network/secureudpclient/main.cpp2
-rw-r--r--examples/network/secureudpclient/mainwindow.cpp2
-rw-r--r--examples/network/secureudpclient/mainwindow.h8
-rw-r--r--examples/network/secureudpserver/CMakeLists.txt34
-rw-r--r--examples/network/secureudpserver/main.cpp2
-rw-r--r--examples/network/secureudpserver/mainwindow.h4
-rw-r--r--examples/network/secureudpserver/nicselector.h4
-rw-r--r--examples/network/secureudpserver/server.cpp6
-rw-r--r--examples/network/secureudpserver/server.h4
-rw-r--r--examples/network/threadedfortuneserver/CMakeLists.txt33
-rw-r--r--examples/network/threadedfortuneserver/dialog.cpp10
-rw-r--r--examples/network/threadedfortuneserver/fortunethread.cpp4
-rw-r--r--examples/network/threadedfortuneserver/fortunethread.h4
-rw-r--r--examples/network/torrent/CMakeLists.txt51
-rw-r--r--examples/network/torrent/filemanager.cpp22
-rw-r--r--examples/network/torrent/filemanager.h32
-rw-r--r--examples/network/torrent/icons.qrc23
-rw-r--r--examples/network/torrent/icons/1downarrow.pngbin895 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/1downarrow.svg3
-rw-r--r--examples/network/torrent/icons/1uparrow.pngbin822 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/1uparrow.svg3
-rw-r--r--examples/network/torrent/icons/about.svg4
-rw-r--r--examples/network/torrent/icons/bottom.pngbin1632 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/bottom.svg6
-rw-r--r--examples/network/torrent/icons/edit_add.pngbin394 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/edit_add.svg4
-rw-r--r--examples/network/torrent/icons/edit_remove.pngbin368 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/edit_remove.svg3
-rw-r--r--examples/network/torrent/icons/exit.pngbin1426 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/exit.svg4
-rw-r--r--examples/network/torrent/icons/peertopeer.pngbin10072 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/peertopeer.svg62
-rw-r--r--examples/network/torrent/icons/player_pause.pngbin690 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/player_pause.svg6
-rw-r--r--examples/network/torrent/icons/player_play.pngbin900 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/player_play.svg3
-rw-r--r--examples/network/torrent/icons/player_stop.pngbin627 -> 0 bytes
-rw-r--r--examples/network/torrent/icons/player_stop.svg5
-rw-r--r--examples/network/torrent/icons/stop.pngbin1252 -> 0 bytes
-rw-r--r--examples/network/torrent/main.cpp2
-rw-r--r--examples/network/torrent/mainwindow.cpp47
-rw-r--r--examples/network/torrent/metainfo.h2
-rw-r--r--examples/network/torrent/peerwireclient.cpp101
-rw-r--r--examples/network/torrent/peerwireclient.h8
-rw-r--r--examples/network/torrent/ratecontroller.cpp6
-rw-r--r--examples/network/torrent/torrentclient.cpp90
-rw-r--r--examples/network/torrent/torrentclient.h3
-rw-r--r--examples/network/torrent/torrentserver.cpp2
-rw-r--r--examples/network/torrent/trackerclient.cpp14
-rw-r--r--examples/network/torrent/trackerclient.h1
166 files changed, 1367 insertions, 2202 deletions
diff --git a/examples/network/CMakeLists.txt b/examples/network/CMakeLists.txt
index e6b35307de..6222bb7c8b 100644
--- a/examples/network/CMakeLists.txt
+++ b/examples/network/CMakeLists.txt
@@ -1,39 +1,36 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-if(NOT TARGET Qt::Network)
+if(NOT TARGET Qt6::Network)
return()
endif()
-qt_internal_add_example(download)
-qt_internal_add_example(downloadmanager)
-if(NOT INTEGRITY)
+if(NOT INTEGRITY AND NOT ANDROID)
qt_internal_add_example(dnslookup)
endif()
-if(TARGET Qt::Widgets)
+if(TARGET Qt6::Widgets)
qt_internal_add_example(blockingfortuneclient)
qt_internal_add_example(broadcastreceiver)
qt_internal_add_example(broadcastsender)
qt_internal_add_example(http)
- qt_internal_add_example(loopback)
qt_internal_add_example(threadedfortuneserver)
- qt_internal_add_example(googlesuggest)
qt_internal_add_example(torrent)
qt_internal_add_example(multicastreceiver)
qt_internal_add_example(multicastsender)
qt_internal_add_example(fortuneclient)
qt_internal_add_example(fortuneserver)
+ qt_internal_add_example(rsslisting)
endif()
-if(QT_FEATURE_processenvironment AND TARGET Qt::Widgets)
+if(QT_FEATURE_processenvironment AND TARGET Qt6::Widgets)
qt_internal_add_example(network-chat)
endif()
-if(QT_FEATURE_ssl AND TARGET Qt::Widgets)
+if(QT_FEATURE_ssl AND TARGET Qt6::Widgets)
qt_internal_add_example(securesocketclient)
endif()
-if(QT_FEATURE_dtls AND TARGET Qt::Widgets)
+if(QT_FEATURE_dtls AND TARGET Qt6::Widgets)
qt_internal_add_example(secureudpserver)
qt_internal_add_example(secureudpclient)
endif()
-if(QT_FEATURE_sctp AND TARGET Qt::Widgets)
+if(QT_FEATURE_sctp AND TARGET Qt6::Widgets)
qt_internal_add_example(multistreamserver)
qt_internal_add_example(multistreamclient)
endif()
diff --git a/examples/network/blockingfortuneclient/CMakeLists.txt b/examples/network/blockingfortuneclient/CMakeLists.txt
index aad6996101..de010f3805 100644
--- a/examples/network/blockingfortuneclient/CMakeLists.txt
+++ b/examples/network/blockingfortuneclient/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(blockingfortuneclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/blockingfortuneclient")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(blockingfortuneclient
blockingclient.cpp blockingclient.h
fortunethread.cpp fortunethread.h
@@ -25,15 +19,22 @@ set_target_properties(blockingfortuneclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(blockingfortuneclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(blockingfortuneclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS blockingfortuneclient
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET blockingfortuneclient
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/blockingfortuneclient/blockingclient.cpp b/examples/network/blockingfortuneclient/blockingclient.cpp
index ef059b2e5f..b530e052f6 100644
--- a/examples/network/blockingfortuneclient/blockingclient.cpp
+++ b/examples/network/blockingfortuneclient/blockingclient.cpp
@@ -14,12 +14,11 @@ BlockingClient::BlockingClient(QWidget *parent)
// find out which IP to connect to
QString ipAddress;
- QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
- ipAddressesList.at(i).toIPv4Address()) {
- ipAddress = ipAddressesList.at(i).toString();
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) {
+ ipAddress = entry.toString();
break;
}
}
diff --git a/examples/network/blockingfortuneclient/fortunethread.cpp b/examples/network/blockingfortuneclient/fortunethread.cpp
index 8e8df8cf8e..464482e17b 100644
--- a/examples/network/blockingfortuneclient/fortunethread.cpp
+++ b/examples/network/blockingfortuneclient/fortunethread.cpp
@@ -62,7 +62,7 @@ void FortuneThread::run()
//! [8] //! [11]
QDataStream in(&socket);
- in.setVersion(QDataStream::Qt_4_0);
+ in.setVersion(QDataStream::Qt_6_5);
QString fortune;
//! [11] //! [12]
diff --git a/examples/network/broadcastreceiver/CMakeLists.txt b/examples/network/broadcastreceiver/CMakeLists.txt
index d7ff099ebc..fca4b8d48e 100644
--- a/examples/network/broadcastreceiver/CMakeLists.txt
+++ b/examples/network/broadcastreceiver/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(broadcastreceiver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/broadcastreceiver")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(broadcastreceiver
main.cpp
receiver.cpp receiver.h
@@ -24,15 +18,22 @@ set_target_properties(broadcastreceiver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(broadcastreceiver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(broadcastreceiver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS broadcastreceiver
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET broadcastreceiver
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/broadcastreceiver/receiver.cpp b/examples/network/broadcastreceiver/receiver.cpp
index caa05ac45a..ffade9992c 100644
--- a/examples/network/broadcastreceiver/receiver.cpp
+++ b/examples/network/broadcastreceiver/receiver.cpp
@@ -5,6 +5,7 @@
#include <QPushButton>
#include <QUdpSocket>
#include <QVBoxLayout>
+#include <QCoreApplication>
#include "receiver.h"
@@ -26,7 +27,7 @@ Receiver::Receiver(QWidget *parent)
this, &Receiver::processPendingDatagrams);
//! [1]
connect(quitButton, &QPushButton::clicked,
- this, &Receiver::close);
+ qApp, &QCoreApplication::quit);
auto buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
diff --git a/examples/network/broadcastsender/CMakeLists.txt b/examples/network/broadcastsender/CMakeLists.txt
index 8019906beb..447fcd5425 100644
--- a/examples/network/broadcastsender/CMakeLists.txt
+++ b/examples/network/broadcastsender/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(broadcastsender LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/broadcastsender")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(broadcastsender
main.cpp
sender.cpp sender.h
@@ -24,15 +18,22 @@ set_target_properties(broadcastsender PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(broadcastsender PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(broadcastsender PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS broadcastsender
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET broadcastsender
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/broadcastsender/sender.cpp b/examples/network/broadcastsender/sender.cpp
index 7aa416ad6c..622d3f9616 100644
--- a/examples/network/broadcastsender/sender.cpp
+++ b/examples/network/broadcastsender/sender.cpp
@@ -25,7 +25,7 @@ Sender::Sender(QWidget *parent)
//! [0]
connect(startButton, &QPushButton::clicked, this, &Sender::startBroadcasting);
- connect(quitButton, &QPushButton::clicked, this, &Sender::close);
+ connect(quitButton, &QPushButton::clicked, qApp, &QCoreApplication::quit);
connect(&timer, &QTimer::timeout, this, &Sender::broadcastDatagram);
auto mainLayout = new QVBoxLayout;
diff --git a/examples/network/dnslookup/CMakeLists.txt b/examples/network/dnslookup/CMakeLists.txt
index d460a6c851..b1baef23d9 100644
--- a/examples/network/dnslookup/CMakeLists.txt
+++ b/examples/network/dnslookup/CMakeLists.txt
@@ -4,27 +4,32 @@
cmake_minimum_required(VERSION 3.16)
project(dnslookup LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
+if (ANDROID)
+ message(FATAL_ERROR "This project cannot be built on Android.")
endif()
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/dnslookup")
-
find_package(Qt6 REQUIRED COMPONENTS Core Network)
+qt_standard_project_setup()
+
qt_add_executable(dnslookup
dnslookup.cpp dnslookup.h
)
-target_link_libraries(dnslookup PUBLIC
- Qt::Core
- Qt::Network
+target_link_libraries(dnslookup PRIVATE
+ Qt6::Core
+ Qt6::Network
)
install(TARGETS dnslookup
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET dnslookup
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/dnslookup/dnslookup.cpp b/examples/network/dnslookup/dnslookup.cpp
index 91311b26b8..9e74ddcf42 100644
--- a/examples/network/dnslookup/dnslookup.cpp
+++ b/examples/network/dnslookup/dnslookup.cpp
@@ -11,43 +11,51 @@
#include <QCommandLineParser>
#include <QCommandLineOption>
-#include <stdio.h>
+#include <cstdio>
-static int typeFromParameter(const QString &type)
+using namespace Qt::StringLiterals;
+
+static std::optional<QDnsLookup::Type> typeFromParameter(QStringView type)
{
- if (type == "a")
+ if (type.compare(u"a", Qt::CaseInsensitive) == 0)
return QDnsLookup::A;
- if (type == "aaaa")
+ if (type.compare(u"aaaa", Qt::CaseInsensitive) == 0)
return QDnsLookup::AAAA;
- if (type == "any")
+ if (type.compare(u"any", Qt::CaseInsensitive) == 0)
return QDnsLookup::ANY;
- if (type == "cname")
+ if (type.compare(u"cname", Qt::CaseInsensitive) == 0)
return QDnsLookup::CNAME;
- if (type == "mx")
+ if (type.compare(u"mx", Qt::CaseInsensitive) == 0)
return QDnsLookup::MX;
- if (type == "ns")
+ if (type.compare(u"ns", Qt::CaseInsensitive) == 0)
return QDnsLookup::NS;
- if (type == "ptr")
+ if (type.compare(u"ptr", Qt::CaseInsensitive) == 0)
return QDnsLookup::PTR;
- if (type == "srv")
+ if (type.compare(u"srv", Qt::CaseInsensitive) == 0)
return QDnsLookup::SRV;
- if (type == "txt")
+ if (type.compare(u"txt", Qt::CaseInsensitive) == 0)
return QDnsLookup::TXT;
- return -1;
+ return std::nullopt;
}
//! [0]
-enum CommandLineParseResult
+struct CommandLineParseResult
{
- CommandLineOk,
- CommandLineError,
- CommandLineVersionRequested,
- CommandLineHelpRequested
+ enum class Status {
+ Ok,
+ Error,
+ VersionRequested,
+ HelpRequested
+ };
+ Status statusCode = Status::Ok;
+ std::optional<QString> errorString = std::nullopt;
};
-CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *query, QString *errorMessage)
+CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *query)
{
+ using Status = CommandLineParseResult::Status;
+
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
const QCommandLineOption nameServerOption("n", "The name server to use.", "nameserver");
parser.addOption(nameServerOption);
@@ -57,48 +65,41 @@ CommandLineParseResult parseCommandLine(QCommandLineParser &parser, DnsQuery *qu
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
- if (!parser.parse(QCoreApplication::arguments())) {
- *errorMessage = parser.errorText();
- return CommandLineError;
- }
+ if (!parser.parse(QCoreApplication::arguments()))
+ return { Status::Error, parser.errorText() };
if (parser.isSet(versionOption))
- return CommandLineVersionRequested;
+ return { Status::VersionRequested };
if (parser.isSet(helpOption))
- return CommandLineHelpRequested;
+ return { Status::HelpRequested };
if (parser.isSet(nameServerOption)) {
const QString nameserver = parser.value(nameServerOption);
query->nameServer = QHostAddress(nameserver);
- if (query->nameServer.isNull() || query->nameServer.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
- *errorMessage = "Bad nameserver address: " + nameserver;
- return CommandLineError;
+ if (query->nameServer.isNull()
+ || query->nameServer.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
+ return { Status::Error,
+ u"Bad nameserver address: %1"_s.arg(nameserver) };
}
}
if (parser.isSet(typeOption)) {
const QString typeParameter = parser.value(typeOption);
- const int type = typeFromParameter(typeParameter.toLower());
- if (type < 0) {
- *errorMessage = "Bad record type: " + typeParameter;
- return CommandLineError;
- }
- query->type = static_cast<QDnsLookup::Type>(type);
+ if (std::optional<QDnsLookup::Type> type = typeFromParameter(typeParameter))
+ query->type = *type;
+ else
+ return { Status::Error, u"Bad record type: %1"_s.arg(typeParameter) };
}
const QStringList positionalArguments = parser.positionalArguments();
- if (positionalArguments.isEmpty()) {
- *errorMessage = "Argument 'name' missing.";
- return CommandLineError;
- }
- if (positionalArguments.size() > 1) {
- *errorMessage = "Several 'name' arguments specified.";
- return CommandLineError;
- }
+ if (positionalArguments.isEmpty())
+ return { Status::Error, u"Argument 'name' missing."_s };
+ if (positionalArguments.size() > 1)
+ return { Status::Error, u"Several 'name' arguments specified."_s };
query->name = positionalArguments.first();
- return CommandLineOk;
+ return { Status::Ok };
}
//! [0]
@@ -122,39 +123,52 @@ void DnsManager::execute()
void DnsManager::showResults()
{
if (dns->error() != QDnsLookup::NoError)
- printf("Error: %i (%s)\n", dns->error(), qPrintable(dns->errorString()));
+ std::printf("Error: %i (%s)\n", dns->error(), qPrintable(dns->errorString()));
// CNAME records
const QList<QDnsDomainNameRecord> cnameRecords = dns->canonicalNameRecords();
- for (const QDnsDomainNameRecord &record : cnameRecords)
- printf("%s\t%i\tIN\tCNAME\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
+ for (const QDnsDomainNameRecord &record : cnameRecords) {
+ std::printf("%s\t%i\tIN\tCNAME\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(record.value()));
+ }
// A and AAAA records
const QList<QDnsHostAddressRecord> aRecords = dns->hostAddressRecords();
for (const QDnsHostAddressRecord &record : aRecords) {
- const char *type = (record.value().protocol() == QAbstractSocket::IPv6Protocol) ? "AAAA" : "A";
- printf("%s\t%i\tIN\t%s\t%s\n", qPrintable(record.name()), record.timeToLive(), type, qPrintable(record.value().toString()));
+ const char *type =
+ (record.value().protocol() == QAbstractSocket::IPv6Protocol) ? "AAAA" : "A";
+ std::printf("%s\t%i\tIN\t%s\t%s\n", qPrintable(record.name()), record.timeToLive(), type,
+ qPrintable(record.value().toString()));
}
// MX records
const QList<QDnsMailExchangeRecord> mxRecords = dns->mailExchangeRecords();
- for (const QDnsMailExchangeRecord &record : mxRecords)
- printf("%s\t%i\tIN\tMX\t%u %s\n", qPrintable(record.name()), record.timeToLive(), record.preference(), qPrintable(record.exchange()));
+ for (const QDnsMailExchangeRecord &record : mxRecords) {
+ std::printf("%s\t%i\tIN\tMX\t%u %s\n", qPrintable(record.name()), record.timeToLive(),
+ record.preference(), qPrintable(record.exchange()));
+ }
// NS records
const QList<QDnsDomainNameRecord> nsRecords = dns->nameServerRecords();
- for (const QDnsDomainNameRecord &record : nsRecords)
- printf("%s\t%i\tIN\tNS\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
+ for (const QDnsDomainNameRecord &record : nsRecords) {
+ std::printf("%s\t%i\tIN\tNS\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(record.value()));
+ }
// PTR records
const QList<QDnsDomainNameRecord> ptrRecords = dns->pointerRecords();
- for (const QDnsDomainNameRecord &record : ptrRecords)
- printf("%s\t%i\tIN\tPTR\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value()));
+ for (const QDnsDomainNameRecord &record : ptrRecords) {
+ std::printf("%s\t%i\tIN\tPTR\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(record.value()));
+ }
// SRV records
const QList<QDnsServiceRecord> srvRecords = dns->serviceRecords();
- for (const QDnsServiceRecord &record : srvRecords)
- printf("%s\t%i\tIN\tSRV\t%u %u %u %s\n", qPrintable(record.name()), record.timeToLive(), record.priority(), record.weight(), record.port(), qPrintable(record.target()));
+ for (const QDnsServiceRecord &record : srvRecords) {
+ std::printf("%s\t%i\tIN\tSRV\t%u %u %u %s\n", qPrintable(record.name()),
+ record.timeToLive(), record.priority(), record.weight(), record.port(),
+ qPrintable(record.target()));
+ }
// TXT records
const QList<QDnsTextRecord> txtRecords = dns->textRecords();
@@ -163,7 +177,8 @@ void DnsManager::showResults()
const QList<QByteArray> dnsRecords = record.values();
for (const QByteArray &ba : dnsRecords)
values << "\"" + QString::fromLatin1(ba) + "\"";
- printf("%s\t%i\tIN\tTXT\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(values.join(' ')));
+ std::printf("%s\t%i\tIN\tTXT\t%s\n", qPrintable(record.name()), record.timeToLive(),
+ qPrintable(values.join(' ')));
}
QCoreApplication::instance()->quit();
@@ -175,32 +190,36 @@ int main(int argc, char *argv[])
//! [1]
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- QCoreApplication::setApplicationName(QCoreApplication::translate("QDnsLookupExample", "DNS Lookup Example"));
+ QCoreApplication::setApplicationName(QCoreApplication::translate("QDnsLookupExample",
+ "DNS Lookup Example"));
QCommandLineParser parser;
- parser.setApplicationDescription(QCoreApplication::translate("QDnsLookupExample", "An example demonstrating the class QDnsLookup."));
+ parser.setApplicationDescription(QCoreApplication::translate("QDnsLookupExample",
+ "An example demonstrating the "
+ "class QDnsLookup."));
DnsQuery query;
- QString errorMessage;
- switch (parseCommandLine(parser, &query, &errorMessage)) {
- case CommandLineOk:
+ using Status = CommandLineParseResult::Status;
+ CommandLineParseResult parseResult = parseCommandLine(parser, &query);
+ switch (parseResult.statusCode) {
+ case Status::Ok:
break;
- case CommandLineError:
- fputs(qPrintable(errorMessage), stderr);
- fputs("\n\n", stderr);
- fputs(qPrintable(parser.helpText()), stderr);
+ case Status::Error:
+ std::fputs(qPrintable(parseResult.errorString.value_or(u"Unknown error occurred"_s)),
+ stderr);
+ std::fputs("\n\n", stderr);
+ std::fputs(qPrintable(parser.helpText()), stderr);
return 1;
- case CommandLineVersionRequested:
- printf("%s %s\n", qPrintable(QCoreApplication::applicationName()),
- qPrintable(QCoreApplication::applicationVersion()));
- return 0;
- case CommandLineHelpRequested:
+ case Status::VersionRequested:
+ parser.showVersion();
+ Q_UNREACHABLE_RETURN(0);
+ case Status::HelpRequested:
parser.showHelp();
- Q_UNREACHABLE();
+ Q_UNREACHABLE_RETURN(0);
}
//! [1]
DnsManager manager;
manager.setQuery(query);
- QTimer::singleShot(0, &manager, SLOT(execute()));
+ QTimer::singleShot(0, &manager, &DnsManager::execute);
return app.exec();
}
diff --git a/examples/network/doc/images/blockingfortuneclient-example.png b/examples/network/doc/images/blockingfortuneclient-example.png
index cdb7cac0d3..ab918e791d 100644
--- a/examples/network/doc/images/blockingfortuneclient-example.png
+++ b/examples/network/doc/images/blockingfortuneclient-example.png
Binary files differ
diff --git a/examples/network/doc/images/dnslookup-example.webp b/examples/network/doc/images/dnslookup-example.webp
new file mode 100644
index 0000000000..c835cf1af3
--- /dev/null
+++ b/examples/network/doc/images/dnslookup-example.webp
Binary files differ
diff --git a/examples/network/doc/images/fortuneclient-example.png b/examples/network/doc/images/fortuneclient-example.png
index b34a98736d..cae0b066dc 100644
--- a/examples/network/doc/images/fortuneclient-example.png
+++ b/examples/network/doc/images/fortuneclient-example.png
Binary files differ
diff --git a/examples/network/doc/images/fortuneserver-example.png b/examples/network/doc/images/fortuneserver-example.png
index 73f27d5653..55ea8b1c29 100644
--- a/examples/network/doc/images/fortuneserver-example.png
+++ b/examples/network/doc/images/fortuneserver-example.png
Binary files differ
diff --git a/examples/network/doc/images/googlesuggest-example.png b/examples/network/doc/images/googlesuggest-example.png
deleted file mode 100644
index c704f5b2b4..0000000000
--- a/examples/network/doc/images/googlesuggest-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/http-example.png b/examples/network/doc/images/http-example.png
deleted file mode 100644
index c5f3ef1649..0000000000
--- a/examples/network/doc/images/http-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/http-example.webp b/examples/network/doc/images/http-example.webp
new file mode 100644
index 0000000000..4f6269ec8b
--- /dev/null
+++ b/examples/network/doc/images/http-example.webp
Binary files differ
diff --git a/examples/network/doc/images/loopback-example.png b/examples/network/doc/images/loopback-example.png
deleted file mode 100644
index 2b1bd4a0f2..0000000000
--- a/examples/network/doc/images/loopback-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/multi-stream-client-example.webp b/examples/network/doc/images/multi-stream-client-example.webp
new file mode 100644
index 0000000000..6ec651ae9e
--- /dev/null
+++ b/examples/network/doc/images/multi-stream-client-example.webp
Binary files differ
diff --git a/examples/network/doc/images/multi-stream-server-example.webp b/examples/network/doc/images/multi-stream-server-example.webp
new file mode 100644
index 0000000000..95610e7267
--- /dev/null
+++ b/examples/network/doc/images/multi-stream-server-example.webp
Binary files differ
diff --git a/examples/network/doc/images/multicastreceiver-example.png b/examples/network/doc/images/multicastreceiver-example.png
deleted file mode 100644
index 8de11cda63..0000000000
--- a/examples/network/doc/images/multicastreceiver-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/multicastreceiver-example.webp b/examples/network/doc/images/multicastreceiver-example.webp
new file mode 100644
index 0000000000..2dd0c28036
--- /dev/null
+++ b/examples/network/doc/images/multicastreceiver-example.webp
Binary files differ
diff --git a/examples/network/doc/images/multicastsender-example.png b/examples/network/doc/images/multicastsender-example.png
deleted file mode 100644
index a619b047e3..0000000000
--- a/examples/network/doc/images/multicastsender-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/multicastsender-example.webp b/examples/network/doc/images/multicastsender-example.webp
new file mode 100644
index 0000000000..b06da08351
--- /dev/null
+++ b/examples/network/doc/images/multicastsender-example.webp
Binary files differ
diff --git a/examples/network/doc/images/network-chat-example.png b/examples/network/doc/images/network-chat-example.png
deleted file mode 100644
index 949bb07d87..0000000000
--- a/examples/network/doc/images/network-chat-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/network-chat-example.webp b/examples/network/doc/images/network-chat-example.webp
new file mode 100644
index 0000000000..9b8cc1fd8a
--- /dev/null
+++ b/examples/network/doc/images/network-chat-example.webp
Binary files differ
diff --git a/examples/network/doc/images/rsslisting.png b/examples/network/doc/images/rsslisting.png
new file mode 100644
index 0000000000..0b05375f93
--- /dev/null
+++ b/examples/network/doc/images/rsslisting.png
Binary files differ
diff --git a/examples/network/doc/images/securesocketclient-example.webp b/examples/network/doc/images/securesocketclient-example.webp
new file mode 100644
index 0000000000..658f93d053
--- /dev/null
+++ b/examples/network/doc/images/securesocketclient-example.webp
Binary files differ
diff --git a/examples/network/doc/images/securesocketclient.png b/examples/network/doc/images/securesocketclient.png
deleted file mode 100644
index 8736cbc264..0000000000
--- a/examples/network/doc/images/securesocketclient.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/securesocketclient2.png b/examples/network/doc/images/securesocketclient2.png
deleted file mode 100644
index 23db851e61..0000000000
--- a/examples/network/doc/images/securesocketclient2.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/doc/images/threadedfortuneserver-example.png b/examples/network/doc/images/threadedfortuneserver-example.png
index 701a0ca035..72315e0b79 100644
--- a/examples/network/doc/images/threadedfortuneserver-example.png
+++ b/examples/network/doc/images/threadedfortuneserver-example.png
Binary files differ
diff --git a/examples/network/doc/images/torrent-example.png b/examples/network/doc/images/torrent-example.png
index 1032716e04..485bc7f719 100644
--- a/examples/network/doc/images/torrent-example.png
+++ b/examples/network/doc/images/torrent-example.png
Binary files differ
diff --git a/examples/network/doc/src/blockingfortuneclient.qdoc b/examples/network/doc/src/blockingfortuneclient.qdoc
index 931391567d..ec99447b4b 100644
--- a/examples/network/doc/src/blockingfortuneclient.qdoc
+++ b/examples/network/doc/src/blockingfortuneclient.qdoc
@@ -3,7 +3,9 @@
/*!
\example blockingfortuneclient
- \title Blocking Fortune Client Example
+ \title Blocking Fortune Client
+ \examplecategory {Networking}
+ \meta tags {tcp,network,threading,synchronous-io}
\ingroup examples-network
\brief Demonstrates how to create a client for a network service.
@@ -107,7 +109,7 @@
Now we can create a QDataStream object, passing the socket to
QDataStream's constructor, and as in the other client examples we set
- the stream protocol version to QDataStream::Qt_4_0.
+ the stream protocol version to QDataStream::Qt_6_5.
\snippet blockingfortuneclient/fortunethread.cpp 12
@@ -123,7 +125,7 @@
The final part of our loop is that we acquire the mutex so that we can
safely read from our member data. We then let the thread go to sleep by
calling QWaitCondition::wait(). At this point, we can go back to
- requestNewFortune() and look closed at the call to wakeOne():
+ requestNewFortune() and look closely at the call to wakeOne():
\snippet blockingfortuneclient/fortunethread.cpp 1
\dots
@@ -169,5 +171,5 @@
Here, we simply display the fortune we received as the argument.
- \sa {Fortune Client Example}, {Fortune Server Example}
+ \sa {Fortune Client}, {Fortune Server}
*/
diff --git a/examples/network/doc/src/broadcastreceiver.qdoc b/examples/network/doc/src/broadcastreceiver.qdoc
index 0a0531dd9e..cb134c699d 100644
--- a/examples/network/doc/src/broadcastreceiver.qdoc
+++ b/examples/network/doc/src/broadcastreceiver.qdoc
@@ -3,7 +3,9 @@
/*!
\example broadcastreceiver
- \title Broadcast Receiver Example
+ \title Broadcast Receiver
+ \examplecategory {Networking}
+ \meta tags {network,broadcast,udp}
\ingroup examples-network
\brief Demonstrates how to receive information broadcasted over a local network.
diff --git a/examples/network/doc/src/broadcastsender.qdoc b/examples/network/doc/src/broadcastsender.qdoc
index 675482c6d2..d02b179b77 100644
--- a/examples/network/doc/src/broadcastsender.qdoc
+++ b/examples/network/doc/src/broadcastsender.qdoc
@@ -3,7 +3,9 @@
/*!
\example broadcastsender
- \title Broadcast Sender Example
+ \title Broadcast Sender
+ \examplecategory {Networking}
+ \meta tags {network,broadcast,udp}
\ingroup examples-network
\brief Demonstrates how to broadcast information to multiple clients on a local network.
diff --git a/examples/network/doc/src/dnslookup.qdoc b/examples/network/doc/src/dnslookup.qdoc
new file mode 100644
index 0000000000..0a5a69f70a
--- /dev/null
+++ b/examples/network/doc/src/dnslookup.qdoc
@@ -0,0 +1,17 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example dnslookup
+ \title DNS lookup
+ \examplecategory {Networking}
+ \meta tags {network,dns,command line parser,command line,console}
+ \ingroup examples-network
+ \brief Demonstrates how to lookup a host name using QDnsLookup.
+
+ This example uses QDnsLookup to demonstrate how to look up a host
+ name and print the results on the command line. As well as how you can
+ use QCommandLineParser to parse command line arguments.
+
+ \image dnslookup-example.webp
+*/
diff --git a/examples/network/doc/src/fortuneclient.qdoc b/examples/network/doc/src/fortuneclient.qdoc
index 2e5c976ecc..054937e893 100644
--- a/examples/network/doc/src/fortuneclient.qdoc
+++ b/examples/network/doc/src/fortuneclient.qdoc
@@ -3,7 +3,9 @@
/*!
\example fortuneclient
- \title Fortune Client Example
+ \title Fortune Client
+ \examplecategory {Networking}
+ \meta tags {tcp,network}
\ingroup examples-network
\brief Demonstrates how to create a client for a network service.
@@ -38,7 +40,7 @@
\endlist
In this example, we will demonstrate the asynchronous approach. The
- \l{blockingfortuneclient}{Blocking Fortune Client Example}
+ \l{blockingfortuneclient}{Blocking Fortune Client} example
illustrates the synchronous approach.
Our class contains some data and a few private slots:
@@ -59,7 +61,7 @@
The protocol is based on QDataStream, so we set the stream device to the
newly created socket. We then explicitly set the protocol version of the
- stream to QDataStream::Qt_4_0 to ensure that we're using the same version
+ stream to QDataStream::Qt_6_5 to ensure that we're using the same version
as the fortune server, no matter which version of Qt the client and
server use.
@@ -132,5 +134,5 @@
After a successful read transaction, we call QLabel::setText() to display
the fortune.
- \sa {Fortune Server Example}, {Blocking Fortune Client Example}
+ \sa {Fortune Server}, {Blocking Fortune Client}
*/
diff --git a/examples/network/doc/src/fortuneserver.qdoc b/examples/network/doc/src/fortuneserver.qdoc
index a24804ffda..1973f372ce 100644
--- a/examples/network/doc/src/fortuneserver.qdoc
+++ b/examples/network/doc/src/fortuneserver.qdoc
@@ -3,13 +3,15 @@
/*!
\example fortuneserver
- \title Fortune Server Example
+ \title Fortune Server
+ \examplecategory {Networking}
+ \meta tags {tcp,network,server}
\ingroup examples-network
\brief Demonstrates how to create a server for a network service.
This example is intended to be run alongside the
\l{fortuneclient}{Fortune Client} example or the
- \l{blockingfortuneclient}{Blocking Fortune Client Example}.
+ \l{blockingfortuneclient}{Blocking Fortune Client} example.
\image fortuneserver-example.png Screenshot of the Fortune Server example
@@ -48,7 +50,7 @@
to the connecting socket. This is a common way to transfer binary data
using QTcpSocket. First we create a QByteArray and a QDataStream object,
passing the bytearray to QDataStream's constructor. We then explicitly set
- the protocol version of QDataStream to QDataStream::Qt_4_0 to ensure that
+ the protocol version of QDataStream to QDataStream::Qt_5_10 to ensure that
we can communicate with clients from future versions of Qt (see
QDataStream::setVersion()). We continue by streaming in a random fortune.
@@ -69,5 +71,5 @@
will then close, which in turn will cause QObject::deleteLater() to delete
it.
- \sa {Fortune Client Example}, {Threaded Fortune Server Example}
+ \sa {Fortune Client}, {Threaded Fortune Server}
*/
diff --git a/examples/network/doc/src/googlesuggest.qdoc b/examples/network/doc/src/googlesuggest.qdoc
deleted file mode 100644
index 0cd1b6d868..0000000000
--- a/examples/network/doc/src/googlesuggest.qdoc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example googlesuggest
- \title Google Suggest Example
- \ingroup examples-network
- \brief Obtains the list of search recommendations by the Google search engine.
-
- The example uses the QNetworkAccessManager to obtain the list of search
- recommendations by Google as the user types into a QLineEdit.
-
- \image googlesuggest-example.png
-
- The application makes use of the \c get function in
- QNetworkAccessManager to post a request and obtain the result of the search
- query sent to the Google search engine. The results returned are listed as
- clickable links appearing below the search box as a drop-down menu.
-
- The widget is built up by a QLineEdit as the search box, and a QTreeView
- used as a popup menu below the search box.
-
- \section1 GSuggestCompletion Class Declaration
-
- This class implements an event filter and a number of functions to display
- the search results and to determent when and how to perform the search.
-
- \snippet googlesuggest/googlesuggest.h 1
-
- The class connects to a QLineEdit and uses a QTreeWidget to display the
- results. A QTimer controls the start of the network requests that are
- executed using a QNetworkAccessManager.
-
- \section1 GSuggestCompletion Class Implementation
-
- We start by defining a constant containing the URL to be used in the Google
- queries. This is the basis for the query. The letters typed into the search
- box will be added to the query to perform the search itself.
-
- \snippet googlesuggest/googlesuggest.cpp 1
-
- In the constructor, we set the parent of this GSuggestCompletion instance
- to be the QLineEdit passed in. For simplicity, the QLineEdit is also stored
- in the explicit \c editor member variable.
-
- We then create a QTreeWidget as a toplevel widget and configure the various
- properties to give it the look of a popup widget. The widget is populated
- with the results by Google Suggest API request.
-
- Furthermore, we install the GSuggestCompletion instance as an event filter
- on the QTreeWidget, and connect the \c itemClicked() signal with the \c
- doneCompletion() slot.
-
- A single-shot QTimer is used to start the request when the user has stopped
- typing for 500 ms.
-
- Finally, we connect the networkManagers \c finished() signal with the \c
- handleNetworkData() slot to handle the incoming data.
-
- \snippet googlesuggest/googlesuggest.cpp 2
-
- Since the QTreeWidget popup has been instantiated as a toplevel widget, the
- destructor has to delete it explicitly from memory to avoid a memory leak.
-
- \snippet googlesuggest/googlesuggest.cpp 3
-
- The event filter handles mouse press and key press events that are
- delivered to the popup. For mouse press events we just hide the popup and
- return focus to the editor widget, and then return true to prevent further
- event processing.
-
- Key event handling is implemented so that Enter and Return execute the
- selected link, while the Escape key hides the popup. Since we want to be
- able to navigate the list of suggestions using the different navigation
- keys on the keyboard we let Qt continue regular event processing for those
- by returning false from the eventFilter reimplementation.
-
- For all other keys, the event will be passed on to the editor widget and the
- popup is hidden. This way the user's typing will not be interrupted by the
- popping up of the completion list.
-
- \snippet googlesuggest/googlesuggest.cpp 4
-
- The \c showCompletion() function populates the QTreeWidget with the results
- returned from the query. It takes a QStringList of the suggested search
- terms.
-
- \snippet googlesuggest/googlesuggest.cpp 5
-
- A QTreeWidgetItem is created for each index in the list and inserted into
- the QTreeWidget. Finally, we adjust position and size of the popup to make
- sure that it pops up in the correct position below the editor, and show it.
-
- The \c doneCompletion() function, which is called by the event filter when
- either Enter or Return keys are pressed, stops the timer to prevent further
- requests and passes the text of the selected item to the editor. We then
- make the \c editor QLineEdit emit the returnPressed() signal, to which the
- application can connect to open the respective web page.
-
- \snippet googlesuggest/googlesuggest.cpp 6
-
- The \c autoSuggest() slot is called when the timer times out, and uses the
- text in the editor to build the complete search query. The query is then
- passed to the QNetworkAccessManager's \c get() function to start the
- request.
-
- \snippet googlesuggest/googlesuggest.cpp 7
-
- The function \c preventSuggest() stops the timer to prevent further
- requests from being started.
-
- \snippet googlesuggest/googlesuggest.cpp 8
-
- When the network request is finished, the QNetworkAccessManager delivers the
- data received from the server through the networkReply object.
-
- \snippet googlesuggest/googlesuggest.cpp 9
-
- To extract the data from the reply we use the \c readAll() function, which
- is inherited from QIODevice and returns a QByteArray. Since this data is
- encoded in XML we can use a QXmlStreamReader to traverse the data and
- extract the search result as QStrings, which we can stream into two
- QStringLists used to populate the popup.
-
- Finally, we schedule the QNetworkReply object for deletion using the \c
- deleteLater function.
-
- \section1 SearchBox Class Declaration
-
- The SearchBox class inherits QLineEdit and adds the protected slot \c
- doSearch().
-
- A \c GSuggestCompletion member provides the SearchBox with the request
- functionality and the suggestions returned from the Google search engine.
-
- \snippet googlesuggest/searchbox.h 1
-
- \section1 SearchBox Class Implementation
-
- The search box constructor instantiates the GSuggestCompletion object and
- connects the returnPressed() signal to the doSearch() slot.
-
- \snippet googlesuggest/searchbox.cpp 1
-
- The function \c doSearch() stops the completer from sending any further
- queries to the search engine.
-
- Further, the function extracts the selected search phrase and opens it
- in the default web browser using QDesktopServices.
-
- \snippet googlesuggest/searchbox.cpp 2
-
-*/
diff --git a/examples/network/doc/src/http.qdoc b/examples/network/doc/src/http.qdoc
index 0776b13a00..c155997394 100644
--- a/examples/network/doc/src/http.qdoc
+++ b/examples/network/doc/src/http.qdoc
@@ -3,14 +3,17 @@
/*!
\example http
- \title HTTP Example
+ \examplecategory {Networking}
+ \examplecategory {Web Technologies}
+ \meta tags {http,network,https,proxy}
+ \title HTTP Client
\ingroup examples-network
\brief Demonstrates a simple HTTP client.
This example demonstrates how a simple HTTP client can fetch files
from remote hosts.
- \image http-example.png
+ \image http-example.webp
The main work of this example is done in the HttpWindow class.
Thus we will focus on that.
diff --git a/examples/network/doc/src/loopback.qdoc b/examples/network/doc/src/loopback.qdoc
deleted file mode 100644
index 657e2959bf..0000000000
--- a/examples/network/doc/src/loopback.qdoc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example loopback
- \title Loopback Example
- \ingroup examples-network
- \brief Demonstrates the client-server communication on a local host.
-
- The example demonstrates how the clients and servers on a local host
- communicate with each other.
-
- \image loopback-example.png
-*/
diff --git a/examples/network/doc/src/multicastreceiver.qdoc b/examples/network/doc/src/multicastreceiver.qdoc
index 0003f04284..16c7235c17 100644
--- a/examples/network/doc/src/multicastreceiver.qdoc
+++ b/examples/network/doc/src/multicastreceiver.qdoc
@@ -3,10 +3,12 @@
/*!
\example multicastreceiver
- \title Multicast Receiver Example
+ \title Multicast Receiver
+ \examplecategory {Networking}
+ \meta tags {network,multicast,ipv6,ipv4,udp}
\ingroup examples-network
\brief Demonstrates how to receive information sent to a multicast group.
- This example demonstrates how to receive messages sent to a multicast group
- \image multicastreceiver-example.png
+ This example demonstrates how to receive messages sent to a multicast group.
+ \image multicastreceiver-example.webp
*/
diff --git a/examples/network/doc/src/multicastsender.qdoc b/examples/network/doc/src/multicastsender.qdoc
index c5305f271f..26e0d951fe 100644
--- a/examples/network/doc/src/multicastsender.qdoc
+++ b/examples/network/doc/src/multicastsender.qdoc
@@ -3,12 +3,14 @@
/*!
\example multicastsender
- \title Multicast Sender Example
+ \title Multicast Sender
+ \examplecategory {Networking}
+ \meta tags {network,multicast,ipv6,ipv4,udp}
\ingroup examples-network
\brief Demonstrates how to send messages to a multicast group.
This example demonstrates how to send messages to the clients of a
multicast group.
- \image multicastsender-example.png
+ \image multicastsender-example.webp
*/
diff --git a/examples/network/doc/src/multistreamclient.qdoc b/examples/network/doc/src/multistreamclient.qdoc
new file mode 100644
index 0000000000..bb70eac741
--- /dev/null
+++ b/examples/network/doc/src/multistreamclient.qdoc
@@ -0,0 +1,15 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example multistreamclient
+ \title Multi-stream Client
+ \examplecategory {Networking}
+ \meta tags {network,sctp}
+ \ingroup examples-network
+ \brief Demonstrates how to use SCTP on the client side.
+
+ This example demonstrates how to use SCTP, with multiple channels,
+ to interact with other clients through a server.
+ \image multi-stream-client-example.webp
+*/
diff --git a/examples/network/doc/src/multistreamserver.qdoc b/examples/network/doc/src/multistreamserver.qdoc
new file mode 100644
index 0000000000..9e498be3c9
--- /dev/null
+++ b/examples/network/doc/src/multistreamserver.qdoc
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example multistreamserver
+ \title Multi-stream Server
+ \examplecategory {Networking}
+ \meta tags {network,sctp}
+ \ingroup examples-network
+ \brief Demonstrates how to use SCTP on the server side.
+
+ This example demonstrates how to use SCTP, with multiple channels,
+ on the server side, receiving multiple connections and sending
+ messages to connected clients.
+ \image multi-stream-server-example.webp
+*/
diff --git a/examples/network/doc/src/network-chat.qdoc b/examples/network/doc/src/network-chat.qdoc
index 29ba0652bf..6a8f0024e3 100644
--- a/examples/network/doc/src/network-chat.qdoc
+++ b/examples/network/doc/src/network-chat.qdoc
@@ -3,12 +3,14 @@
/*!
\example network-chat
- \title Network Chat Example
+ \title Network Chat
\ingroup examples-network
+ \examplecategory {Networking}
+ \meta tag {network,serialization}
\brief Demonstrates a stateful peer-to-peer Chat client.
This example uses broadcasting with QUdpSocket and QNetworkInterface to
discover its peers.
- \image network-chat-example.png
+ \image network-chat-example.webp
*/
diff --git a/examples/network/doc/src/network-download.qdoc b/examples/network/doc/src/network-download.qdoc
deleted file mode 100644
index 807cebada2..0000000000
--- a/examples/network/doc/src/network-download.qdoc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example download
- \title Network Download Example
- \brief Demonstrates how to use networking APIs for multiple downloads.
- \ingroup examples-network
-
- The Network Download example shows how to perform multiple downloads in
- parallel using the QNetworkAccessManager class.
-
- This example is designed to be run from the command-line.
-
- The \l{Network Download Manager Example} implements a more complex system
- that places files in a queue for sequential downloading.
-*/
diff --git a/examples/network/doc/src/network-downloadmanager.qdoc b/examples/network/doc/src/network-downloadmanager.qdoc
deleted file mode 100644
index 6f5606b016..0000000000
--- a/examples/network/doc/src/network-downloadmanager.qdoc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example downloadmanager
- \title Network Download Manager Example
- \brief Demonstrates how to use the networking APIs for multiple downloads.
- \ingroup examples-network
-
- The Network Download example shows how to implement a queue for multiple
- downloads using the QNetworkAccessManager class.
-
- This example is designed to be run from the command-line.
-
- See the \l{Network Download Example} for a simpler version of this example
- that obtains multiple files in parallel.
-*/
diff --git a/examples/network/doc/src/rsslisting.qdoc b/examples/network/doc/src/rsslisting.qdoc
new file mode 100644
index 0000000000..a1e91932f6
--- /dev/null
+++ b/examples/network/doc/src/rsslisting.qdoc
@@ -0,0 +1,129 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example rsslisting
+ \examplecategory {Networking}
+ \meta tag {serialization}
+ \title A minimal RSS listing application
+
+ \brief A demonstration of how to fetch and display a network resource.
+
+ This example shows how to fetch a resource the user has requested and
+ display data contained in the response, illustrated by an RSS listing
+ application. (RDF Site Summary, or Really Simple Syndication, is a standard
+ format for communicating updates to web sites. See
+ https://www.rssboard.org/rss-specification for details.) The user inferface
+ in the illustration is simple, as the focus of this example is on how to use
+ networking, but naturally a more sophisticated interface would be wanted for
+ a serious RSS reader.
+
+ The example also illustrates how to do asynchronous parsing of data as it is
+ received, preserving state in member variables so that an incremental parser
+ can consume chunks of data as they arrive over the network. Constituents of
+ the parsed content may start in one chunk of data but not be completed until
+ a later chunk, requiring the parser to retain state between calls.
+
+ \image rsslisting.png
+
+ The main program is fairly minimal. It simply instantiates a \l QApplication
+ and the \c RSSListing widget, shows the latter and hands over control to the
+ former. For the sake of illustration, it gives the widget the Qt blog's URL
+ as default value for the resource to check.
+
+ \snippet rsslisting/main.cpp 0
+
+ \section1 The RSSListing class
+
+ \snippet rsslisting/rsslisting.h 0
+
+ The widget itself provides a simple user interface for specifying the URL to
+ fetch and, once available updates are displayed, controlling the downloading
+ of updated items. A \l QLineEdit provides for input of the URL, and a
+ \l QTreeWidget for display of the results once fetched.
+
+ The widget downloads and parses the RSS (a form of XML) asynchronously,
+ feeding the data to an XML reader as it arrives. This supports reading of
+ very large data sources. Because the data is streamed from the network
+ through the XML reader, there is no need to retain the full text of the XML
+ in memory. In other context, a similar approach can allow the user to
+ interrupt such incremental loading.
+
+ \section2 Construction
+
+ \snippet rsslisting/rsslisting.cpp setup
+
+ The constructor sets up the assorted components of the widget and connects
+ their various signals to the slots it shall use to handle them.
+
+ The user interface consists of a line edit, a push button, and a list view
+ widget. The line edit is used for entering the URL to fetch; the push button
+ starts the process of fetching updates. The line edit is empty by default,
+ but the constructor's caller can override that, as our \c main() has done.
+ In any case, the user can replace the default with the URL of another RSS
+ feed.
+
+ The list view shows the updated items reported in the RSS feed.
+ Double-clicking on one of these sends its URL to the user's browser or other
+ user agent using \l QDesktopServices::openUrl().
+
+ \section2 The slots
+
+ \snippet rsslisting/rsslisting.cpp slots
+
+ All slots are kept simple by delegating any hard work to private methods.
+
+ When the user completes input of a URL, either by clicking the "Fetch"
+ button or by pressing the return key in the line edit, the \c fetch() slot
+ disables the "Fetch" button and disables further editing of the line edit.
+ It clears the display of available updates and delegates to \c get() the
+ initiating of an HTTP GET request.
+
+ When data is received, the network reply triggers its \l {QNetworkReply::}
+ {readyRead()} signal, which \c get() connects to the \c consumeData()
+ slot. This checks the response got a successful status code and, if it did,
+ calls \c parseXml() to consume the data.
+
+ If the network reply gets an error, this is delivered to the \c error()
+ slot, which reports the error, clears the XML stream reader then disconnects
+ from the reply and deletes it.
+
+ On completion (whether successful or otherwise) of a network reply, the \c
+ finished() slot restores the UI to be ready to accept a new URL to fetch by
+ re-enabling the line edit and "Fetch" button.
+
+ \section2 The get() method
+
+ \snippet rsslisting/rsslisting.cpp get
+
+ The private \c get() method is used by the \c fetch() slot to initiate an
+ HTTP GET request. It first clears the XML stream reader and, if a reply is
+ currently active, disconnects and deletes it. If the URL it has been passed
+ is valid, it asks the network access manager to GET it. It connects its
+ relevant slots to signals of the resulting reply (if any) and sets up its
+ XML stream reader to read data from the reply - a network reply object is
+ also a \c QIODevice, from which data can be read.
+
+ \section2 The parseXml() method
+
+ \snippet rsslisting/rsslisting.cpp parse
+
+ When data is received, and thus made available to the XML stream reader, \c
+ parseXml() reads from the XML stream, checking for \c item elements and,
+ within them, \c title and \c link elements. It will use the \c{rss:about}
+ attribute of an \c item as URL in the Link column of the tree-view, failing
+ that the content of its \c link element; and it uses the content of the \c
+ title element in the Title column of the tree-view. As each \c item element
+ closes, its details are turned into a new row in the tree widget, with the
+ extracted title and URL in the Title and Link columns.
+
+ The variables that keep track of the parsing state - \c linkString, \c
+ titleString and \c currentTag - are member variables of the \c RSSListing
+ class, even though they are only accessed from this method, because this
+ method may be called repeatedly, as new data arrives, and one chunk of
+ received data may start an element that isn't completed until a later chunk
+ arrives. This enables the parser to operate asynchronously as the data
+ arrives, instead of having to wait until all the data has arrived.
+
+ \sa QNetworkReply, QXmlStreamReader
+*/
diff --git a/examples/network/doc/src/securesocketclient.qdoc b/examples/network/doc/src/securesocketclient.qdoc
index b0272ca1f0..7ff3ae6da5 100644
--- a/examples/network/doc/src/securesocketclient.qdoc
+++ b/examples/network/doc/src/securesocketclient.qdoc
@@ -3,7 +3,9 @@
/*!
\example securesocketclient
- \title Secure Socket Client Example
+ \title Secure Socket Client
+ \examplecategory {Networking}
+ \meta tags {tcp,network,tls,ssl}
\ingroup examples-network
\brief Demonstrates how to communicate over an encrypted (SSL) connection.
@@ -11,6 +13,5 @@
encrypted connection, deal with authenticity problems, and display security
and certificate information.
- \image securesocketclient.png
- \image securesocketclient2.png
+ \image securesocketclient-example.webp
*/
diff --git a/examples/network/doc/src/secureudpclient.qdoc b/examples/network/doc/src/secureudpclient.qdoc
index 0f673b0a66..b7a51c0814 100644
--- a/examples/network/doc/src/secureudpclient.qdoc
+++ b/examples/network/doc/src/secureudpclient.qdoc
@@ -4,6 +4,7 @@
/*!
\example secureudpclient
\title DTLS client
+ \examplecategory {Networking}
\ingroup examples-network
\brief This example demonstrates how to implement client-side DTLS connections.
diff --git a/examples/network/doc/src/secureudpserver.qdoc b/examples/network/doc/src/secureudpserver.qdoc
index f98ee74164..3d224d91bc 100644
--- a/examples/network/doc/src/secureudpserver.qdoc
+++ b/examples/network/doc/src/secureudpserver.qdoc
@@ -4,6 +4,7 @@
/*!
\example secureudpserver
\title DTLS server
+ \examplecategory {Networking}
\ingroup examples-network
\brief This examples demonstrates how to implement a simple DTLS server.
diff --git a/examples/network/doc/src/threadedfortuneserver.qdoc b/examples/network/doc/src/threadedfortuneserver.qdoc
index 86de36a4ef..51198061e6 100644
--- a/examples/network/doc/src/threadedfortuneserver.qdoc
+++ b/examples/network/doc/src/threadedfortuneserver.qdoc
@@ -3,7 +3,9 @@
/*!
\example threadedfortuneserver
- \title Threaded Fortune Server Example
+ \title Threaded Fortune Server
+ \examplecategory {Networking}
+ \meta tags {tcp,network,threading,server,synchronous-io}
\ingroup examples-network
\brief The Threaded Fortune Server example shows how to create a server for a
@@ -79,6 +81,5 @@
the socket has disconnected. Because we are running in a separate thread,
the GUI will remain responsive.
- \sa {Fortune Server Example}, {Fortune Client Example}, {Blocking Fortune
- Client Example}
+ \sa {Fortune Server}, {Fortune Client}, {Blocking Fortune Client}
*/
diff --git a/examples/network/doc/src/torrent.qdoc b/examples/network/doc/src/torrent.qdoc
index 301be1863a..124a697293 100644
--- a/examples/network/doc/src/torrent.qdoc
+++ b/examples/network/doc/src/torrent.qdoc
@@ -4,6 +4,7 @@
/*!
\example torrent
\title Torrent Example
+ \examplecategory {Networking}
\ingroup examples-network
\brief Demonstrates complex TCP/IP operations.
diff --git a/examples/network/download/CMakeLists.txt b/examples/network/download/CMakeLists.txt
deleted file mode 100644
index fac34ff4ed..0000000000
--- a/examples/network/download/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(download LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/download")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Network)
-
-qt_add_executable(download
- main.cpp
-)
-
-target_link_libraries(download PUBLIC
- Qt::Core
- Qt::Network
-)
-
-install(TARGETS download
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/download/download.pro b/examples/network/download/download.pro
deleted file mode 100644
index 63d80a0e7c..0000000000
--- a/examples/network/download/download.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT = core network
-CONFIG += cmdline
-
-SOURCES += main.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/download
-INSTALLS += target
diff --git a/examples/network/download/main.cpp b/examples/network/download/main.cpp
deleted file mode 100644
index 32fccbad9c..0000000000
--- a/examples/network/download/main.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QtCore>
-#include <QtNetwork>
-
-#include <cstdio>
-
-QT_BEGIN_NAMESPACE
-class QSslError;
-QT_END_NAMESPACE
-
-using namespace std;
-
-class DownloadManager: public QObject
-{
- Q_OBJECT
- QNetworkAccessManager manager;
- QList<QNetworkReply *> currentDownloads;
-
-public:
- DownloadManager();
- void doDownload(const QUrl &url);
- static QString saveFileName(const QUrl &url);
- bool saveToDisk(const QString &filename, QIODevice *data);
- static bool isHttpRedirect(QNetworkReply *reply);
-
-public slots:
- void execute();
- void downloadFinished(QNetworkReply *reply);
- void sslErrors(const QList<QSslError> &errors);
-};
-
-DownloadManager::DownloadManager()
-{
- connect(&manager, &QNetworkAccessManager::finished,
- this, &DownloadManager::downloadFinished);
-}
-
-void DownloadManager::doDownload(const QUrl &url)
-{
- QNetworkRequest request(url);
- QNetworkReply *reply = manager.get(request);
-
-#if QT_CONFIG(ssl)
- connect(reply, &QNetworkReply::sslErrors,
- this, &DownloadManager::sslErrors);
-#endif
-
- currentDownloads.append(reply);
-}
-
-QString DownloadManager::saveFileName(const QUrl &url)
-{
- QString path = url.path();
- QString basename = QFileInfo(path).fileName();
-
- if (basename.isEmpty())
- basename = "download";
-
- if (QFile::exists(basename)) {
- // already exists, don't overwrite
- int i = 0;
- basename += '.';
- while (QFile::exists(basename + QString::number(i)))
- ++i;
-
- basename += QString::number(i);
- }
-
- return basename;
-}
-
-bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
-{
- QFile file(filename);
- if (!file.open(QIODevice::WriteOnly)) {
- fprintf(stderr, "Could not open %s for writing: %s\n",
- qPrintable(filename),
- qPrintable(file.errorString()));
- return false;
- }
-
- file.write(data->readAll());
- file.close();
-
- return true;
-}
-
-bool DownloadManager::isHttpRedirect(QNetworkReply *reply)
-{
- int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- return statusCode == 301 || statusCode == 302 || statusCode == 303
- || statusCode == 305 || statusCode == 307 || statusCode == 308;
-}
-
-void DownloadManager::execute()
-{
- QStringList args = QCoreApplication::instance()->arguments();
- args.takeFirst(); // skip the first argument, which is the program's name
- if (args.isEmpty()) {
- printf("Qt Download example - downloads all URLs in parallel\n"
- "Usage: download url1 [url2... urlN]\n"
- "\n"
- "Downloads the URLs passed in the command-line to the local directory\n"
- "If the target file already exists, a .0, .1, .2, etc. is appended to\n"
- "differentiate.\n");
- QCoreApplication::instance()->quit();
- return;
- }
-
- for (const QString &arg : qAsConst(args)) {
- QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());
- doDownload(url);
- }
-}
-
-void DownloadManager::sslErrors(const QList<QSslError> &sslErrors)
-{
-#if QT_CONFIG(ssl)
- for (const QSslError &error : sslErrors)
- fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
-#else
- Q_UNUSED(sslErrors);
-#endif
-}
-
-void DownloadManager::downloadFinished(QNetworkReply *reply)
-{
- QUrl url = reply->url();
- if (reply->error()) {
- fprintf(stderr, "Download of %s failed: %s\n",
- url.toEncoded().constData(),
- qPrintable(reply->errorString()));
- } else {
- if (isHttpRedirect(reply)) {
- fputs("Request was redirected.\n", stderr);
- } else {
- QString filename = saveFileName(url);
- if (saveToDisk(filename, reply)) {
- printf("Download of %s succeeded (saved to %s)\n",
- url.toEncoded().constData(), qPrintable(filename));
- }
- }
- }
-
- currentDownloads.removeAll(reply);
- reply->deleteLater();
-
- if (currentDownloads.isEmpty()) {
- // all downloads finished
- QCoreApplication::instance()->quit();
- }
-}
-
-int main(int argc, char **argv)
-{
- QCoreApplication app(argc, argv);
-
- DownloadManager manager;
- QTimer::singleShot(0, &manager, SLOT(execute()));
-
- app.exec();
-}
-
-#include "main.moc"
diff --git a/examples/network/downloadmanager/CMakeLists.txt b/examples/network/downloadmanager/CMakeLists.txt
deleted file mode 100644
index 469940bf1a..0000000000
--- a/examples/network/downloadmanager/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(downloadmanager LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/downloadmanager")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Network)
-
-qt_add_executable(downloadmanager
- downloadmanager.cpp downloadmanager.h
- main.cpp
- textprogressbar.cpp textprogressbar.h
-)
-
-target_link_libraries(downloadmanager PUBLIC
- Qt::Core
- Qt::Network
-)
-
-install(TARGETS downloadmanager
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/downloadmanager/downloadmanager.cpp b/examples/network/downloadmanager/downloadmanager.cpp
deleted file mode 100644
index ffb7362113..0000000000
--- a/examples/network/downloadmanager/downloadmanager.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "downloadmanager.h"
-
-#include <QTextStream>
-
-#include <cstdio>
-
-using namespace std;
-
-DownloadManager::DownloadManager(QObject *parent)
- : QObject(parent)
-{
-}
-
-void DownloadManager::append(const QStringList &urls)
-{
- for (const QString &urlAsString : urls)
- append(QUrl::fromEncoded(urlAsString.toLocal8Bit()));
-
- if (downloadQueue.isEmpty())
- QTimer::singleShot(0, this, &DownloadManager::finished);
-}
-
-void DownloadManager::append(const QUrl &url)
-{
- if (downloadQueue.isEmpty())
- QTimer::singleShot(0, this, &DownloadManager::startNextDownload);
-
- downloadQueue.enqueue(url);
- ++totalCount;
-}
-
-QString DownloadManager::saveFileName(const QUrl &url)
-{
- QString path = url.path();
- QString basename = QFileInfo(path).fileName();
-
- if (basename.isEmpty())
- basename = "download";
-
- if (QFile::exists(basename)) {
- // already exists, don't overwrite
- int i = 0;
- basename += '.';
- while (QFile::exists(basename + QString::number(i)))
- ++i;
-
- basename += QString::number(i);
- }
-
- return basename;
-}
-
-void DownloadManager::startNextDownload()
-{
- if (downloadQueue.isEmpty()) {
- printf("%d/%d files downloaded successfully\n", downloadedCount, totalCount);
- emit finished();
- return;
- }
-
- QUrl url = downloadQueue.dequeue();
-
- QString filename = saveFileName(url);
- output.setFileName(filename);
- if (!output.open(QIODevice::WriteOnly)) {
- fprintf(stderr, "Problem opening save file '%s' for download '%s': %s\n",
- qPrintable(filename), url.toEncoded().constData(),
- qPrintable(output.errorString()));
-
- startNextDownload();
- return; // skip this download
- }
-
- QNetworkRequest request(url);
- currentDownload = manager.get(request);
- connect(currentDownload, &QNetworkReply::downloadProgress,
- this, &DownloadManager::downloadProgress);
- connect(currentDownload, &QNetworkReply::finished,
- this, &DownloadManager::downloadFinished);
- connect(currentDownload, &QNetworkReply::readyRead,
- this, &DownloadManager::downloadReadyRead);
-
- // prepare the output
- printf("Downloading %s...\n", url.toEncoded().constData());
- downloadTimer.start();
-}
-
-void DownloadManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
-{
- progressBar.setStatus(bytesReceived, bytesTotal);
-
- // calculate the download speed
- double speed = bytesReceived * 1000.0 / downloadTimer.elapsed();
- QString unit;
- if (speed < 1024) {
- unit = "bytes/sec";
- } else if (speed < 1024*1024) {
- speed /= 1024;
- unit = "kB/s";
- } else {
- speed /= 1024*1024;
- unit = "MB/s";
- }
-
- progressBar.setMessage(QString::fromLatin1("%1 %2")
- .arg(speed, 3, 'f', 1).arg(unit));
- progressBar.update();
-}
-
-void DownloadManager::downloadFinished()
-{
- progressBar.clear();
- output.close();
-
- if (currentDownload->error()) {
- // download failed
- fprintf(stderr, "Failed: %s\n", qPrintable(currentDownload->errorString()));
- output.remove();
- } else {
- // let's check if it was actually a redirect
- if (isHttpRedirect()) {
- reportRedirect();
- output.remove();
- } else {
- printf("Succeeded.\n");
- ++downloadedCount;
- }
- }
-
- currentDownload->deleteLater();
- startNextDownload();
-}
-
-void DownloadManager::downloadReadyRead()
-{
- output.write(currentDownload->readAll());
-}
-
-bool DownloadManager::isHttpRedirect() const
-{
- int statusCode = currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- return statusCode == 301 || statusCode == 302 || statusCode == 303
- || statusCode == 305 || statusCode == 307 || statusCode == 308;
-}
-
-void DownloadManager::reportRedirect()
-{
- int statusCode = currentDownload->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- QUrl requestUrl = currentDownload->request().url();
- QTextStream(stderr) << "Request: " << requestUrl.toDisplayString()
- << " was redirected with code: " << statusCode
- << '\n';
-
- QVariant target = currentDownload->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (!target.isValid())
- return;
- QUrl redirectUrl = target.toUrl();
- if (redirectUrl.isRelative())
- redirectUrl = requestUrl.resolved(redirectUrl);
- QTextStream(stderr) << "Redirected to: " << redirectUrl.toDisplayString()
- << '\n';
-}
diff --git a/examples/network/downloadmanager/downloadmanager.h b/examples/network/downloadmanager/downloadmanager.h
deleted file mode 100644
index 4293bce26b..0000000000
--- a/examples/network/downloadmanager/downloadmanager.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef DOWNLOADMANAGER_H
-#define DOWNLOADMANAGER_H
-
-#include <QtNetwork>
-#include <QtCore>
-
-#include "textprogressbar.h"
-
-class DownloadManager: public QObject
-{
- Q_OBJECT
-public:
- explicit DownloadManager(QObject *parent = nullptr);
-
- void append(const QUrl &url);
- void append(const QStringList &urls);
- static QString saveFileName(const QUrl &url);
-
-signals:
- void finished();
-
-private slots:
- void startNextDownload();
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
- void downloadFinished();
- void downloadReadyRead();
-
-private:
- bool isHttpRedirect() const;
- void reportRedirect();
-
- QNetworkAccessManager manager;
- QQueue<QUrl> downloadQueue;
- QNetworkReply *currentDownload = nullptr;
- QFile output;
- QElapsedTimer downloadTimer;
- TextProgressBar progressBar;
-
- int downloadedCount = 0;
- int totalCount = 0;
-};
-
-#endif
diff --git a/examples/network/downloadmanager/downloadmanager.pro b/examples/network/downloadmanager/downloadmanager.pro
deleted file mode 100644
index cd1a977e5d..0000000000
--- a/examples/network/downloadmanager/downloadmanager.pro
+++ /dev/null
@@ -1,17 +0,0 @@
-QT = core network
-CONFIG += cmdline
-
-HEADERS += downloadmanager.h textprogressbar.h
-SOURCES += downloadmanager.cpp main.cpp textprogressbar.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/downloadmanager
-INSTALLS += target
-
-OTHER_FILES += \
- debian/changelog \
- debian/compat \
- debian/control \
- debian/copyright \
- debian/README \
- debian/rules
diff --git a/examples/network/downloadmanager/main.cpp b/examples/network/downloadmanager/main.cpp
deleted file mode 100644
index 6b99e38c63..0000000000
--- a/examples/network/downloadmanager/main.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QCoreApplication>
-#include <QStringList>
-
-#include "downloadmanager.h"
-
-#include <cstdio>
-
-int main(int argc, char **argv)
-{
- using namespace std;
-
- QCoreApplication app(argc, argv);
- QStringList arguments = app.arguments();
- arguments.takeFirst(); // remove the first argument, which is the program's name
-
- if (arguments.isEmpty()) {
- printf("Qt Download example\n"
- "Usage: downloadmanager url1 [url2... urlN]\n"
- "\n"
- "Downloads the URLs passed in the command-line to the local directory\n"
- "If the target file already exists, a .0, .1, .2, etc. is appended to\n"
- "differentiate.\n");
- return 0;
- }
-
- DownloadManager manager;
- manager.append(arguments);
-
- QObject::connect(&manager, &DownloadManager::finished,
- &app, &QCoreApplication::quit);
- app.exec();
-}
diff --git a/examples/network/downloadmanager/textprogressbar.cpp b/examples/network/downloadmanager/textprogressbar.cpp
deleted file mode 100644
index 824b403cfc..0000000000
--- a/examples/network/downloadmanager/textprogressbar.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "textprogressbar.h"
-
-#include <QByteArray>
-
-#include <cstdio>
-
-using namespace std;
-
-void TextProgressBar::clear()
-{
- printf("\n");
- fflush(stdout);
-
- value = 0;
- maximum = -1;
- iteration = 0;
-}
-
-void TextProgressBar::update()
-{
- ++iteration;
-
- if (maximum > 0) {
- // we know the maximum
- // draw a progress bar
- int percent = value * 100 / maximum;
- int hashes = percent / 2;
-
- QByteArray progressbar(hashes, '#');
- if (percent % 2)
- progressbar += '>';
-
- printf("\r[%-50s] %3d%% %s ",
- progressbar.constData(),
- percent,
- qPrintable(message));
- } else {
- // we don't know the maximum, so we can't draw a progress bar
- int center = (iteration % 48) + 1; // 50 spaces, minus 2
- QByteArray before(qMax(center - 2, 0), ' ');
- QByteArray after(qMin(center + 2, 50), ' ');
-
- printf("\r[%s###%s] %s ",
- before.constData(), after.constData(), qPrintable(message));
- }
-}
-
-void TextProgressBar::setMessage(const QString &m)
-{
- message = m;
-}
-
-void TextProgressBar::setStatus(qint64 val, qint64 max)
-{
- value = val;
- maximum = max;
-}
diff --git a/examples/network/downloadmanager/textprogressbar.h b/examples/network/downloadmanager/textprogressbar.h
deleted file mode 100644
index 60ef0dfddc..0000000000
--- a/examples/network/downloadmanager/textprogressbar.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef TEXTPROGRESSBAR_H
-#define TEXTPROGRESSBAR_H
-
-#include <QString>
-
-class TextProgressBar
-{
-public:
- void clear();
- void update();
- void setMessage(const QString &message);
- void setStatus(qint64 value, qint64 maximum);
-
-private:
- QString message;
- qint64 value = 0;
- qint64 maximum = -1;
- int iteration = 0;
-};
-
-#endif
diff --git a/examples/network/fortuneclient/CMakeLists.txt b/examples/network/fortuneclient/CMakeLists.txt
index 01a8ae4b48..ba55939b37 100644
--- a/examples/network/fortuneclient/CMakeLists.txt
+++ b/examples/network/fortuneclient/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(fortuneclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/fortuneclient")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(fortuneclient
client.cpp client.h
main.cpp
@@ -24,15 +18,22 @@ set_target_properties(fortuneclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(fortuneclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(fortuneclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS fortuneclient
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET fortuneclient
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/fortuneclient/client.cpp b/examples/network/fortuneclient/client.cpp
index 68fbb68a4e..af7efbd9ed 100644
--- a/examples/network/fortuneclient/client.cpp
+++ b/examples/network/fortuneclient/client.cpp
@@ -14,7 +14,6 @@ Client::Client(QWidget *parent)
, getFortuneButton(new QPushButton(tr("Get Fortune")))
, tcpSocket(new QTcpSocket(this))
{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
//! [0]
hostCombo->setEditable(true);
// find out name of this machine
@@ -28,16 +27,16 @@ Client::Client(QWidget *parent)
if (name != QLatin1String("localhost"))
hostCombo->addItem(QString("localhost"));
// find out IP addresses of this machine
- QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// add non-localhost addresses
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (!ipAddressesList.at(i).isLoopback())
- hostCombo->addItem(ipAddressesList.at(i).toString());
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (!entry.isLoopback())
+ hostCombo->addItem(entry.toString());
}
// add localhost addresses
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (ipAddressesList.at(i).isLoopback())
- hostCombo->addItem(ipAddressesList.at(i).toString());
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (entry.isLoopback())
+ hostCombo->addItem(entry.toString());
}
portLineEdit->setValidator(new QIntValidator(1, 65535, this));
@@ -61,7 +60,7 @@ Client::Client(QWidget *parent)
//! [1]
in.setDevice(tcpSocket);
- in.setVersion(QDataStream::Qt_4_0);
+ in.setVersion(QDataStream::Qt_6_5);
//! [1]
connect(hostCombo, &QComboBox::editTextChanged,
diff --git a/examples/network/fortuneserver/CMakeLists.txt b/examples/network/fortuneserver/CMakeLists.txt
index 80f2c74bde..af51db6a5e 100644
--- a/examples/network/fortuneserver/CMakeLists.txt
+++ b/examples/network/fortuneserver/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(fortuneserver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/fortuneserver")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(fortuneserver
main.cpp
server.cpp server.h
@@ -24,15 +18,22 @@ set_target_properties(fortuneserver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(fortuneserver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(fortuneserver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS fortuneserver
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET fortuneserver
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/fortuneserver/server.cpp b/examples/network/fortuneserver/server.cpp
index 3a78429d31..67d6117566 100644
--- a/examples/network/fortuneserver/server.cpp
+++ b/examples/network/fortuneserver/server.cpp
@@ -11,7 +11,6 @@ Server::Server(QWidget *parent)
: QDialog(parent)
, statusLabel(new QLabel)
{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
statusLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
initServer();
@@ -72,12 +71,11 @@ void Server::initServer()
}
//! [0]
QString ipAddress;
- QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
- ipAddressesList.at(i).toIPv4Address()) {
- ipAddress = ipAddressesList.at(i).toString();
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) {
+ ipAddress = entry.toString();
break;
}
}
@@ -96,7 +94,7 @@ void Server::sendFortune()
//! [5]
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
- out.setVersion(QDataStream::Qt_5_10);
+ out.setVersion(QDataStream::Qt_6_5);
out << fortunes[QRandomGenerator::global()->bounded(fortunes.size())];
//! [4] //! [7]
diff --git a/examples/network/googlesuggest/CMakeLists.txt b/examples/network/googlesuggest/CMakeLists.txt
deleted file mode 100644
index 2cad46b8fd..0000000000
--- a/examples/network/googlesuggest/CMakeLists.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(googlesuggest LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/googlesuggest")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
-
-qt_add_executable(googlesuggest
- googlesuggest.cpp googlesuggest.h
- main.cpp
- searchbox.cpp searchbox.h
-)
-
-set_target_properties(googlesuggest PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(googlesuggest PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
-)
-
-install(TARGETS googlesuggest
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/googlesuggest/googlesuggest.cpp b/examples/network/googlesuggest/googlesuggest.cpp
deleted file mode 100644
index b8cb589262..0000000000
--- a/examples/network/googlesuggest/googlesuggest.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "googlesuggest.h"
-
-//! [1]
-const QString gsuggestUrl(QStringLiteral("http://google.com/complete/search?output=toolbar&q=%1"));
-//! [1]
-
-//! [2]
-GSuggestCompletion::GSuggestCompletion(QLineEdit *parent): QObject(parent), editor(parent)
-{
- popup = new QTreeWidget;
- popup->setWindowFlags(Qt::Popup);
- popup->setFocusPolicy(Qt::NoFocus);
- popup->setFocusProxy(parent);
- popup->setMouseTracking(true);
-
- popup->setColumnCount(1);
- popup->setUniformRowHeights(true);
- popup->setRootIsDecorated(false);
- popup->setEditTriggers(QTreeWidget::NoEditTriggers);
- popup->setSelectionBehavior(QTreeWidget::SelectRows);
- popup->setFrameStyle(QFrame::Box | QFrame::Plain);
- popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- popup->header()->hide();
-
- popup->installEventFilter(this);
-
- connect(popup, &QTreeWidget::itemClicked,
- this, &GSuggestCompletion::doneCompletion);
-
- timer.setSingleShot(true);
- timer.setInterval(500);
- connect(&timer, &QTimer::timeout,
- this, &GSuggestCompletion::autoSuggest);
- connect(editor, &QLineEdit::textEdited,
- &timer, QOverload<>::of(&QTimer::start));
-
- connect(&networkManager, &QNetworkAccessManager::finished,
- this, &GSuggestCompletion::handleNetworkData);
-
-}
-//! [2]
-
-//! [3]
-GSuggestCompletion::~GSuggestCompletion()
-{
- delete popup;
-}
-//! [3]
-
-//! [4]
-bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev)
-{
- if (obj != popup)
- return false;
-
- if (ev->type() == QEvent::MouseButtonPress) {
- popup->hide();
- editor->setFocus();
- return true;
- }
-
- if (ev->type() == QEvent::KeyPress) {
- bool consumed = false;
- int key = static_cast<QKeyEvent*>(ev)->key();
- switch (key) {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- doneCompletion();
- consumed = true;
- break;
-
- case Qt::Key_Escape:
- editor->setFocus();
- popup->hide();
- consumed = true;
- break;
-
- case Qt::Key_Up:
- case Qt::Key_Down:
- case Qt::Key_Home:
- case Qt::Key_End:
- case Qt::Key_PageUp:
- case Qt::Key_PageDown:
- break;
-
- default:
- editor->setFocus();
- editor->event(ev);
- popup->hide();
- break;
- }
-
- return consumed;
- }
-
- return false;
-}
-//! [4]
-
-//! [5]
-void GSuggestCompletion::showCompletion(const QList<QString> &choices)
-{
- if (choices.isEmpty())
- return;
-
- const QPalette &pal = editor->palette();
- QColor color = pal.color(QPalette::Disabled, QPalette::WindowText);
-
- popup->setUpdatesEnabled(false);
- popup->clear();
-
- for (const auto &choice : choices) {
- auto item = new QTreeWidgetItem(popup);
- item->setText(0, choice);
- item->setForeground(0, color);
- }
-
- popup->setCurrentItem(popup->topLevelItem(0));
- popup->resizeColumnToContents(0);
- popup->setUpdatesEnabled(true);
-
- popup->move(editor->mapToGlobal(QPoint(0, editor->height())));
- popup->setFocus();
- popup->show();
-}
-//! [5]
-
-//! [6]
-void GSuggestCompletion::doneCompletion()
-{
- timer.stop();
- popup->hide();
- editor->setFocus();
- QTreeWidgetItem *item = popup->currentItem();
- if (item) {
- editor->setText(item->text(0));
- QMetaObject::invokeMethod(editor, "returnPressed");
- }
-}
-//! [6]
-
-//! [7]
-void GSuggestCompletion::autoSuggest()
-{
- QString str = editor->text();
- QString url = gsuggestUrl.arg(str);
- networkManager.get(QNetworkRequest(url));
-}
-//! [7]
-
-//! [8]
-void GSuggestCompletion::preventSuggest()
-{
- timer.stop();
-}
-//! [8]
-
-//! [9]
-void GSuggestCompletion::handleNetworkData(QNetworkReply *networkReply)
-{
- QUrl url = networkReply->url();
- if (networkReply->error() == QNetworkReply::NoError) {
- QList<QString> choices;
-
- QByteArray response(networkReply->readAll());
- QXmlStreamReader xml(response);
- while (!xml.atEnd()) {
- xml.readNext();
- if (xml.tokenType() == QXmlStreamReader::StartElement)
- if (xml.name() == u"suggestion") {
- auto str = xml.attributes().value("data");
- choices << str.toString();
- }
- }
-
- showCompletion(choices);
- }
-
- networkReply->deleteLater();
-}
-//! [9]
diff --git a/examples/network/googlesuggest/googlesuggest.h b/examples/network/googlesuggest/googlesuggest.h
deleted file mode 100644
index c46b58044b..0000000000
--- a/examples/network/googlesuggest/googlesuggest.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef GOOGLESUGGEST_H
-#define GOOGLESUGGEST_H
-
-#include <QtWidgets>
-#include <QtNetwork>
-#include <QtCore>
-
-//! [1]
-class GSuggestCompletion : public QObject
-{
- Q_OBJECT
-
-public:
- explicit GSuggestCompletion(QLineEdit *parent = nullptr);
- ~GSuggestCompletion();
- bool eventFilter(QObject *obj, QEvent *ev) override;
- void showCompletion(const QList<QString> &choices);
-
-public slots:
-
- void doneCompletion();
- void preventSuggest();
- void autoSuggest();
- void handleNetworkData(QNetworkReply *networkReply);
-
-private:
- QLineEdit *editor = nullptr;
- QTreeWidget *popup = nullptr;
- QTimer timer;
- QNetworkAccessManager networkManager;
-};
-//! [1]
-#endif // GOOGLESUGGEST_H
-
diff --git a/examples/network/googlesuggest/googlesuggest.pro b/examples/network/googlesuggest/googlesuggest.pro
deleted file mode 100644
index 6e73906303..0000000000
--- a/examples/network/googlesuggest/googlesuggest.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT += network widgets
-requires(qtConfig(itemviews))
-SOURCES = main.cpp searchbox.cpp googlesuggest.cpp
-HEADERS = searchbox.h googlesuggest.h
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/googlesuggest
-INSTALLS += target
diff --git a/examples/network/googlesuggest/main.cpp b/examples/network/googlesuggest/main.cpp
deleted file mode 100644
index 0e927f3d23..0000000000
--- a/examples/network/googlesuggest/main.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QApplication>
-
-#include "searchbox.h"
-
-int main(int argc, char * argv[])
-{
- QApplication app(argc, argv);
- SearchBox searchEdit;
- searchEdit.show();
- return app.exec();
-}
diff --git a/examples/network/googlesuggest/searchbox.cpp b/examples/network/googlesuggest/searchbox.cpp
deleted file mode 100644
index 56ca44dac4..0000000000
--- a/examples/network/googlesuggest/searchbox.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QDesktopServices>
-#include <QUrl>
-
-#include "searchbox.h"
-#include "googlesuggest.h"
-
-const QString gsearchUrl = QStringLiteral("http://www.google.com/search?q=%1");
-
-//! [1]
-SearchBox::SearchBox(QWidget *parent)
- : QLineEdit(parent)
- , completer(new GSuggestCompletion(this))
-{
- connect(this, &SearchBox::returnPressed, this, &SearchBox::doSearch);
-
- setWindowTitle("Search with Google");
-
- adjustSize();
- resize(400, height());
- setFocus();
-}
-//! [1]
-
-//! [2]
-void SearchBox::doSearch()
-{
- completer->preventSuggest();
- QString url = gsearchUrl.arg(text());
- QDesktopServices::openUrl(url);
-}
-//! [2]
-
diff --git a/examples/network/googlesuggest/searchbox.h b/examples/network/googlesuggest/searchbox.h
deleted file mode 100644
index be9beba1bc..0000000000
--- a/examples/network/googlesuggest/searchbox.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef SEARCHBOX_H
-#define SEARCHBOX_H
-
-//! [1]
-#include <QLineEdit>
-
-class GSuggestCompletion;
-
-class SearchBox: public QLineEdit
-{
- Q_OBJECT
-
-public:
- explicit SearchBox(QWidget *parent = nullptr);
-
-protected slots:
- void doSearch();
-
-private:
- GSuggestCompletion *completer = nullptr;
-//! [1]
-};
-
-
-#endif // SEARCHBOX_H
diff --git a/examples/network/http/CMakeLists.txt b/examples/network/http/CMakeLists.txt
index 36bf303d7c..705c3a0beb 100644
--- a/examples/network/http/CMakeLists.txt
+++ b/examples/network/http/CMakeLists.txt
@@ -4,17 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(http LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/http")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(http
authenticationdialog.ui
httpwindow.cpp httpwindow.h
@@ -26,15 +19,22 @@ set_target_properties(http PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(http PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(http PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS http
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET http
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/http/httpwindow.cpp b/examples/network/http/httpwindow.cpp
index 9fa32da101..72f130734b 100644
--- a/examples/network/http/httpwindow.cpp
+++ b/examples/network/http/httpwindow.cpp
@@ -1,4 +1,4 @@
-// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "httpwindow.h"
@@ -23,7 +23,6 @@ ProgressDialog::ProgressDialog(const QUrl &url, QWidget *parent)
: QProgressDialog(parent)
{
setWindowTitle(tr("Download Progress"));
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setLabelText(tr("Downloading %1.").arg(url.toDisplayString()));
setMinimum(0);
setValue(0);
@@ -42,17 +41,20 @@ HttpWindow::HttpWindow(QWidget *parent)
, statusLabel(new QLabel(tr("Please enter the URL of a file you want to download.\n\n"), this))
, urlLineEdit(new QLineEdit(defaultUrl))
, downloadButton(new QPushButton(tr("Download")))
- , launchCheckBox(new QCheckBox("Launch file"))
+ , launchCheckBox(new QCheckBox(tr("Launch file")))
, defaultFileLineEdit(new QLineEdit(defaultFileName))
, downloadDirectoryLineEdit(new QLineEdit)
{
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
- setWindowTitle(tr("HTTP"));
+ setWindowTitle(tr("HTTP Client"));
//! [qnam-auth-required-1]
connect(&qnam, &QNetworkAccessManager::authenticationRequired,
this, &HttpWindow::slotAuthenticationRequired);
//! [qnam-auth-required-1]
+#if QT_CONFIG(networkproxy)
+ connect(&qnam, &QNetworkAccessManager::proxyAuthenticationRequired,
+ this, &HttpWindow::slotProxyAuthenticationRequired);
+#endif
QFormLayout *formLayout = new QFormLayout;
urlLineEdit->setClearButtonEnabled(true);
@@ -142,19 +144,18 @@ void HttpWindow::downloadFile()
bool useDirectory = !downloadDirectory.isEmpty() && QFileInfo(downloadDirectory).isDir();
if (useDirectory)
fileName.prepend(downloadDirectory + '/');
+
if (QFile::exists(fileName)) {
- if (QMessageBox::question(this, tr("Overwrite Existing File"),
- tr("There already exists a file called %1%2."
- " Overwrite?")
- .arg(fileName,
- useDirectory
- ? QString()
- : QStringLiteral(" in the current directory")),
- QMessageBox::Yes | QMessageBox::No,
- QMessageBox::No)
- == QMessageBox::No) {
+ QString alreadyExists = useDirectory
+ ? tr("There already exists a file called %1. Overwrite?")
+ : tr("There already exists a file called %1 in the current directory. "
+ "Overwrite?");
+ QMessageBox::StandardButton response = QMessageBox::question(this,
+ tr("Overwrite Existing File"),
+ alreadyExists.arg(QDir::toNativeSeparators(fileName)),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
+ if (response == QMessageBox::No)
return;
- }
QFile::remove(fileName);
}
@@ -272,11 +273,34 @@ void HttpWindow::sslErrors(const QList<QSslError> &errors)
errorString += error.errorString();
}
- if (QMessageBox::warning(this, tr("SSL Errors"),
- tr("One or more SSL errors has occurred:\n%1").arg(errorString),
- QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) {
+ if (QMessageBox::warning(this, tr("TLS Errors"),
+ tr("One or more TLS errors has occurred:\n%1").arg(errorString),
+ QMessageBox::Ignore | QMessageBox::Abort)
+ == QMessageBox::Ignore) {
reply->ignoreSslErrors();
}
}
//! [sslerrors-2]
#endif
+
+#if QT_CONFIG(networkproxy)
+void HttpWindow::slotProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
+{
+ QDialog authenticationDialog;
+ Ui::Dialog ui;
+ ui.setupUi(&authenticationDialog);
+ authenticationDialog.adjustSize();
+ ui.siteDescription->setText(tr("A network proxy at %1 is requesting credentials for realm: %2")
+ .arg(proxy.hostName(), authenticator->realm()));
+
+ // If the user passed credentials in the URL to http_proxy or similar they may be available to
+ // us. Otherwise this will just leave the fields empty
+ ui.userEdit->setText(proxy.user());
+ ui.passwordEdit->setText(proxy.password());
+
+ if (authenticationDialog.exec() == QDialog::Accepted) {
+ authenticator->setUser(ui.userEdit->text());
+ authenticator->setPassword(ui.passwordEdit->text());
+ }
+}
+#endif
diff --git a/examples/network/http/httpwindow.h b/examples/network/http/httpwindow.h
index 64e9274288..ade0635e48 100644
--- a/examples/network/http/httpwindow.h
+++ b/examples/network/http/httpwindow.h
@@ -19,6 +19,9 @@ class QSslError;
class QAuthenticator;
class QNetworkReply;
class QCheckBox;
+#if QT_CONFIG(networkproxy)
+class QNetworkProxy;
+#endif
QT_END_NAMESPACE
@@ -52,6 +55,9 @@ private slots:
#if QT_CONFIG(ssl)
void sslErrors(const QList<QSslError> &errors);
#endif
+#if QT_CONFIG(networkproxy)
+ void slotProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
+#endif
private:
std::unique_ptr<QFile> openFileForWrite(const QString &fileName);
diff --git a/examples/network/http/main.cpp b/examples/network/http/main.cpp
index 049d10dcc2..4b0bd9e76a 100644
--- a/examples/network/http/main.cpp
+++ b/examples/network/http/main.cpp
@@ -14,11 +14,7 @@ int main(int argc, char *argv[])
const QRect availableSize = httpWin.screen()->availableGeometry();
httpWin.resize(availableSize.width() / 5, availableSize.height() / 5);
httpWin.move((availableSize.width() - httpWin.width()) / 2, (availableSize.height() - httpWin.height()) / 2);
-#ifdef Q_OS_ANDROID
- httpWin.showMaximized();
-#else
httpWin.show();
-#endif
return app.exec();
}
diff --git a/examples/network/loopback/CMakeLists.txt b/examples/network/loopback/CMakeLists.txt
deleted file mode 100644
index 4dfb7e763b..0000000000
--- a/examples/network/loopback/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-cmake_minimum_required(VERSION 3.16)
-project(loopback LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/loopback")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
-
-qt_add_executable(loopback
- dialog.cpp dialog.h
- main.cpp
-)
-
-set_target_properties(loopback PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(loopback PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
-)
-
-install(TARGETS loopback
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/network/loopback/dialog.cpp b/examples/network/loopback/dialog.cpp
deleted file mode 100644
index d1673d3338..0000000000
--- a/examples/network/loopback/dialog.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "dialog.h"
-
-#include <QtNetwork>
-#include <QtWidgets>
-
-static const int TotalBytes = 50 * 1024 * 1024;
-static const int PayloadSize = 64 * 1024; // 64 KB
-
-Dialog::Dialog(QWidget *parent)
- : QDialog(parent)
-{
- clientProgressBar = new QProgressBar;
- clientStatusLabel = new QLabel(tr("Client ready"));
- serverProgressBar = new QProgressBar;
- serverStatusLabel = new QLabel(tr("Server ready"));
-
- startButton = new QPushButton(tr("&Start"));
- quitButton = new QPushButton(tr("&Quit"));
-
- buttonBox = new QDialogButtonBox;
- buttonBox->addButton(startButton, QDialogButtonBox::ActionRole);
- buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
-
- connect(startButton, &QAbstractButton::clicked, this, &Dialog::start);
- connect(quitButton, &QAbstractButton::clicked, this, &QWidget::close);
- connect(&tcpServer, &QTcpServer::newConnection,
- this, &Dialog::acceptConnection);
- connect(&tcpClient, &QAbstractSocket::connected, this, &Dialog::startTransfer);
- connect(&tcpClient, &QIODevice::bytesWritten,
- this, &Dialog::updateClientProgress);
- connect(&tcpClient, &QAbstractSocket::errorOccurred,
- this, &Dialog::displayError);
-
- QVBoxLayout *mainLayout = new QVBoxLayout;
- mainLayout->addWidget(clientProgressBar);
- mainLayout->addWidget(clientStatusLabel);
- mainLayout->addWidget(serverProgressBar);
- mainLayout->addWidget(serverStatusLabel);
- mainLayout->addStretch(1);
- mainLayout->addSpacing(10);
- mainLayout->addWidget(buttonBox);
- setLayout(mainLayout);
-
- setWindowTitle(tr("Loopback"));
-}
-
-void Dialog::start()
-{
- startButton->setEnabled(false);
-
-#ifndef QT_NO_CURSOR
- QGuiApplication::setOverrideCursor(Qt::WaitCursor);
-#endif
-
- bytesWritten = 0;
- bytesReceived = 0;
-
- while (!tcpServer.isListening() && !tcpServer.listen()) {
- QMessageBox::StandardButton ret = QMessageBox::critical(this,
- tr("Loopback"),
- tr("Unable to start the test: %1.")
- .arg(tcpServer.errorString()),
- QMessageBox::Retry
- | QMessageBox::Cancel);
- if (ret == QMessageBox::Cancel)
- return;
- }
-
- serverStatusLabel->setText(tr("Listening"));
- clientStatusLabel->setText(tr("Connecting"));
- tcpClient.connectToHost(QHostAddress::LocalHost, tcpServer.serverPort());
-}
-
-void Dialog::acceptConnection()
-{
- tcpServerConnection = tcpServer.nextPendingConnection();
- if (!tcpServerConnection) {
- serverStatusLabel->setText(tr("Error: got invalid pending connection!"));
- return;
- }
-
- connect(tcpServerConnection, &QIODevice::readyRead,
- this, &Dialog::updateServerProgress);
- connect(tcpServerConnection, &QAbstractSocket::errorOccurred,
- this, &Dialog::displayError);
- connect(tcpServerConnection, &QTcpSocket::disconnected,
- tcpServerConnection, &QTcpSocket::deleteLater);
-
- serverStatusLabel->setText(tr("Accepted connection"));
- tcpServer.close();
-}
-
-void Dialog::startTransfer()
-{
- // called when the TCP client connected to the loopback server
- bytesToWrite = TotalBytes - int(tcpClient.write(QByteArray(PayloadSize, '@')));
- clientStatusLabel->setText(tr("Connected"));
-}
-
-void Dialog::updateServerProgress()
-{
- bytesReceived += int(tcpServerConnection->bytesAvailable());
- tcpServerConnection->readAll();
-
- serverProgressBar->setMaximum(TotalBytes);
- serverProgressBar->setValue(bytesReceived);
- serverStatusLabel->setText(tr("Received %1MB")
- .arg(bytesReceived / (1024 * 1024)));
-
- if (bytesReceived == TotalBytes) {
- tcpServerConnection->close();
- startButton->setEnabled(true);
-#ifndef QT_NO_CURSOR
- QGuiApplication::restoreOverrideCursor();
-#endif
- }
-}
-
-void Dialog::updateClientProgress(qint64 numBytes)
-{
- // called when the TCP client has written some bytes
- bytesWritten += int(numBytes);
-
- // only write more if not finished and when the Qt write buffer is below a certain size.
- if (bytesToWrite > 0 && tcpClient.bytesToWrite() <= 4 * PayloadSize)
- bytesToWrite -= tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@'));
-
- clientProgressBar->setMaximum(TotalBytes);
- clientProgressBar->setValue(bytesWritten);
- clientStatusLabel->setText(tr("Sent %1MB").arg(bytesWritten / (1024 * 1024)));
-}
-
-void Dialog::displayError(QAbstractSocket::SocketError socketError)
-{
- if (socketError == QTcpSocket::RemoteHostClosedError)
- return;
-
- QMessageBox::information(this, tr("Network error"),
- tr("The following error occurred: %1.")
- .arg(tcpClient.errorString()));
-
- tcpClient.close();
- tcpServer.close();
- clientProgressBar->reset();
- serverProgressBar->reset();
- clientStatusLabel->setText(tr("Client ready"));
- serverStatusLabel->setText(tr("Server ready"));
- startButton->setEnabled(true);
-#ifndef QT_NO_CURSOR
- QGuiApplication::restoreOverrideCursor();
-#endif
-}
diff --git a/examples/network/loopback/dialog.h b/examples/network/loopback/dialog.h
deleted file mode 100644
index c39ffb00ce..0000000000
--- a/examples/network/loopback/dialog.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef DIALOG_H
-#define DIALOG_H
-
-#include <QDialog>
-#include <QTcpServer>
-#include <QTcpSocket>
-
-QT_BEGIN_NAMESPACE
-class QDialogButtonBox;
-class QLabel;
-class QProgressBar;
-class QPushButton;
-QT_END_NAMESPACE
-
-class Dialog : public QDialog
-{
- Q_OBJECT
-
-public:
- Dialog(QWidget *parent = nullptr);
-
-public slots:
- void start();
- void acceptConnection();
- void startTransfer();
- void updateServerProgress();
- void updateClientProgress(qint64 numBytes);
- void displayError(QAbstractSocket::SocketError socketError);
-
-private:
- QProgressBar *clientProgressBar = nullptr;
- QProgressBar *serverProgressBar = nullptr;
- QLabel *clientStatusLabel = nullptr;
- QLabel *serverStatusLabel = nullptr;
-
- QPushButton *startButton = nullptr;
- QPushButton *quitButton = nullptr;
- QDialogButtonBox *buttonBox = nullptr;
-
- QTcpServer tcpServer;
- QTcpSocket tcpClient;
- QTcpSocket *tcpServerConnection = nullptr;
- int bytesToWrite = 0;
- int bytesWritten = 0;
- int bytesReceived = 0;
-};
-
-#endif
diff --git a/examples/network/loopback/loopback.pro b/examples/network/loopback/loopback.pro
deleted file mode 100644
index 14b22daa57..0000000000
--- a/examples/network/loopback/loopback.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-QT += network widgets
-
-HEADERS = dialog.h
-SOURCES = dialog.cpp \
- main.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/network/loopback
-INSTALLS += target
diff --git a/examples/network/loopback/main.cpp b/examples/network/loopback/main.cpp
deleted file mode 100644
index 3eb7cbf57d..0000000000
--- a/examples/network/loopback/main.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "dialog.h"
-
-#include <QApplication>
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
- Dialog dialog;
- dialog.show();
- return app.exec();
-}
diff --git a/examples/network/multicastreceiver/CMakeLists.txt b/examples/network/multicastreceiver/CMakeLists.txt
index 1baee432fa..cb1139e69a 100644
--- a/examples/network/multicastreceiver/CMakeLists.txt
+++ b/examples/network/multicastreceiver/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(multicastreceiver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/multicastreceiver")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(multicastreceiver
main.cpp
receiver.cpp receiver.h
@@ -24,15 +18,22 @@ set_target_properties(multicastreceiver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(multicastreceiver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(multicastreceiver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS multicastreceiver
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET multicastreceiver
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/multicastreceiver/receiver.cpp b/examples/network/multicastreceiver/receiver.cpp
index 2a49553875..23e204ca25 100644
--- a/examples/network/multicastreceiver/receiver.cpp
+++ b/examples/network/multicastreceiver/receiver.cpp
@@ -38,7 +38,7 @@ Receiver::Receiver(QWidget *parent)
connect(&udpSocket6, &QUdpSocket::readyRead,
this, &Receiver::processPendingDatagrams);
connect(quitButton, &QPushButton::clicked,
- this, &Receiver::close);
+ qApp, &QCoreApplication::quit);
}
void Receiver::processPendingDatagrams()
@@ -47,7 +47,7 @@ void Receiver::processPendingDatagrams()
// using QUdpSocket::readDatagram (API since Qt 4)
while (udpSocket4.hasPendingDatagrams()) {
- datagram.resize(int(udpSocket4.pendingDatagramSize()));
+ datagram.resize(qsizetype(udpSocket4.pendingDatagramSize()));
udpSocket4.readDatagram(datagram.data(), datagram.size());
statusLabel->setText(tr("Received IPv4 datagram: \"%1\"")
.arg(datagram.constData()));
diff --git a/examples/network/multicastsender/CMakeLists.txt b/examples/network/multicastsender/CMakeLists.txt
index a5c7570dd7..eb45b9f2fa 100644
--- a/examples/network/multicastsender/CMakeLists.txt
+++ b/examples/network/multicastsender/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(multicastsender LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/multicastsender")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(multicastsender
main.cpp
sender.cpp sender.h
@@ -24,15 +18,22 @@ set_target_properties(multicastsender PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(multicastsender PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(multicastsender PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS multicastsender
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET multicastsender
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/multistreamclient/CMakeLists.txt b/examples/network/multistreamclient/CMakeLists.txt
index ffa0eb377d..1226a4b3c7 100644
--- a/examples/network/multistreamclient/CMakeLists.txt
+++ b/examples/network/multistreamclient/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(multistreamclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/multistreamclient")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(multistreamclient
chatconsumer.cpp chatconsumer.h
client.cpp client.h
@@ -28,15 +22,22 @@ set_target_properties(multistreamclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(multistreamclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(multistreamclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS multistreamclient
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET multistreamclient
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/multistreamserver/CMakeLists.txt b/examples/network/multistreamserver/CMakeLists.txt
index b9f179fdd4..3f77506f70 100644
--- a/examples/network/multistreamserver/CMakeLists.txt
+++ b/examples/network/multistreamserver/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(multistreamserver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/multistreamserver")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(multistreamserver
chatprovider.cpp chatprovider.h
main.cpp
@@ -28,15 +22,22 @@ set_target_properties(multistreamserver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(multistreamserver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(multistreamserver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS multistreamserver
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET multistreamserver
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/network-chat/CMakeLists.txt b/examples/network/network-chat/CMakeLists.txt
index 7e40564d33..127a4c2fb5 100644
--- a/examples/network/network-chat/CMakeLists.txt
+++ b/examples/network/network-chat/CMakeLists.txt
@@ -4,17 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(network-chat LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/network-chat")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(network-chat
chatdialog.cpp chatdialog.h chatdialog.ui
client.cpp client.h
@@ -29,15 +22,26 @@ set_target_properties(network-chat PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(network-chat PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_compile_definitions(network-chat PRIVATE
+ QT_USE_QSTRINGBUILDER
+)
+
+target_link_libraries(network-chat PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS network-chat
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET network-chat
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/network-chat/chatdialog.cpp b/examples/network/network-chat/chatdialog.cpp
index ddec5c2997..55c98fed0c 100644
--- a/examples/network/network-chat/chatdialog.cpp
+++ b/examples/network/network-chat/chatdialog.cpp
@@ -1,10 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QtWidgets>
-
#include "chatdialog.h"
+#include <QTimer>
+#include <QScrollBar>
+#include <QLineEdit>
+#include <QTextTable>
+#include <QMessageBox>
+
ChatDialog::ChatDialog(QWidget *parent)
: QDialog(parent)
{
@@ -27,7 +31,7 @@ ChatDialog::ChatDialog(QWidget *parent)
myNickName = client.nickName();
newParticipant(myNickName);
tableFormat.setBorder(0);
- QTimer::singleShot(10 * 1000, this, SLOT(showInformation()));
+ QTimer::singleShot(10 * 1000, this, &ChatDialog::showInformation);
}
void ChatDialog::appendMessage(const QString &from, const QString &message)
diff --git a/examples/network/network-chat/chatdialog.h b/examples/network/network-chat/chatdialog.h
index adda73fb72..45a9858822 100644
--- a/examples/network/network-chat/chatdialog.h
+++ b/examples/network/network-chat/chatdialog.h
@@ -12,7 +12,7 @@ class ChatDialog : public QDialog, private Ui::ChatDialog
Q_OBJECT
public:
- ChatDialog(QWidget *parent = nullptr);
+ explicit ChatDialog(QWidget *parent = nullptr);
public slots:
void appendMessage(const QString &from, const QString &message);
diff --git a/examples/network/network-chat/client.cpp b/examples/network/network-chat/client.cpp
index c9b165f724..c637224127 100644
--- a/examples/network/network-chat/client.cpp
+++ b/examples/network/network-chat/client.cpp
@@ -1,15 +1,18 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QtNetwork>
-
#include "client.h"
#include "connection.h"
#include "peermanager.h"
+#include <QHostInfo>
+
+#include <algorithm>
+#include <functional>
+
Client::Client()
+ : peerManager(new PeerManager(this))
{
- peerManager = new PeerManager(this);
peerManager->setServerPort(server.serverPort());
peerManager->startBroadcasting();
@@ -24,7 +27,7 @@ void Client::sendMessage(const QString &message)
if (message.isEmpty())
return;
- for (Connection *connection : qAsConst(peers))
+ for (Connection *connection : std::as_const(peers))
connection->sendMessage(message);
}
@@ -34,43 +37,35 @@ QString Client::nickName() const
+ ':' + QString::number(server.serverPort());
}
-bool Client::hasConnection(const QHostAddress &senderIp, int senderPort) const
+bool Client::hasConnection(const QByteArray &peerUniqueId) const
{
- if (senderPort == -1)
- return peers.contains(senderIp);
-
- if (!peers.contains(senderIp))
- return false;
-
- const QList<Connection *> connections = peers.values(senderIp);
- for (const Connection *connection : connections) {
- if (connection->peerPort() == senderPort)
- return true;
- }
-
- return false;
+ return peers.contains(peerUniqueId);
}
void Client::newConnection(Connection *connection)
{
- connection->setGreetingMessage(peerManager->userName());
-
- connect(connection, &Connection::errorOccurred, this, &Client::connectionError);
- connect(connection, &Connection::disconnected, this, &Client::disconnected);
+ connection->setGreetingMessage(peerManager->userName(), peerManager->uniqueId());
connect(connection, &Connection::readyForUse, this, &Client::readyForUse);
+ connect(connection, &Connection::errorOccurred, connection, &QObject::deleteLater);
+ connect(connection, &Connection::disconnected, connection, &QObject::deleteLater);
}
void Client::readyForUse()
{
Connection *connection = qobject_cast<Connection *>(sender());
- if (!connection || hasConnection(connection->peerAddress(),
- connection->peerPort()))
+ if (!connection || hasConnection(connection->uniqueId())) {
+ if (connection) {
+ connection->disconnectFromHost();
+ connection->deleteLater();
+ }
return;
+ }
- connect(connection, &Connection::newMessage,
- this, &Client::newMessage);
+ connect(connection, &Connection::errorOccurred, this, &Client::connectionError);
+ connect(connection, &Connection::disconnected, this, &Client::disconnected);
+ connect(connection, &Connection::newMessage, this, &Client::newMessage);
- peers.insert(connection->peerAddress(), connection);
+ peers.insert(connection->uniqueId(), connection);
QString nick = connection->name();
if (!nick.isEmpty())
emit newParticipant(nick);
@@ -90,8 +85,7 @@ void Client::connectionError(QAbstractSocket::SocketError /* socketError */)
void Client::removeConnection(Connection *connection)
{
- if (peers.contains(connection->peerAddress())) {
- peers.remove(connection->peerAddress());
+ if (peers.remove(connection->uniqueId())) {
QString nick = connection->name();
if (!nick.isEmpty())
emit participantLeft(nick);
diff --git a/examples/network/network-chat/client.h b/examples/network/network-chat/client.h
index 5d55bf53d3..a09d0c21f6 100644
--- a/examples/network/network-chat/client.h
+++ b/examples/network/network-chat/client.h
@@ -4,12 +4,12 @@
#ifndef CLIENT_H
#define CLIENT_H
+#include "server.h"
+
#include <QAbstractSocket>
#include <QHash>
#include <QHostAddress>
-#include "server.h"
-
class PeerManager;
class Client : public QObject
@@ -21,7 +21,7 @@ public:
void sendMessage(const QString &message);
QString nickName() const;
- bool hasConnection(const QHostAddress &senderIp, int senderPort = -1) const;
+ bool hasConnection(const QByteArray &peerUniqueId) const;
signals:
void newMessage(const QString &from, const QString &message);
@@ -39,7 +39,7 @@ private:
PeerManager *peerManager;
Server server;
- QMultiHash<QHostAddress, Connection *> peers;
+ QHash<QByteArray, Connection *> peers;
};
#endif
diff --git a/examples/network/network-chat/connection.cpp b/examples/network/network-chat/connection.cpp
index d89266a53c..0f59cc91ed 100644
--- a/examples/network/network-chat/connection.cpp
+++ b/examples/network/network-chat/connection.cpp
@@ -4,7 +4,7 @@
#include "connection.h"
-#include <QtNetwork>
+#include <QTimerEvent>
static const int TransferTimeout = 30 * 1000;
static const int PongTimeout = 60 * 1000;
@@ -21,18 +21,12 @@ static const int PingInterval = 5 * 1000;
* plaintext = { 0 => text }
* ping = { 1 => null }
* pong = { 2 => null }
- * greeting = { 3 => text }
+ * greeting = { 3 => { text, bytes } }
*/
Connection::Connection(QObject *parent)
: QTcpSocket(parent), writer(this)
{
- greetingMessage = tr("undefined");
- username = tr("unknown");
- state = WaitingForGreeting;
- currentDataType = Undefined;
- transferTimerId = -1;
- isGreetingMessageSent = false;
pingTimer.setInterval(PingInterval);
connect(this, &QTcpSocket::readyRead, this,
@@ -54,7 +48,7 @@ Connection::Connection(qintptr socketDescriptor, QObject *parent)
Connection::~Connection()
{
- if (isGreetingMessageSent) {
+ if (isGreetingMessageSent && QAbstractSocket::state() != QAbstractSocket::UnconnectedState) {
// Indicate clean shutdown.
writer.endArray();
waitForBytesWritten(2000);
@@ -66,9 +60,15 @@ QString Connection::name() const
return username;
}
-void Connection::setGreetingMessage(const QString &message)
+void Connection::setGreetingMessage(const QString &message, const QByteArray &uniqueId)
{
greetingMessage = message;
+ localUniqueId = uniqueId;
+}
+
+QByteArray Connection::uniqueId() const
+{
+ return peerUniqueId;
}
bool Connection::sendMessage(const QString &message)
@@ -124,7 +124,29 @@ void Connection::processReadyRead()
reader.next();
} else {
// Current state: read command payload
- if (reader.isString()) {
+ if (currentDataType == Greeting) {
+ if (state == ReadingGreeting) {
+ if (!reader.isContainer() || !reader.isLengthKnown() || reader.length() != 2)
+ break; // protocol error
+ state = ProcessingGreeting;
+ reader.enterContainer();
+ }
+ if (state != ProcessingGreeting)
+ break; // protocol error
+ if (reader.isString()) {
+ auto r = reader.readString();
+ buffer += r.data;
+ } else if (reader.isByteArray()) {
+ auto r = reader.readByteArray();
+ peerUniqueId += r.data;
+ if (r.status == QCborStreamReader::EndOfString) {
+ reader.leaveContainer();
+ processGreeting();
+ }
+ }
+ if (state == ProcessingGreeting)
+ continue;
+ } else if (reader.isString()) {
auto r = reader.readString();
buffer += r.data;
if (r.status != QCborStreamReader::EndOfString)
@@ -132,7 +154,7 @@ void Connection::processReadyRead()
} else if (reader.isNull()) {
reader.next();
} else {
- break; // protocol error
+ break; // protocol error
}
// Next state: no command read
@@ -142,13 +164,7 @@ void Connection::processReadyRead()
transferTimerId = -1;
}
- if (state == ReadingGreeting) {
- if (currentDataType != Greeting)
- break; // protocol error
- processGreeting();
- } else {
- processData();
- }
+ processData();
}
}
@@ -178,7 +194,10 @@ void Connection::sendGreetingMessage()
writer.startMap(1);
writer.append(Greeting);
+ writer.startArray(2);
writer.append(greetingMessage);
+ writer.append(localUniqueId);
+ writer.endArray();
writer.endMap();
isGreetingMessageSent = true;
diff --git a/examples/network/network-chat/connection.h b/examples/network/network-chat/connection.h
index a3082247cb..4b063e7def 100644
--- a/examples/network/network-chat/connection.h
+++ b/examples/network/network-chat/connection.h
@@ -12,8 +12,6 @@
#include <QTcpSocket>
#include <QTimer>
-static const int MaxBufferSize = 1024000;
-
class Connection : public QTcpSocket
{
Q_OBJECT
@@ -22,6 +20,7 @@ public:
enum ConnectionState {
WaitingForGreeting,
ReadingGreeting,
+ ProcessingGreeting,
ReadyForUse
};
enum DataType {
@@ -32,14 +31,16 @@ public:
Undefined
};
- Connection(QObject *parent = nullptr);
- Connection(qintptr socketDescriptor, QObject *parent = nullptr);
+ explicit Connection(QObject *parent = nullptr);
+ explicit Connection(qintptr socketDescriptor, QObject *parent = nullptr);
~Connection();
QString name() const;
- void setGreetingMessage(const QString &message);
+ void setGreetingMessage(const QString &message, const QByteArray &uniqueId);
bool sendMessage(const QString &message);
+ QByteArray uniqueId() const;
+
signals:
void readyForUse();
void newMessage(const QString &from, const QString &message);
@@ -59,15 +60,17 @@ private:
QCborStreamReader reader;
QCborStreamWriter writer;
- QString greetingMessage;
- QString username;
+ QString greetingMessage = tr("undefined");
+ QString username = tr("unknown");
QTimer pingTimer;
QElapsedTimer pongTime;
QString buffer;
- ConnectionState state;
- DataType currentDataType;
- int transferTimerId;
- bool isGreetingMessageSent;
+ QByteArray localUniqueId;
+ QByteArray peerUniqueId;
+ ConnectionState state = WaitingForGreeting;
+ DataType currentDataType = Undefined;
+ int transferTimerId = -1;
+ bool isGreetingMessageSent = false;
};
#endif
diff --git a/examples/network/network-chat/main.cpp b/examples/network/network-chat/main.cpp
index bc6c4ef636..5d679d284b 100644
--- a/examples/network/network-chat/main.cpp
+++ b/examples/network/network-chat/main.cpp
@@ -1,11 +1,9 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QApplication>
-
#include "chatdialog.h"
-#include <QtCore/QSettings>
+#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
diff --git a/examples/network/network-chat/network-chat.pro b/examples/network/network-chat/network-chat.pro
index 2e3cbbc489..626a710949 100644
--- a/examples/network/network-chat/network-chat.pro
+++ b/examples/network/network-chat/network-chat.pro
@@ -11,6 +11,7 @@ SOURCES = chatdialog.cpp \
server.cpp
FORMS = chatdialog.ui
QT += network widgets
+DEFINES += QT_USE_QSTRINGBUILDER
requires(qtConfig(udpsocket))
requires(qtConfig(listwidget))
diff --git a/examples/network/network-chat/peermanager.cpp b/examples/network/network-chat/peermanager.cpp
index 68a10b34be..a70ed7da73 100644
--- a/examples/network/network-chat/peermanager.cpp
+++ b/examples/network/network-chat/peermanager.cpp
@@ -2,20 +2,19 @@
// Copyright (C) 2018 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QtNetwork>
-
#include "client.h"
#include "connection.h"
#include "peermanager.h"
+#include <QNetworkInterface>
+#include <QUuid>
+
static const qint32 BroadcastInterval = 2000;
static const unsigned broadcastPort = 45000;
PeerManager::PeerManager(Client *client)
- : QObject(client)
+ : QObject(client), client(client)
{
- this->client = client;
-
static const char *envVariables[] = {
"USERNAME", "USER", "USERDOMAIN", "HOSTNAME", "DOMAINNAME"
};
@@ -29,8 +28,12 @@ PeerManager::PeerManager(Client *client)
if (username.isEmpty())
username = "unknown";
+ // We generate a unique per-process identifier so we can avoid multiple
+ // connections to/from the same remote peer as well as ignore our own
+ // broadcasts.
+ localUniqueId = QUuid::createUuid().toByteArray();
+
updateAddresses();
- serverPort = 0;
broadcastSocket.bind(QHostAddress::Any, broadcastPort, QUdpSocket::ShareAddress
| QUdpSocket::ReuseAddressHint);
@@ -52,6 +55,11 @@ QString PeerManager::userName() const
return username;
}
+QByteArray PeerManager::uniqueId() const
+{
+ return localUniqueId;
+}
+
void PeerManager::startBroadcasting()
{
broadcastTimer.start();
@@ -59,11 +67,7 @@ void PeerManager::startBroadcasting()
bool PeerManager::isLocalHostAddress(const QHostAddress &address) const
{
- for (const QHostAddress &localAddress : ipAddresses) {
- if (address.isEqual(localAddress))
- return true;
- }
- return false;
+ return ipAddresses.contains(address);
}
void PeerManager::sendBroadcastDatagram()
@@ -72,15 +76,14 @@ void PeerManager::sendBroadcastDatagram()
{
QCborStreamWriter writer(&datagram);
writer.startArray(2);
- writer.append(username);
+ writer.append(localUniqueId);
writer.append(serverPort);
writer.endArray();
}
bool validBroadcastAddresses = true;
- for (const QHostAddress &address : qAsConst(broadcastAddresses)) {
- if (broadcastSocket.writeDatagram(datagram, address,
- broadcastPort) == -1)
+ for (const QHostAddress &address : std::as_const(broadcastAddresses)) {
+ if (broadcastSocket.writeDatagram(datagram, address, broadcastPort) == -1)
validBroadcastAddresses = false;
}
@@ -100,6 +103,7 @@ void PeerManager::readBroadcastDatagram()
continue;
int senderServerPort;
+ QByteArray peerUniqueId;
{
// decode the datagram
QCborStreamReader reader(datagram);
@@ -109,10 +113,12 @@ void PeerManager::readBroadcastDatagram()
continue;
reader.enterContainer();
- if (reader.lastError() != QCborError::NoError || !reader.isString())
+ if (reader.lastError() != QCborError::NoError || !reader.isByteArray())
continue;
- while (reader.readString().status == QCborStreamReader::Ok) {
- // we don't actually need the username right now
+ auto r = reader.readByteArray();
+ while (r.status == QCborStreamReader::Ok) {
+ peerUniqueId = r.data;
+ r = reader.readByteArray();
}
if (reader.lastError() != QCborError::NoError || !reader.isUnsignedInteger())
@@ -120,10 +126,10 @@ void PeerManager::readBroadcastDatagram()
senderServerPort = reader.toInteger();
}
- if (isLocalHostAddress(senderIp) && senderServerPort == serverPort)
+ if (peerUniqueId == localUniqueId)
continue;
- if (!client->hasConnection(senderIp)) {
+ if (!client->hasConnection(peerUniqueId)) {
Connection *connection = new Connection(this);
emit newConnection(connection);
connection->connectToHost(senderIp, senderServerPort);
diff --git a/examples/network/network-chat/peermanager.h b/examples/network/network-chat/peermanager.h
index b9ea8053b2..fff48540ea 100644
--- a/examples/network/network-chat/peermanager.h
+++ b/examples/network/network-chat/peermanager.h
@@ -18,10 +18,11 @@ class PeerManager : public QObject
Q_OBJECT
public:
- PeerManager(Client *client);
+ explicit PeerManager(Client *client);
void setServerPort(int port);
QString userName() const;
+ QByteArray uniqueId() const;
void startBroadcasting();
bool isLocalHostAddress(const QHostAddress &address) const;
@@ -35,13 +36,14 @@ private slots:
private:
void updateAddresses();
- Client *client;
+ Client *client = nullptr;
QList<QHostAddress> broadcastAddresses;
QList<QHostAddress> ipAddresses;
QUdpSocket broadcastSocket;
QTimer broadcastTimer;
QString username;
- int serverPort;
+ QByteArray localUniqueId;
+ int serverPort = 0;
};
#endif
diff --git a/examples/network/network-chat/server.cpp b/examples/network/network-chat/server.cpp
index 1537cbb06a..afc96717ca 100644
--- a/examples/network/network-chat/server.cpp
+++ b/examples/network/network-chat/server.cpp
@@ -1,8 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include <QtNetwork>
-
#include "connection.h"
#include "server.h"
diff --git a/examples/network/network-chat/server.h b/examples/network/network-chat/server.h
index f41ffebaef..0557de30de 100644
--- a/examples/network/network-chat/server.h
+++ b/examples/network/network-chat/server.h
@@ -13,7 +13,7 @@ class Server : public QTcpServer
Q_OBJECT
public:
- Server(QObject *parent = nullptr);
+ explicit Server(QObject *parent = nullptr);
signals:
void newConnection(Connection *connection);
diff --git a/examples/network/network.pro b/examples/network/network.pro
index 3f851d7c71..a0fc95dbf8 100644
--- a/examples/network/network.pro
+++ b/examples/network/network.pro
@@ -2,29 +2,22 @@ requires(qtHaveModule(network))
TEMPLATE = subdirs
QT_FOR_CONFIG += network-private
-SUBDIRS = \
- download \
- downloadmanager
!integrity: SUBDIRS += dnslookup
qtHaveModule(widgets) {
SUBDIRS += \
blockingfortuneclient \
broadcastreceiver \
broadcastsender \
+ fortuneclient \
+ fortuneserver \
http \
- loopback \
- threadedfortuneserver \
- googlesuggest \
- torrent \
multicastreceiver \
- multicastsender
+ multicastsender \
+ rsslisting \
+ threadedfortuneserver \
+ torrent
qtConfig(processenvironment): SUBDIRS += network-chat
-
- SUBDIRS += \
- fortuneclient \
- fortuneserver
-
qtConfig(ssl): SUBDIRS += securesocketclient
qtConfig(dtls): SUBDIRS += secureudpserver secureudpclient
qtConfig(sctp): SUBDIRS += multistreamserver multistreamclient
diff --git a/examples/network/rsslisting/CMakeLists.txt b/examples/network/rsslisting/CMakeLists.txt
new file mode 100644
index 0000000000..58d9edcb92
--- /dev/null
+++ b/examples/network/rsslisting/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(rsslisting LANGUAGES CXX)
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(rsslisting
+ main.cpp
+ rsslisting.cpp rsslisting.h
+)
+
+set_target_properties(rsslisting PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(rsslisting PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
+)
+
+install(TARGETS rsslisting
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET rsslisting
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
+)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/rsslisting/main.cpp b/examples/network/rsslisting/main.cpp
new file mode 100644
index 0000000000..7a64db8a0c
--- /dev/null
+++ b/examples/network/rsslisting/main.cpp
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "rsslisting.h"
+#include <QtWidgets>
+using namespace Qt::StringLiterals;
+
+//! [0]
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ RSSListing rsslisting(u"https://www.qt.io/blog/rss.xml"_s);
+ rsslisting.show();
+ return app.exec();
+}
+//! [0]
diff --git a/examples/network/rsslisting/rsslisting.cpp b/examples/network/rsslisting/rsslisting.cpp
new file mode 100644
index 0000000000..ed7c163c76
--- /dev/null
+++ b/examples/network/rsslisting/rsslisting.cpp
@@ -0,0 +1,126 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "rsslisting.h"
+
+#include <QtCore>
+#include <QtWidgets>
+#include <QtNetwork>
+
+//! [setup]
+RSSListing::RSSListing(const QString &url, QWidget *parent)
+ : QWidget(parent), currentReply(0)
+{
+ connect(&manager, &QNetworkAccessManager::finished, this, &RSSListing::finished);
+
+ lineEdit = new QLineEdit(this);
+ lineEdit->setText(url);
+ connect(lineEdit, &QLineEdit::returnPressed, this, &RSSListing::fetch);
+
+ fetchButton = new QPushButton(tr("Fetch"), this);
+ connect(fetchButton, &QPushButton::clicked, this, &RSSListing::fetch);
+
+ treeWidget = new QTreeWidget(this);
+ connect(treeWidget, &QTreeWidget::itemActivated,
+ // Open the link in the browser:
+ this, [](QTreeWidgetItem *item) { QDesktopServices::openUrl(QUrl(item->text(1))); });
+ treeWidget->setHeaderLabels(QStringList { tr("Title"), tr("Link") });
+ treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+ QHBoxLayout *hboxLayout = new QHBoxLayout;
+ hboxLayout->addWidget(lineEdit);
+ hboxLayout->addWidget(fetchButton);
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addLayout(hboxLayout);
+ layout->addWidget(treeWidget);
+
+ setWindowTitle(tr("RSS listing example"));
+ resize(640, 480);
+}
+//! [setup]
+
+//! [slots]
+void RSSListing::fetch()
+{
+ lineEdit->setReadOnly(true);
+ fetchButton->setEnabled(false);
+ treeWidget->clear();
+
+ get(QUrl(lineEdit->text()));
+}
+
+void RSSListing::consumeData()
+{
+ int statusCode = currentReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ if (statusCode >= 200 && statusCode < 300)
+ parseXml();
+}
+
+void RSSListing::error(QNetworkReply::NetworkError)
+{
+ qWarning("error retrieving RSS feed");
+ xml.clear();
+ currentReply->disconnect(this);
+ currentReply->deleteLater();
+ currentReply = nullptr;
+}
+
+void RSSListing::finished(QNetworkReply *reply)
+{
+ Q_UNUSED(reply);
+ lineEdit->setReadOnly(false);
+ fetchButton->setEnabled(true);
+}
+//! [slots]
+
+// Private methods
+
+//! [get]
+void RSSListing::get(const QUrl &url)
+{
+ if (currentReply) {
+ currentReply->disconnect(this);
+ currentReply->deleteLater();
+ }
+ currentReply = url.isValid() ? manager.get(QNetworkRequest(url)) : nullptr;
+ if (currentReply) {
+ connect(currentReply, &QNetworkReply::readyRead, this, &RSSListing::consumeData);
+ connect(currentReply, &QNetworkReply::errorOccurred, this, &RSSListing::error);
+
+ }
+ xml.setDevice(currentReply); // Equivalent to clear() if currentReply is null.
+}
+//! [get]
+
+// TODO: this is a candidate for showing how to use coroutines, once available.
+//! [parse]
+void RSSListing::parseXml()
+{
+ while (!xml.atEnd()) {
+ xml.readNext();
+ if (xml.isStartElement()) {
+ if (xml.name() == u"item") {
+ linkString = xml.attributes().value("rss:about").toString();
+ titleString.clear();
+ }
+ currentTag = xml.name().toString();
+ } else if (xml.isEndElement()) {
+ if (xml.name() == u"item") {
+
+ QTreeWidgetItem *item = new QTreeWidgetItem;
+ item->setText(0, titleString);
+ item->setText(1, linkString);
+ treeWidget->addTopLevelItem(item);
+ }
+ } else if (xml.isCharacters() && !xml.isWhitespace()) {
+ if (currentTag == "title")
+ titleString += xml.text();
+ else if (currentTag == "link")
+ linkString += xml.text();
+ }
+ }
+ if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError)
+ qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
+}
+//! [parse]
diff --git a/examples/network/rsslisting/rsslisting.h b/examples/network/rsslisting/rsslisting.h
new file mode 100644
index 0000000000..499bc5d1d4
--- /dev/null
+++ b/examples/network/rsslisting/rsslisting.h
@@ -0,0 +1,54 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef RSSLISTING_H
+#define RSSLISTING_H
+
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QWidget>
+#include <QXmlStreamReader>
+
+QT_BEGIN_NAMESPACE
+class QLineEdit;
+class QPushButton;
+class QTreeWidget;
+class QTreeWidgetItem;
+class QUrl;
+QT_END_NAMESPACE
+
+//! [0]
+class RSSListing : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit RSSListing(const QString &url = QString(), QWidget *widget = nullptr);
+
+public slots:
+ void fetch();
+ void finished(QNetworkReply *reply);
+ void consumeData();
+ void error(QNetworkReply::NetworkError);
+
+private:
+ void parseXml();
+ void get(const QUrl &url);
+
+ // Parser state:
+ QXmlStreamReader xml;
+ QString currentTag;
+ QString linkString;
+ QString titleString;
+
+ // Network state:
+ QNetworkAccessManager manager;
+ QNetworkReply *currentReply;
+
+ // UI elements:
+ QLineEdit *lineEdit;
+ QTreeWidget *treeWidget;
+ QPushButton *fetchButton;
+};
+//! [0]
+
+#endif
diff --git a/examples/network/rsslisting/rsslisting.pro b/examples/network/rsslisting/rsslisting.pro
new file mode 100644
index 0000000000..aacbe3127f
--- /dev/null
+++ b/examples/network/rsslisting/rsslisting.pro
@@ -0,0 +1,8 @@
+HEADERS += rsslisting.h
+SOURCES += main.cpp rsslisting.cpp
+QT += network widgets
+requires(qtConfig(treewidget))
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/network/rsslisting
+INSTALLS += target
diff --git a/examples/network/securesocketclient/CMakeLists.txt b/examples/network/securesocketclient/CMakeLists.txt
index 24e7057232..8066e5eba7 100644
--- a/examples/network/securesocketclient/CMakeLists.txt
+++ b/examples/network/securesocketclient/CMakeLists.txt
@@ -4,17 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(securesocketclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/securesocketclient")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(securesocketclient
certificateinfo.cpp certificateinfo.h certificateinfo.ui
main.cpp
@@ -27,11 +20,11 @@ set_target_properties(securesocketclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(securesocketclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(securesocketclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
# Resources:
@@ -47,7 +40,14 @@ qt_add_resources(securesocketclient "securesocketclient"
)
install(TARGETS securesocketclient
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET securesocketclient
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/securesocketclient/certificateinfo.cpp b/examples/network/securesocketclient/certificateinfo.cpp
index 2d6a943d60..a5778d2e0a 100644
--- a/examples/network/securesocketclient/certificateinfo.cpp
+++ b/examples/network/securesocketclient/certificateinfo.cpp
@@ -39,19 +39,19 @@ void CertificateInfo::updateCertificateInfo(int index)
if (index >= 0 && index < certificateChain.size()) {
const QSslCertificate &cert = certificateChain.at(index);
QStringList lines;
- lines << tr("Organization: %1").arg(cert.subjectInfo(QSslCertificate::Organization).join(QLatin1Char(' ')))
- << tr("Subunit: %1").arg(cert.subjectInfo(QSslCertificate::OrganizationalUnitName).join(QLatin1Char(' ')))
- << tr("Country: %1").arg(cert.subjectInfo(QSslCertificate::CountryName).join(QLatin1Char(' ')))
- << tr("Locality: %1").arg(cert.subjectInfo(QSslCertificate::LocalityName).join(QLatin1Char(' ')))
- << tr("State/Province: %1").arg(cert.subjectInfo(QSslCertificate::StateOrProvinceName).join(QLatin1Char(' ')))
- << tr("Common Name: %1").arg(cert.subjectInfo(QSslCertificate::CommonName).join(QLatin1Char(' ')))
+ lines << tr("Organization: %1").arg(cert.subjectInfo(QSslCertificate::Organization).join(u' '))
+ << tr("Subunit: %1").arg(cert.subjectInfo(QSslCertificate::OrganizationalUnitName).join(u' '))
+ << tr("Country: %1").arg(cert.subjectInfo(QSslCertificate::CountryName).join(u' '))
+ << tr("Locality: %1").arg(cert.subjectInfo(QSslCertificate::LocalityName).join(u' '))
+ << tr("State/Province: %1").arg(cert.subjectInfo(QSslCertificate::StateOrProvinceName).join(u' '))
+ << tr("Common Name: %1").arg(cert.subjectInfo(QSslCertificate::CommonName).join(u' '))
<< QString()
- << tr("Issuer Organization: %1").arg(cert.issuerInfo(QSslCertificate::Organization).join(QLatin1Char(' ')))
- << tr("Issuer Unit Name: %1").arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName).join(QLatin1Char(' ')))
- << tr("Issuer Country: %1").arg(cert.issuerInfo(QSslCertificate::CountryName).join(QLatin1Char(' ')))
- << tr("Issuer Locality: %1").arg(cert.issuerInfo(QSslCertificate::LocalityName).join(QLatin1Char(' ')))
- << tr("Issuer State/Province: %1").arg(cert.issuerInfo(QSslCertificate::StateOrProvinceName).join(QLatin1Char(' ')))
- << tr("Issuer Common Name: %1").arg(cert.issuerInfo(QSslCertificate::CommonName).join(QLatin1Char(' ')));
+ << tr("Issuer Organization: %1").arg(cert.issuerInfo(QSslCertificate::Organization).join(u' '))
+ << tr("Issuer Unit Name: %1").arg(cert.issuerInfo(QSslCertificate::OrganizationalUnitName).join(u' '))
+ << tr("Issuer Country: %1").arg(cert.issuerInfo(QSslCertificate::CountryName).join(u' '))
+ << tr("Issuer Locality: %1").arg(cert.issuerInfo(QSslCertificate::LocalityName).join(u' '))
+ << tr("Issuer State/Province: %1").arg(cert.issuerInfo(QSslCertificate::StateOrProvinceName).join(u' '))
+ << tr("Issuer Common Name: %1").arg(cert.issuerInfo(QSslCertificate::CommonName).join(u' '));
for (const auto &line : lines)
form->certificateInfoView->addItem(line);
}
diff --git a/examples/network/securesocketclient/main.cpp b/examples/network/securesocketclient/main.cpp
index 5898bf0878..7a59e6f774 100644
--- a/examples/network/securesocketclient/main.cpp
+++ b/examples/network/securesocketclient/main.cpp
@@ -11,8 +11,6 @@ QT_REQUIRE_CONFIG(ssl);
int main(int argc, char **argv)
{
- Q_INIT_RESOURCE(securesocketclient);
-
QApplication app(argc, argv);
if (!QSslSocket::supportsSsl()) {
diff --git a/examples/network/securesocketclient/sslclient.cpp b/examples/network/securesocketclient/sslclient.cpp
index c21feaf473..413038ddd5 100644
--- a/examples/network/securesocketclient/sslclient.cpp
+++ b/examples/network/securesocketclient/sslclient.cpp
@@ -71,7 +71,7 @@ void SslClient::socketEncrypted()
const QSslCipher cipher = socket->sessionCipher();
const QString cipherInfo = QString("%1, %2 (%3/%4)").arg(cipher.authenticationMethod())
.arg(cipher.name()).arg(cipher.usedBits())
- .arg(cipher.supportedBits());;
+ .arg(cipher.supportedBits());
form->cipherLabel->setText(cipherInfo);
padLock->show();
}
diff --git a/examples/network/secureudpclient/CMakeLists.txt b/examples/network/secureudpclient/CMakeLists.txt
index 1d43cd0f4f..53a8c1340e 100644
--- a/examples/network/secureudpclient/CMakeLists.txt
+++ b/examples/network/secureudpclient/CMakeLists.txt
@@ -4,17 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(secureudpclient LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/secureudpclient")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(secureudpclient
addressdialog.cpp addressdialog.h addressdialog.ui
association.cpp association.h
@@ -27,15 +20,22 @@ set_target_properties(secureudpclient PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(secureudpclient PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(secureudpclient PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS secureudpclient
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET secureudpclient
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/secureudpclient/addressdialog.h b/examples/network/secureudpclient/addressdialog.h
index aab387cf19..4081f44709 100644
--- a/examples/network/secureudpclient/addressdialog.h
+++ b/examples/network/secureudpclient/addressdialog.h
@@ -6,17 +6,11 @@
#include <QDialog>
QT_BEGIN_NAMESPACE
-
namespace Ui {
-
class AddressDialog;
-
}
-
QT_END_NAMESPACE
-QT_USE_NAMESPACE
-
class AddressDialog : public QDialog
{
Q_OBJECT
diff --git a/examples/network/secureudpclient/association.cpp b/examples/network/secureudpclient/association.cpp
index b76a6a7155..ede8393913 100644
--- a/examples/network/secureudpclient/association.cpp
+++ b/examples/network/secureudpclient/association.cpp
@@ -3,8 +3,6 @@
#include "association.h"
-QT_BEGIN_NAMESPACE
-
DtlsAssociation::DtlsAssociation(const QHostAddress &address, quint16 port,
const QString &connectionName)
: name(connectionName),
@@ -151,5 +149,3 @@ void DtlsAssociation::pingTimeout()
++ping;
}
//! [10]
-
-QT_END_NAMESPACE
diff --git a/examples/network/secureudpclient/association.h b/examples/network/secureudpclient/association.h
index 8bb7bbc011..4822d7c0c9 100644
--- a/examples/network/secureudpclient/association.h
+++ b/examples/network/secureudpclient/association.h
@@ -6,8 +6,6 @@
#include <QtNetwork>
#include <QtCore>
-QT_BEGIN_NAMESPACE
-
//! [0]
class DtlsAssociation : public QObject
{
@@ -45,6 +43,4 @@ private:
};
//! [0]
-QT_END_NAMESPACE
-
#endif // ASSOCIATION_H
diff --git a/examples/network/secureudpclient/main.cpp b/examples/network/secureudpclient/main.cpp
index 827778769d..d0499728c8 100644
--- a/examples/network/secureudpclient/main.cpp
+++ b/examples/network/secureudpclient/main.cpp
@@ -7,8 +7,6 @@
int main(int argc, char *argv[])
{
- QT_USE_NAMESPACE
-
QApplication app(argc, argv);
MainWindow window;
window.show();
diff --git a/examples/network/secureudpclient/mainwindow.cpp b/examples/network/secureudpclient/mainwindow.cpp
index 8b9ac24c62..987eb739b9 100644
--- a/examples/network/secureudpclient/mainwindow.cpp
+++ b/examples/network/secureudpclient/mainwindow.cpp
@@ -83,7 +83,7 @@ void MainWindow::on_connectButton_clicked()
return startNewConnection(remoteAddress);
addInfoMessage(tr("Looking up the host ..."));
- lookupId = QHostInfo::lookupHost(hostName, this, SLOT(lookupFinished(QHostInfo)));
+ lookupId = QHostInfo::lookupHost(hostName, this, &MainWindow::lookupFinished);
updateUi();
}
diff --git a/examples/network/secureudpclient/mainwindow.h b/examples/network/secureudpclient/mainwindow.h
index 4e55d0f156..8b68f5787e 100644
--- a/examples/network/secureudpclient/mainwindow.h
+++ b/examples/network/secureudpclient/mainwindow.h
@@ -8,21 +8,15 @@
#include <QList>
QT_BEGIN_NAMESPACE
-
namespace Ui {
-
class MainWindow;
-
}
class QHostAddress;
class QHostInfo;
-
-class DtlsAssociation;
-
QT_END_NAMESPACE
-QT_USE_NAMESPACE
+class DtlsAssociation;
class MainWindow : public QMainWindow
{
diff --git a/examples/network/secureudpserver/CMakeLists.txt b/examples/network/secureudpserver/CMakeLists.txt
index 234602f4a3..e92186b574 100644
--- a/examples/network/secureudpserver/CMakeLists.txt
+++ b/examples/network/secureudpserver/CMakeLists.txt
@@ -4,17 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(secureudpserver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/secureudpserver")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(secureudpserver
main.cpp
mainwindow.cpp mainwindow.h mainwindow.ui
@@ -27,15 +20,22 @@ set_target_properties(secureudpserver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(secureudpserver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(secureudpserver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS secureudpserver
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET secureudpserver
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/secureudpserver/main.cpp b/examples/network/secureudpserver/main.cpp
index b144f6571c..7ec6a29aec 100644
--- a/examples/network/secureudpserver/main.cpp
+++ b/examples/network/secureudpserver/main.cpp
@@ -7,8 +7,6 @@
int main(int argc, char *argv[])
{
- QT_USE_NAMESPACE
-
QApplication a(argc, argv);
MainWindow w;
w.show();
diff --git a/examples/network/secureudpserver/mainwindow.h b/examples/network/secureudpserver/mainwindow.h
index 77cba00b5e..7c69a9b414 100644
--- a/examples/network/secureudpserver/mainwindow.h
+++ b/examples/network/secureudpserver/mainwindow.h
@@ -8,15 +8,11 @@
#include <QMainWindow>
QT_BEGIN_NAMESPACE
-
namespace Ui {
class MainWindow;
}
-
QT_END_NAMESPACE
-QT_USE_NAMESPACE
-
class MainWindow : public QMainWindow
{
Q_OBJECT
diff --git a/examples/network/secureudpserver/nicselector.h b/examples/network/secureudpserver/nicselector.h
index 1cbe56e85e..4f8bf9a85f 100644
--- a/examples/network/secureudpserver/nicselector.h
+++ b/examples/network/secureudpserver/nicselector.h
@@ -9,15 +9,11 @@
#include <QList>
QT_BEGIN_NAMESPACE
-
namespace Ui {
class NicSelector;
}
-
QT_END_NAMESPACE
-QT_USE_NAMESPACE
-
class NicSelector : public QDialog
{
Q_OBJECT
diff --git a/examples/network/secureudpserver/server.cpp b/examples/network/secureudpserver/server.cpp
index 3f39cbb739..4aa22c606b 100644
--- a/examples/network/secureudpserver/server.cpp
+++ b/examples/network/secureudpserver/server.cpp
@@ -5,8 +5,6 @@
#include <algorithm>
-QT_BEGIN_NAMESPACE
-
namespace {
QString peer_info(const QHostAddress &address, quint16 port)
@@ -213,11 +211,9 @@ void DtlsServer::decryptDatagram(QDtls *connection, const QByteArray &clientMess
//! [14]
void DtlsServer::shutdown()
{
- for (const auto &connection : qExchange(knownClients, {}))
+ for (const auto &connection : std::exchange(knownClients, {}))
connection->shutdown(&serverSocket);
serverSocket.close();
}
//! [14]
-
-QT_END_NAMESPACE
diff --git a/examples/network/secureudpserver/server.h b/examples/network/secureudpserver/server.h
index 05e41d4532..a8b6a727c8 100644
--- a/examples/network/secureudpserver/server.h
+++ b/examples/network/secureudpserver/server.h
@@ -9,8 +9,6 @@
#include <vector>
#include <memory>
-QT_BEGIN_NAMESPACE
-
//! [0]
class DtlsServer : public QObject
{
@@ -55,6 +53,4 @@ private:
};
//! [0]
-QT_END_NAMESPACE
-
#endif // SERVER_H
diff --git a/examples/network/threadedfortuneserver/CMakeLists.txt b/examples/network/threadedfortuneserver/CMakeLists.txt
index 02a7cb9474..8fc8cc416d 100644
--- a/examples/network/threadedfortuneserver/CMakeLists.txt
+++ b/examples/network/threadedfortuneserver/CMakeLists.txt
@@ -4,16 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(threadedfortuneserver LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/threadedfortuneserver")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(threadedfortuneserver
dialog.cpp dialog.h
fortuneserver.cpp fortuneserver.h
@@ -26,15 +20,22 @@ set_target_properties(threadedfortuneserver PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(threadedfortuneserver PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(threadedfortuneserver PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
install(TARGETS threadedfortuneserver
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET threadedfortuneserver
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/threadedfortuneserver/dialog.cpp b/examples/network/threadedfortuneserver/dialog.cpp
index 675f5d6520..9449cab5fa 100644
--- a/examples/network/threadedfortuneserver/dialog.cpp
+++ b/examples/network/threadedfortuneserver/dialog.cpp
@@ -26,12 +26,12 @@ Dialog::Dialog(QWidget *parent)
}
QString ipAddress;
- QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
+ const QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
- for (int i = 0; i < ipAddressesList.size(); ++i) {
- if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
- ipAddressesList.at(i).toIPv4Address()) {
- ipAddress = ipAddressesList.at(i).toString();
+
+ for (const QHostAddress &entry : ipAddressesList) {
+ if (entry != QHostAddress::LocalHost && entry.toIPv4Address()) {
+ ipAddress = entry.toString();
break;
}
}
diff --git a/examples/network/threadedfortuneserver/fortunethread.cpp b/examples/network/threadedfortuneserver/fortunethread.cpp
index 89a2acc550..8bef57599e 100644
--- a/examples/network/threadedfortuneserver/fortunethread.cpp
+++ b/examples/network/threadedfortuneserver/fortunethread.cpp
@@ -6,7 +6,7 @@
#include <QtNetwork>
//! [0]
-FortuneThread::FortuneThread(int socketDescriptor, const QString &fortune, QObject *parent)
+FortuneThread::FortuneThread(qintptr socketDescriptor, const QString &fortune, QObject *parent)
: QThread(parent), socketDescriptor(socketDescriptor), text(fortune)
{
}
@@ -25,7 +25,7 @@ void FortuneThread::run()
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
- out.setVersion(QDataStream::Qt_4_0);
+ out.setVersion(QDataStream::Qt_6_5);
out << text;
//! [3] //! [4]
diff --git a/examples/network/threadedfortuneserver/fortunethread.h b/examples/network/threadedfortuneserver/fortunethread.h
index e93a67a37a..7dae6f2e12 100644
--- a/examples/network/threadedfortuneserver/fortunethread.h
+++ b/examples/network/threadedfortuneserver/fortunethread.h
@@ -13,7 +13,7 @@ class FortuneThread : public QThread
Q_OBJECT
public:
- FortuneThread(int socketDescriptor, const QString &fortune, QObject *parent);
+ FortuneThread(qintptr socketDescriptor, const QString &fortune, QObject *parent);
void run() override;
@@ -21,7 +21,7 @@ signals:
void error(QTcpSocket::SocketError socketError);
private:
- int socketDescriptor;
+ qintptr socketDescriptor;
QString text;
};
//! [0]
diff --git a/examples/network/torrent/CMakeLists.txt b/examples/network/torrent/CMakeLists.txt
index 28823c6400..fbf974efef 100644
--- a/examples/network/torrent/CMakeLists.txt
+++ b/examples/network/torrent/CMakeLists.txt
@@ -4,17 +4,10 @@
cmake_minimum_required(VERSION 3.16)
project(torrent LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/network/torrent")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui Network Widgets)
+qt_standard_project_setup()
+
qt_add_executable(torrent
addtorrentdialog.cpp addtorrentdialog.h
addtorrentform.ui
@@ -36,23 +29,24 @@ set_target_properties(torrent PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(torrent PUBLIC
- Qt::Core
- Qt::Gui
- Qt::Network
- Qt::Widgets
+target_link_libraries(torrent PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Network
+ Qt6::Widgets
)
# Resources:
set(icons_resource_files
- "icons/1downarrow.png"
- "icons/1uparrow.png"
- "icons/bottom.png"
- "icons/exit.png"
- "icons/peertopeer.png"
- "icons/player_pause.png"
- "icons/player_play.png"
- "icons/player_stop.png"
+ "icons/1downarrow.svg"
+ "icons/1uparrow.svg"
+ "icons/bottom.svg"
+ "icons/exit.svg"
+ "icons/peertopeer.svg"
+ "icons/player_pause.svg"
+ "icons/player_play.svg"
+ "icons/player_stop.svg"
+ "icons/about.svg"
)
qt_add_resources(torrent "icons"
@@ -63,7 +57,14 @@ qt_add_resources(torrent "icons"
)
install(TARGETS torrent
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET torrent
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/network/torrent/filemanager.cpp b/examples/network/torrent/filemanager.cpp
index c86c3f2dd4..054bb1d41c 100644
--- a/examples/network/torrent/filemanager.cpp
+++ b/examples/network/torrent/filemanager.cpp
@@ -30,13 +30,13 @@ FileManager::~FileManager()
cond.wakeOne();
wait();
- for (QFile *file : qAsConst(files)) {
+ for (QFile *file : std::as_const(files)) {
file->close();
delete file;
}
}
-int FileManager::read(int pieceIndex, int offset, int length)
+qint32 FileManager::read(qint32 pieceIndex, qint32 offset, qint32 length)
{
ReadRequest request;
request.pieceIndex = pieceIndex;
@@ -55,7 +55,7 @@ int FileManager::read(int pieceIndex, int offset, int length)
return request.id;
}
-void FileManager::write(int pieceIndex, int offset, const QByteArray &data)
+void FileManager::write(qint32 pieceIndex, qint32 offset, const QByteArray &data)
{
WriteRequest request;
request.pieceIndex = pieceIndex;
@@ -71,7 +71,7 @@ void FileManager::write(int pieceIndex, int offset, const QByteArray &data)
}
}
-void FileManager::verifyPiece(int pieceIndex)
+void FileManager::verifyPiece(qint32 pieceIndex)
{
QMutexLocker locker(&mutex);
pendingVerificationRequests << pieceIndex;
@@ -83,7 +83,7 @@ void FileManager::verifyPiece(int pieceIndex)
}
}
-int FileManager::pieceLengthAt(int pieceIndex) const
+qint32 FileManager::pieceLengthAt(qint32 pieceIndex) const
{
QMutexLocker locker(&mutex);
return (sha1s.size() == pieceIndex + 1)
@@ -282,7 +282,7 @@ bool FileManager::generateFiles()
return true;
}
-QByteArray FileManager::readBlock(int pieceIndex, int offset, int length)
+QByteArray FileManager::readBlock(qint32 pieceIndex, qint32 offset, qint32 length)
{
QByteArray block;
qint64 startReadIndex = (quint64(pieceIndex) * pieceLength) + offset;
@@ -320,7 +320,7 @@ QByteArray FileManager::readBlock(int pieceIndex, int offset, int length)
return block;
}
-bool FileManager::writeBlock(int pieceIndex, int offset, const QByteArray &data)
+bool FileManager::writeBlock(qint32 pieceIndex, qint32 offset, const QByteArray &data)
{
qint64 startWriteIndex = (qint64(pieceIndex) * pieceLength) + offset;
qint64 currentIndex = 0;
@@ -373,9 +373,9 @@ void FileManager::verifyFileContents()
int oldPercent = 0;
if (!newFile) {
- int numPieces = sha1s.size();
+ qint32 numPieces = sha1s.size();
- for (int index = 0; index < numPieces; ++index) {
+ for (qint32 index = 0; index < numPieces; ++index) {
verifySinglePiece(index);
int percent = ((index + 1) * 100) / numPieces;
@@ -391,11 +391,11 @@ void FileManager::verifyFileContents()
}
// Verify all pending pieces
- for (int index : qAsConst(newPendingVerificationRequests))
+ for (int index : std::as_const(newPendingVerificationRequests))
emit pieceVerified(index, verifySinglePiece(index));
}
-bool FileManager::verifySinglePiece(int pieceIndex)
+bool FileManager::verifySinglePiece(qint32 pieceIndex)
{
QByteArray block = readBlock(pieceIndex, 0, pieceLength);
QByteArray sha1Sum = QCryptographicHash::hash(block, QCryptographicHash::Sha1);
diff --git a/examples/network/torrent/filemanager.h b/examples/network/torrent/filemanager.h
index a62461574b..9eef18a8ab 100644
--- a/examples/network/torrent/filemanager.h
+++ b/examples/network/torrent/filemanager.h
@@ -29,13 +29,13 @@ public:
inline void setMetaInfo(const MetaInfo &info) { metaInfo = info; }
inline void setDestinationFolder(const QString &directory) { destinationPath = directory; }
- int read(int pieceIndex, int offset, int length);
- void write(int pieceIndex, int offset, const QByteArray &data);
- void verifyPiece(int pieceIndex);
+ qint32 read(qint32 pieceIndex, qint32 offset, qint32 length);
+ void write(qint32 pieceIndex, qint32 offset, const QByteArray &data);
+ void verifyPiece(qint32 pieceIndex);
inline qint64 totalSize() const { return totalLength; }
- inline int pieceCount() const { return numPieces; }
- int pieceLengthAt(int pieceIndex) const;
+ inline qint32 pieceCount() const { return numPieces; }
+ qint32 pieceLengthAt(qint32 pieceIndex) const;
QBitArray completedPieces() const;
void setCompletedPieces(const QBitArray &pieces);
@@ -46,35 +46,35 @@ public slots:
void startDataVerification();
signals:
- void dataRead(int id, int pieceIndex, int offset, const QByteArray &data);
+ void dataRead(qint32 id, qint32 pieceIndex, qint32 offset, const QByteArray &data);
void error();
void verificationProgress(int percent);
void verificationDone();
- void pieceVerified(int pieceIndex, bool verified);
+ void pieceVerified(qint32 pieceIndex, bool verified);
protected:
void run() override;
private slots:
- bool verifySinglePiece(int pieceIndex);
+ bool verifySinglePiece(qint32 pieceIndex);
void wakeUp();
private:
bool generateFiles();
- QByteArray readBlock(int pieceIndex, int offset, int length);
- bool writeBlock(int pieceIndex, int offset, const QByteArray &data);
+ QByteArray readBlock(qint32 pieceIndex, qint32 offset, qint32 length);
+ bool writeBlock(qint32 pieceIndex, qint32 offset, const QByteArray &data);
void verifyFileContents();
struct WriteRequest {
- int pieceIndex;
- int offset;
+ qint32 pieceIndex;
+ qint32 offset;
QByteArray data;
};
struct ReadRequest {
- int pieceIndex;
- int offset;
- int length;
- int id;
+ qint32 pieceIndex;
+ qint32 offset;
+ qint32 length;
+ qint32 id;
};
QString errString;
diff --git a/examples/network/torrent/icons.qrc b/examples/network/torrent/icons.qrc
index 9541ef7600..5606275d92 100644
--- a/examples/network/torrent/icons.qrc
+++ b/examples/network/torrent/icons.qrc
@@ -1,12 +1,13 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/">
- <file>icons/peertopeer.png</file>
- <file>icons/1uparrow.png</file>
- <file>icons/1downarrow.png</file>
- <file>icons/bottom.png</file>
- <file>icons/player_pause.png</file>
- <file>icons/player_play.png</file>
- <file>icons/player_stop.png</file>
- <file>icons/exit.png</file>
-</qresource>
+<RCC>
+ <qresource prefix="/">
+ <file>icons/peertopeer.svg</file>
+ <file>icons/1uparrow.svg</file>
+ <file>icons/1downarrow.svg</file>
+ <file>icons/bottom.svg</file>
+ <file>icons/player_pause.svg</file>
+ <file>icons/player_play.svg</file>
+ <file>icons/player_stop.svg</file>
+ <file>icons/exit.svg</file>
+ <file>icons/about.svg</file>
+ </qresource>
</RCC>
diff --git a/examples/network/torrent/icons/1downarrow.png b/examples/network/torrent/icons/1downarrow.png
deleted file mode 100644
index 08403b82ba..0000000000
--- a/examples/network/torrent/icons/1downarrow.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/1downarrow.svg b/examples/network/torrent/icons/1downarrow.svg
new file mode 100644
index 0000000000..fc43085f59
--- /dev/null
+++ b/examples/network/torrent/icons/1downarrow.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M21.7071 7.29289C21.3166 6.90237 20.6834 6.90237 20.2929 7.29289L12 15.5858L3.70711 7.29289C3.31658 6.90237 2.68342 6.90237 2.29289 7.29289C1.90237 7.68342 1.90237 8.31658 2.29289 8.70711L11.2929 17.7071C11.6834 18.0976 12.3166 18.0976 12.7071 17.7071L21.7071 8.70711C22.0976 8.31658 22.0976 7.68342 21.7071 7.29289Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/network/torrent/icons/1uparrow.png b/examples/network/torrent/icons/1uparrow.png
deleted file mode 100644
index f044811787..0000000000
--- a/examples/network/torrent/icons/1uparrow.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/1uparrow.svg b/examples/network/torrent/icons/1uparrow.svg
new file mode 100644
index 0000000000..aaed789617
--- /dev/null
+++ b/examples/network/torrent/icons/1uparrow.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M21.7071 16.7071C21.3166 17.0976 20.6834 17.0976 20.2929 16.7071L12 8.41421L3.70711 16.7071C3.31658 17.0976 2.68342 17.0976 2.29289 16.7071C1.90237 16.3166 1.90237 15.6834 2.29289 15.2929L11.2929 6.29289C11.6834 5.90237 12.3166 5.90237 12.7071 6.29289L21.7071 15.2929C22.0976 15.6834 22.0976 16.3166 21.7071 16.7071Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/network/torrent/icons/about.svg b/examples/network/torrent/icons/about.svg
new file mode 100644
index 0000000000..2772c4fa31
--- /dev/null
+++ b/examples/network/torrent/icons/about.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12C4 7.58172 7.58172 4 12 4ZM12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2Z" fill="#0D0D0D"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11.8735 14C11.4243 14 11.0305 13.6404 11.0859 13.1913C11.1218 12.9004 11.1938 12.7598 11.2726 12.6061C11.2846 12.5827 11.2968 12.559 11.309 12.5344C11.4537 12.2427 11.8446 11.8125 12.4814 11.2438C12.742 11.025 12.9591 10.788 13.1328 10.5328C13.3065 10.2776 13.3933 10.0042 13.3933 9.7125C13.3933 9.40625 13.2775 9.12552 13.0459 8.87031C12.8143 8.6151 12.467 8.4875 12.0038 8.4875C11.4827 8.4875 11.0955 8.64062 10.8422 8.94687C10.7885 9.0118 10.7473 9.09933 10.7158 9.19697C10.5687 9.65217 10.2209 10.0625 9.74577 10.0625C9.26613 10.0625 8.88562 9.66512 9.03161 9.20479C9.18688 8.71516 9.47937 8.13493 9.99543 7.65625C10.5093 7.21875 11.1787 7 12.0038 7C12.8143 7 13.5164 7.21875 14.1098 7.65625C14.7033 8.09375 15 8.72083 15 9.5375C15 10.0188 14.8914 10.4307 14.6743 10.7734C14.4572 11.1161 14.1605 11.4771 13.7841 11.8562C13.2775 12.3375 12.9699 12.7167 12.8614 12.9938C12.834 13.0635 12.8088 13.1315 12.7863 13.2017C12.65 13.6271 12.3172 14 11.8735 14ZM12 15C12.5523 15 13 15.4477 13 16C13 16.5523 12.5523 17 12 17C11.4477 17 11 16.5523 11 16C11 15.4477 11.4477 15 12 15Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/network/torrent/icons/bottom.png b/examples/network/torrent/icons/bottom.png
deleted file mode 100644
index fe66b5d028..0000000000
--- a/examples/network/torrent/icons/bottom.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/bottom.svg b/examples/network/torrent/icons/bottom.svg
new file mode 100644
index 0000000000..44395cde25
--- /dev/null
+++ b/examples/network/torrent/icons/bottom.svg
@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="File /download_arrow_down">
+<path id="Layer01" fill-rule="evenodd" clip-rule="evenodd" d="M3 21C3 20.4477 3.44772 20 4 20H20C20.5523 20 21 20.4477 21 21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21Z" fill="#0D0D0D"/>
+<path id="Layer02" fill-rule="evenodd" clip-rule="evenodd" d="M12.7071 16.7071C12.3166 17.0976 11.6834 17.0976 11.2929 16.7071L7.93679 13.351C7.54626 12.9605 7.54626 12.3273 7.93679 11.9368C8.32731 11.5463 8.96047 11.5463 9.351 11.9368L11 13.5858L11 3.27208C11 2.71979 11.4477 2.27208 12 2.27208C12.5523 2.27208 13 2.71979 13 3.27208L13 13.5858L14.649 11.9368C15.0395 11.5463 15.6727 11.5463 16.0632 11.9368C16.4537 12.3273 16.4537 12.9605 16.0632 13.351L12.7071 16.7071Z" fill="#0D0D0D"/>
+</g>
+</svg>
diff --git a/examples/network/torrent/icons/edit_add.png b/examples/network/torrent/icons/edit_add.png
deleted file mode 100644
index 85b022e7a4..0000000000
--- a/examples/network/torrent/icons/edit_add.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/edit_add.svg b/examples/network/torrent/icons/edit_add.svg
new file mode 100644
index 0000000000..ec817193f5
--- /dev/null
+++ b/examples/network/torrent/icons/edit_add.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M11 17L11 7.00003L13 7.00003L13 17L11 17Z" fill="#0D0D0D"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7 11L17 11L17 13L7 13L7 11Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/network/torrent/icons/edit_remove.png b/examples/network/torrent/icons/edit_remove.png
deleted file mode 100644
index 93361f5225..0000000000
--- a/examples/network/torrent/icons/edit_remove.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/edit_remove.svg b/examples/network/torrent/icons/edit_remove.svg
new file mode 100644
index 0000000000..ec18b7da64
--- /dev/null
+++ b/examples/network/torrent/icons/edit_remove.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7 13V11H17V13H7Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/network/torrent/icons/exit.png b/examples/network/torrent/icons/exit.png
deleted file mode 100644
index 2f7ff43a71..0000000000
--- a/examples/network/torrent/icons/exit.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/exit.svg b/examples/network/torrent/icons/exit.svg
new file mode 100644
index 0000000000..94f5245c52
--- /dev/null
+++ b/examples/network/torrent/icons/exit.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C7.58172 20 4 16.4183 4 12C4 7.58172 7.58172 4 12 4ZM12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2Z" fill="#0D0D0D"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M8.4644 15.5355C8.07388 15.145 8.07388 14.5118 8.4644 14.1213L10.5857 12L8.46444 9.87868C8.07392 9.48815 8.07392 8.85499 8.46444 8.46446C8.85496 8.07394 9.48813 8.07394 9.87865 8.46446L12 10.5858L14.1213 8.46446C14.5118 8.07394 15.1449 8.07394 15.5355 8.46446C15.926 8.85499 15.926 9.48815 15.5355 9.87868L13.4142 12L15.5355 14.1213C15.926 14.5118 15.926 15.145 15.5355 15.5355C15.145 15.9261 14.5118 15.9261 14.1213 15.5355L12 13.4142L9.87862 15.5355C9.48809 15.9261 8.85493 15.9261 8.4644 15.5355Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/network/torrent/icons/peertopeer.png b/examples/network/torrent/icons/peertopeer.png
deleted file mode 100644
index f4856dcec5..0000000000
--- a/examples/network/torrent/icons/peertopeer.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/peertopeer.svg b/examples/network/torrent/icons/peertopeer.svg
new file mode 100644
index 0000000000..9498804cb8
--- /dev/null
+++ b/examples/network/torrent/icons/peertopeer.svg
@@ -0,0 +1,62 @@
+<svg width="128" height="128" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="App Icon-Apple-1">
+<rect id="App Icon Bg" x="62" y="62" width="900" height="900" rx="180" fill="url(#paint0_linear_1432_187)"/>
+<g id="torrent client">
+<g id="laptop_mac">
+<mask id="mask0_1432_187" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="122" y="344" width="176" height="176">
+<rect id="Bounding box" x="122" y="344" width="176" height="176" fill="#D9D9D9"/>
+</mask>
+<g mask="url(#mask0_1432_187)">
+<path id="laptop_mac_2" d="M136.667 490.667C132.633 490.667 129.181 489.231 126.308 486.358C123.436 483.486 122 480.033 122 476H151.333C147.3 476 143.847 474.564 140.975 471.692C138.103 468.819 136.667 465.367 136.667 461.333V380.667C136.667 376.633 138.103 373.181 140.975 370.308C143.847 367.436 147.3 366 151.333 366H268.667C272.7 366 276.153 367.436 279.025 370.308C281.897 373.181 283.333 376.633 283.333 380.667V461.333C283.333 465.367 281.897 468.819 279.025 471.692C276.153 474.564 272.7 476 268.667 476H298C298 480.033 296.564 483.486 293.692 486.358C290.819 489.231 287.367 490.667 283.333 490.667H136.667ZM210 483.333C212.078 483.333 213.819 482.631 215.225 481.225C216.631 479.819 217.333 478.078 217.333 476C217.333 473.922 216.631 472.181 215.225 470.775C213.819 469.369 212.078 468.667 210 468.667C207.922 468.667 206.181 469.369 204.775 470.775C203.369 472.181 202.667 473.922 202.667 476C202.667 478.078 203.369 479.819 204.775 481.225C206.181 482.631 207.922 483.333 210 483.333ZM151.333 461.333H268.667V380.667H151.333V461.333Z" fill="white"/>
+</g>
+</g>
+<g id="laptop_mac_3">
+<mask id="mask1_1432_187" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="726" y="344" width="176" height="176">
+<rect id="Bounding box_2" x="726" y="344" width="176" height="176" fill="#D9D9D9"/>
+</mask>
+<g mask="url(#mask1_1432_187)">
+<path id="laptop_mac_4" d="M740.667 490.667C736.633 490.667 733.181 489.231 730.308 486.358C727.436 483.486 726 480.033 726 476H755.333C751.3 476 747.847 474.564 744.975 471.692C742.103 468.819 740.667 465.367 740.667 461.333V380.667C740.667 376.633 742.103 373.181 744.975 370.308C747.847 367.436 751.3 366 755.333 366H872.667C876.7 366 880.153 367.436 883.025 370.308C885.897 373.181 887.333 376.633 887.333 380.667V461.333C887.333 465.367 885.897 468.819 883.025 471.692C880.153 474.564 876.7 476 872.667 476H902C902 480.033 900.564 483.486 897.692 486.358C894.819 489.231 891.367 490.667 887.333 490.667H740.667ZM814 483.333C816.078 483.333 817.819 482.631 819.225 481.225C820.631 479.819 821.333 478.078 821.333 476C821.333 473.922 820.631 472.181 819.225 470.775C817.819 469.369 816.078 468.667 814 468.667C811.922 468.667 810.181 469.369 808.775 470.775C807.369 472.181 806.667 473.922 806.667 476C806.667 478.078 807.369 479.819 808.775 481.225C810.181 482.631 811.922 483.333 814 483.333ZM755.333 461.333H872.667V380.667H755.333V461.333Z" fill="white"/>
+</g>
+</g>
+<g id="laptop_mac_5">
+<mask id="mask2_1432_187" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="248" y="682" width="176" height="176">
+<rect id="Bounding box_3" x="248" y="682" width="176" height="176" fill="#D9D9D9"/>
+</mask>
+<g mask="url(#mask2_1432_187)">
+<path id="laptop_mac_6" d="M262.667 828.667C258.633 828.667 255.181 827.231 252.308 824.358C249.436 821.486 248 818.033 248 814H277.333C273.3 814 269.847 812.564 266.975 809.692C264.103 806.819 262.667 803.367 262.667 799.333V718.667C262.667 714.633 264.103 711.181 266.975 708.308C269.847 705.436 273.3 704 277.333 704H394.667C398.7 704 402.153 705.436 405.025 708.308C407.897 711.181 409.333 714.633 409.333 718.667V799.333C409.333 803.367 407.897 806.819 405.025 809.692C402.153 812.564 398.7 814 394.667 814H424C424 818.033 422.564 821.486 419.692 824.358C416.819 827.231 413.367 828.667 409.333 828.667H262.667ZM336 821.333C338.078 821.333 339.819 820.631 341.225 819.225C342.631 817.819 343.333 816.078 343.333 814C343.333 811.922 342.631 810.181 341.225 808.775C339.819 807.369 338.078 806.667 336 806.667C333.922 806.667 332.181 807.369 330.775 808.775C329.369 810.181 328.667 811.922 328.667 814C328.667 816.078 329.369 817.819 330.775 819.225C332.181 820.631 333.922 821.333 336 821.333ZM277.333 799.333H394.667V718.667H277.333V799.333Z" fill="white"/>
+</g>
+</g>
+<g id="laptop_mac_7">
+<mask id="mask3_1432_187" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="600" y="682" width="176" height="176">
+<rect id="Bounding box_4" x="600" y="682" width="176" height="176" fill="#D9D9D9"/>
+</mask>
+<g mask="url(#mask3_1432_187)">
+<path id="laptop_mac_8" d="M614.667 828.667C610.633 828.667 607.181 827.231 604.308 824.358C601.436 821.486 600 818.033 600 814H629.333C625.3 814 621.847 812.564 618.975 809.692C616.103 806.819 614.667 803.367 614.667 799.333V718.667C614.667 714.633 616.103 711.181 618.975 708.308C621.847 705.436 625.3 704 629.333 704H746.667C750.7 704 754.153 705.436 757.025 708.308C759.897 711.181 761.333 714.633 761.333 718.667V799.333C761.333 803.367 759.897 806.819 757.025 809.692C754.153 812.564 750.7 814 746.667 814H776C776 818.033 774.564 821.486 771.692 824.358C768.819 827.231 765.367 828.667 761.333 828.667H614.667ZM688 821.333C690.078 821.333 691.819 820.631 693.225 819.225C694.631 817.819 695.333 816.078 695.333 814C695.333 811.922 694.631 810.181 693.225 808.775C691.819 807.369 690.078 806.667 688 806.667C685.922 806.667 684.181 807.369 682.775 808.775C681.369 810.181 680.667 811.922 680.667 814C680.667 816.078 681.369 817.819 682.775 819.225C684.181 820.631 685.922 821.333 688 821.333ZM629.333 799.333H746.667V718.667H629.333V799.333Z" fill="white"/>
+</g>
+</g>
+<g id="laptop_mac_9">
+<mask id="mask4_1432_187" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="424" y="130" width="176" height="176">
+<rect id="Bounding box_5" x="424" y="130" width="176" height="176" fill="#D9D9D9"/>
+</mask>
+<g mask="url(#mask4_1432_187)">
+<path id="laptop_mac_10" d="M438.667 276.667C434.633 276.667 431.181 275.231 428.308 272.358C425.436 269.486 424 266.033 424 262H453.333C449.3 262 445.847 260.564 442.975 257.692C440.103 254.819 438.667 251.367 438.667 247.333V166.667C438.667 162.633 440.103 159.181 442.975 156.308C445.847 153.436 449.3 152 453.333 152H570.667C574.7 152 578.153 153.436 581.025 156.308C583.897 159.181 585.333 162.633 585.333 166.667V247.333C585.333 251.367 583.897 254.819 581.025 257.692C578.153 260.564 574.7 262 570.667 262H600C600 266.033 598.564 269.486 595.692 272.358C592.819 275.231 589.367 276.667 585.333 276.667H438.667ZM512 269.333C514.078 269.333 515.819 268.631 517.225 267.225C518.631 265.819 519.333 264.078 519.333 262C519.333 259.922 518.631 258.181 517.225 256.775C515.819 255.369 514.078 254.667 512 254.667C509.922 254.667 508.181 255.369 506.775 256.775C505.369 258.181 504.667 259.922 504.667 262C504.667 264.078 505.369 265.819 506.775 267.225C508.181 268.631 509.922 269.333 512 269.333ZM453.333 247.333H570.667V166.667H453.333V247.333Z" fill="white"/>
+</g>
+</g>
+<path id="netweork-big" fill-rule="evenodd" clip-rule="evenodd" d="M268.007 342C302.498 294.803 350.351 257.989 406 237.126V264.006C364.55 281.188 328.176 308.144 299.754 342H268.007ZM724.246 342C695.824 308.144 659.45 281.188 618 264.006V237.126C673.649 257.989 721.502 294.803 755.993 342H724.246ZM789 520C789 576.131 772.304 628.363 743.608 672H773.017C799.072 627.355 814 575.421 814 520H789ZM512 797C534.744 797 556.848 794.259 578 789.089V814.766C556.757 819.502 534.67 822 512 822C489.33 822 467.243 819.502 446 814.766V789.089C467.152 794.259 489.256 797 512 797ZM280.392 672C251.696 628.363 235 576.131 235 520H210C210 575.421 224.928 627.355 250.983 672H280.392Z" fill="white"/>
+<g id="network">
+<path id="Vector 6" d="M512.222 357.923L602.289 630.013C602.596 630.939 601.531 631.711 600.746 631.132L369.446 460.491C368.67 459.918 369.075 458.686 370.04 458.686H653.981C654.944 458.686 655.35 459.914 654.578 460.489L425.204 631.145C424.425 631.725 423.36 630.965 423.655 630.04L510.319 357.934C510.613 357.011 511.917 357.004 512.222 357.923Z" stroke="white" stroke-width="10"/>
+<circle id="Ellipse 3" cx="512" cy="355" r="22" fill="white"/>
+<circle id="Ellipse 4" cx="366" cy="461" r="22" fill="white"/>
+<circle id="Ellipse 5" cx="658" cy="461" r="22" fill="white"/>
+<circle id="Ellipse 6" cx="423" cy="633" r="22" fill="white"/>
+<circle id="Ellipse 7" cx="600" cy="633" r="22" fill="white"/>
+</g>
+</g>
+</g>
+<defs>
+<linearGradient id="paint0_linear_1432_187" x1="131.231" y1="96.0541" x2="967.084" y2="893.654" gradientUnits="userSpaceOnUse">
+<stop stop-color="#00414A"/>
+<stop offset="1" stop-color="#0C1C1F"/>
+</linearGradient>
+</defs>
+</svg>
diff --git a/examples/network/torrent/icons/player_pause.png b/examples/network/torrent/icons/player_pause.png
deleted file mode 100644
index 8c9bcc4556..0000000000
--- a/examples/network/torrent/icons/player_pause.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/player_pause.svg b/examples/network/torrent/icons/player_pause.svg
new file mode 100644
index 0000000000..6499480ea4
--- /dev/null
+++ b/examples/network/torrent/icons/player_pause.svg
@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Player / pause-symbol">
+<path id="Layer01" fill-rule="evenodd" clip-rule="evenodd" d="M8 7C8 6.44772 8.33579 6 8.75 6H10.25C10.6642 6 11 6.44772 11 7V17C11 17.5523 10.6642 18 10.25 18H8.75C8.33579 18 8 17.5523 8 17V7Z" fill="#0D0D0D"/>
+<path id="Layer02" fill-rule="evenodd" clip-rule="evenodd" d="M13 7C13 6.44772 13.3358 6 13.75 6H15.25C15.6642 6 16 6.44772 16 7V17C16 17.5523 15.6642 18 15.25 18H13.75C13.3358 18 13 17.5523 13 17V7Z" fill="#0D0D0D"/>
+</g>
+</svg>
diff --git a/examples/network/torrent/icons/player_play.png b/examples/network/torrent/icons/player_play.png
deleted file mode 100644
index 70daa339be..0000000000
--- a/examples/network/torrent/icons/player_play.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/player_play.svg b/examples/network/torrent/icons/player_play.svg
new file mode 100644
index 0000000000..a8cce6f422
--- /dev/null
+++ b/examples/network/torrent/icons/player_play.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M17.8182 12L7.89091 6.14985L7.89091 17.8501L17.8182 12ZM19.2 13.4143C20.2667 12.7857 20.2667 11.2143 19.2 10.5857L8.4 4.22123C7.33333 3.59264 6 4.37838 6 5.63555L6 18.3644C6 19.6216 7.33333 20.4074 8.4 19.7788L19.2 13.4143Z" fill="#0D0D0D"/>
+</svg>
diff --git a/examples/network/torrent/icons/player_stop.png b/examples/network/torrent/icons/player_stop.png
deleted file mode 100644
index ce6585ae84..0000000000
--- a/examples/network/torrent/icons/player_stop.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/icons/player_stop.svg b/examples/network/torrent/icons/player_stop.svg
new file mode 100644
index 0000000000..e220f5a790
--- /dev/null
+++ b/examples/network/torrent/icons/player_stop.svg
@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Player / stop-symbol">
+<path id="Layer01" fill-rule="evenodd" clip-rule="evenodd" d="M17 7H7L7 17H17V7ZM7 5C5.89543 5 5 5.89543 5 7V17C5 18.1046 5.89543 19 7 19H17C18.1046 19 19 18.1046 19 17V7C19 5.89543 18.1046 5 17 5H7Z" fill="#0D0D0D"/>
+</g>
+</svg>
diff --git a/examples/network/torrent/icons/stop.png b/examples/network/torrent/icons/stop.png
deleted file mode 100644
index 52e593ab21..0000000000
--- a/examples/network/torrent/icons/stop.png
+++ /dev/null
Binary files differ
diff --git a/examples/network/torrent/main.cpp b/examples/network/torrent/main.cpp
index a7a795fbcc..649f33436a 100644
--- a/examples/network/torrent/main.cpp
+++ b/examples/network/torrent/main.cpp
@@ -9,8 +9,6 @@ int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- Q_INIT_RESOURCE(icons);
-
MainWindow window;
window.show();
diff --git a/examples/network/torrent/mainwindow.cpp b/examples/network/torrent/mainwindow.cpp
index 4d710953a1..9bda5bb05e 100644
--- a/examples/network/torrent/mainwindow.cpp
+++ b/examples/network/torrent/mainwindow.cpp
@@ -26,17 +26,17 @@ protected:
};
// TorrentViewDelegate is used to draw the progress bars.
-class TorrentViewDelegate : public QItemDelegate
+class TorrentViewDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
- inline TorrentViewDelegate(MainWindow *mainWindow) : QItemDelegate(mainWindow) {}
+ inline TorrentViewDelegate(MainWindow *mainWindow) : QStyledItemDelegate(mainWindow) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index ) const override
{
if (index.column() != 2) {
- QItemDelegate::paint(painter, option, index);
+ QStyledItemDelegate::paint(painter, option, index);
return;
}
@@ -80,19 +80,19 @@ MainWindow::MainWindow(QWidget *parent)
setCentralWidget(torrentView);
// Set header resize modes and initial section sizes
- QFontMetrics fm = fontMetrics();
+ const QFontMetrics fm = torrentView->fontMetrics();
QHeaderView *header = torrentView->header();
header->resizeSection(0, fm.horizontalAdvance("typical-name-for-a-torrent.torrent"));
- header->resizeSection(1, fm.horizontalAdvance(headers.at(1) + " "));
- header->resizeSection(2, fm.horizontalAdvance(headers.at(2) + " "));
- header->resizeSection(3, qMax(fm.horizontalAdvance(headers.at(3) + " "), fm.horizontalAdvance(" 1234.0 KB/s ")));
- header->resizeSection(4, qMax(fm.horizontalAdvance(headers.at(4) + " "), fm.horizontalAdvance(" 1234.0 KB/s ")));
- header->resizeSection(5, qMax(fm.horizontalAdvance(headers.at(5) + " "), fm.horizontalAdvance(tr("Downloading") + " ")));
+ header->resizeSection(1, fm.horizontalAdvance(headers.at(1) + " "));
+ header->resizeSection(2, fm.horizontalAdvance(headers.at(2) + " "));
+ header->resizeSection(3, qMax(fm.horizontalAdvance(headers.at(3) + " "), fm.horizontalAdvance(" 1234.0 KB/s ")));
+ header->resizeSection(4, qMax(fm.horizontalAdvance(headers.at(4) + " "), fm.horizontalAdvance(" 1234.0 KB/s ")));
+ header->resizeSection(5, qMax(fm.horizontalAdvance(headers.at(5) + " "), fm.horizontalAdvance(tr("Downloading") + " ")));
// Create common actions
- QAction *newTorrentAction = new QAction(QIcon(":/icons/bottom.png"), tr("Add &new torrent"), this);
- pauseTorrentAction = new QAction(QIcon(":/icons/player_pause.png"), tr("&Pause torrent"), this);
- removeTorrentAction = new QAction(QIcon(":/icons/player_stop.png"), tr("&Remove torrent"), this);
+ QAction *newTorrentAction = new QAction(QIcon(":/icons/bottom.svg"), tr("Add &new torrent"), this);
+ pauseTorrentAction = new QAction(QIcon(":/icons/player_pause.svg"), tr("&Pause torrent"), this);
+ removeTorrentAction = new QAction(QIcon(":/icons/player_stop.svg"), tr("&Remove torrent"), this);
// File menu
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
@@ -100,12 +100,12 @@ MainWindow::MainWindow(QWidget *parent)
fileMenu->addAction(pauseTorrentAction);
fileMenu->addAction(removeTorrentAction);
fileMenu->addSeparator();
- fileMenu->addAction(QIcon(":/icons/exit.png"), tr("E&xit"), this, &MainWindow::close);
+ fileMenu->addAction(QIcon(":/icons/exit.svg"), tr("E&xit"), this, &MainWindow::close);
// Help menu
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
- helpMenu->addAction(tr("&About"), this, &MainWindow::about);
- helpMenu->addAction(tr("About &Qt"), qApp, QApplication::aboutQt);
+ helpMenu->addAction(QIcon(":/icons/about.svg"), tr("&About"), this, &MainWindow::about);
+ helpMenu->addAction(QIcon(":/icons/about.svg"), tr("About &Qt"), qApp, QApplication::aboutQt);
// Top toolbar
QToolBar *topBar = new QToolBar(tr("Tools"));
@@ -115,8 +115,8 @@ MainWindow::MainWindow(QWidget *parent)
topBar->addAction(removeTorrentAction);
topBar->addAction(pauseTorrentAction);
topBar->addSeparator();
- downActionTool = topBar->addAction(QIcon(tr(":/icons/1downarrow.png")), tr("Move down"));
- upActionTool = topBar->addAction(QIcon(tr(":/icons/1uparrow.png")), tr("Move up"));
+ downActionTool = topBar->addAction(QIcon(tr(":/icons/1downarrow.svg")), tr("Move down"));
+ upActionTool = topBar->addAction(QIcon(tr(":/icons/1uparrow.svg")), tr("Move up"));
// Bottom toolbar
QToolBar *bottomBar = new QToolBar(tr("Rate control"));
@@ -311,7 +311,7 @@ bool MainWindow::addTorrent(const QString &fileName, const QString &destinationF
const QByteArray &resumeState)
{
// Check if the torrent is already being downloaded.
- for (const Job &job : qAsConst(jobs)) {
+ for (const Job &job : std::as_const(jobs)) {
if (job.torrentFileName == fileName && job.destinationDirectory == destinationFolder) {
QMessageBox::warning(this, tr("Already downloading"),
tr("The torrent file %1 is "
@@ -462,10 +462,10 @@ void MainWindow::setActionsEnabled()
pauseTorrentAction->setEnabled(item && pauseEnabled);
if (client && client->state() == TorrentClient::Paused) {
- pauseTorrentAction->setIcon(QIcon(":/icons/player_play.png"));
+ pauseTorrentAction->setIcon(QIcon(":/icons/player_play.svg"));
pauseTorrentAction->setText(tr("Resume torrent"));
} else {
- pauseTorrentAction->setIcon(QIcon(":/icons/player_pause.png"));
+ pauseTorrentAction->setIcon(QIcon(":/icons/player_pause.svg"));
pauseTorrentAction->setText(tr("Pause torrent"));
}
@@ -575,7 +575,10 @@ void MainWindow::setDownloadLimit(int value)
void MainWindow::about()
{
QLabel *icon = new QLabel;
- icon->setPixmap(QPixmap(":/icons/peertopeer.png"));
+ QImage img(":/icons/peertopeer.svg");
+ QPixmap pm;
+ pm.convertFromImage(img);
+ icon->setPixmap(pm);
QLabel *text = new QLabel;
text->setWordWrap(true);
@@ -644,7 +647,7 @@ void MainWindow::closeEvent(QCloseEvent *)
// them to signal that they have stopped.
jobsToStop = 0;
jobsStopped = 0;
- for (const Job &job : qAsConst(jobs)) {
+ for (const Job &job : std::as_const(jobs)) {
++jobsToStop;
TorrentClient *client = job.client;
client->disconnect();
diff --git a/examples/network/torrent/metainfo.h b/examples/network/torrent/metainfo.h
index 5ef6a66827..e2717d6e73 100644
--- a/examples/network/torrent/metainfo.h
+++ b/examples/network/torrent/metainfo.h
@@ -17,7 +17,7 @@ struct MetaInfoSingleFile
qint64 length;
QByteArray md5sum;
QString name;
- int pieceLength;
+ qint32 pieceLength;
QList<QByteArray> sha1Sums;
};
diff --git a/examples/network/torrent/peerwireclient.cpp b/examples/network/torrent/peerwireclient.cpp
index 5da9a989af..349371afbf 100644
--- a/examples/network/torrent/peerwireclient.cpp
+++ b/examples/network/torrent/peerwireclient.cpp
@@ -5,36 +5,19 @@
#include <QHostAddress>
#include <QTimerEvent>
+#include <QtEndian>
-static const int PendingRequestTimeout = 60 * 1000;
-static const int ClientTimeout = 120 * 1000;
-static const int ConnectTimeout = 60 * 1000;
-static const int KeepAliveInterval = 30 * 1000;
-static const int RateControlTimerDelay = 2000;
+#include <chrono>
+
+static constexpr std::chrono::seconds PendingRequestTimeout(60);
+static constexpr std::chrono::seconds ClientTimeout(120);
+static constexpr std::chrono::seconds ConnectTimeout(60);
+static constexpr std::chrono::seconds KeepAliveInterval(30);
+static constexpr std::chrono::seconds PeerRateControlTimerDelay(2);
static const int MinimalHeaderSize = 48;
static const char ProtocolId[] = "BitTorrent protocol";
static const char ProtocolIdSize = 19;
-// Reads a 32bit unsigned int from data in network order.
-static inline quint32 fromNetworkData(const char *data)
-{
- const unsigned char *udata = (const unsigned char *)data;
- return (quint32(udata[0]) << 24)
- | (quint32(udata[1]) << 16)
- | (quint32(udata[2]) << 8)
- | (quint32(udata[3]));
-}
-
-// Writes a 32bit unsigned int from num to data in network order.
-static inline void toNetworkData(quint32 num, char *data)
-{
- unsigned char *udata = (unsigned char *)data;
- udata[3] = (num & 0xff);
- udata[2] = (num & 0xff00) >> 8;
- udata[1] = (num & 0xff0000) >> 16;
- udata[0] = (num & 0xff000000) >> 24;
-}
-
// Constructs an unconnected PeerWire client and starts the connect timer.
PeerWireClient::PeerWireClient(const QByteArray &peerId, QObject *parent)
: QTcpSocket(parent), pendingBlockSizes(0),
@@ -45,7 +28,7 @@ PeerWireClient::PeerWireClient(const QByteArray &peerId, QObject *parent)
memset(uploadSpeedData, 0, sizeof(uploadSpeedData));
memset(downloadSpeedData, 0, sizeof(downloadSpeedData));
- transferSpeedTimer = startTimer(RateControlTimerDelay);
+ transferSpeedTimer = startTimer(PeerRateControlTimerDelay);
timeoutTimer = startTimer(ConnectTimeout);
peerIdString = peerId;
@@ -71,7 +54,7 @@ PeerWireClient::PeerWireClient(const QByteArray &peerId, QObject *parent)
// Registers the peer ID and SHA1 sum of the torrent, and initiates
// the handshake.
-void PeerWireClient::initialize(const QByteArray &infoHash, int pieceCount)
+void PeerWireClient::initialize(const QByteArray &infoHash, qint32 pieceCount)
{
this->infoHash = infoHash;
peerPieces.resize(pieceCount);
@@ -159,13 +142,13 @@ void PeerWireClient::sendNotInterested()
// Sends a piece notification / a "have" message, informing the peer
// that we have just downloaded a new piece.
-void PeerWireClient::sendPieceNotification(int piece)
+void PeerWireClient::sendPieceNotification(qint32 piece)
{
if (!sentHandShake)
sendHandShake();
char message[] = {0, 0, 0, 5, 4, 0, 0, 0, 0};
- toNetworkData(piece, &message[5]);
+ qToBigEndian(piece, &message[5]);
write(message, sizeof(message));
}
@@ -194,22 +177,22 @@ void PeerWireClient::sendPieceList(const QBitArray &bitField)
}
char message[] = {0, 0, 0, 1, 5};
- toNetworkData(bits.size() + 1, &message[0]);
+ qToBigEndian<qint32>(bits.size() + 1, &message[0]);
write(message, sizeof(message));
write(bits);
}
// Sends a request for a block.
-void PeerWireClient::requestBlock(int piece, int offset, int length)
+void PeerWireClient::requestBlock(qint32 piece, qint32 offset, qint32 length)
{
char message[] = {0, 0, 0, 1, 6};
- toNetworkData(13, &message[0]);
+ qToBigEndian(13, &message[0]);
write(message, sizeof(message));
char numbers[4 * 3];
- toNetworkData(piece, &numbers[0]);
- toNetworkData(offset, &numbers[4]);
- toNetworkData(length, &numbers[8]);
+ qToBigEndian(piece, &numbers[0]);
+ qToBigEndian(offset, &numbers[4]);
+ qToBigEndian(length, &numbers[8]);
write(numbers, sizeof(numbers));
incoming << TorrentBlock(piece, offset, length);
@@ -223,33 +206,33 @@ void PeerWireClient::requestBlock(int piece, int offset, int length)
}
// Cancels a request for a block.
-void PeerWireClient::cancelRequest(int piece, int offset, int length)
+void PeerWireClient::cancelRequest(qint32 piece, qint32 offset, qint32 length)
{
char message[] = {0, 0, 0, 1, 8};
- toNetworkData(13, &message[0]);
+ qToBigEndian(13, &message[0]);
write(message, sizeof(message));
char numbers[4 * 3];
- toNetworkData(piece, &numbers[0]);
- toNetworkData(offset, &numbers[4]);
- toNetworkData(length, &numbers[8]);
+ qToBigEndian(piece, &numbers[0]);
+ qToBigEndian(offset, &numbers[4]);
+ qToBigEndian(length, &numbers[8]);
write(numbers, sizeof(numbers));
incoming.removeAll(TorrentBlock(piece, offset, length));
}
// Sends a block to the peer.
-void PeerWireClient::sendBlock(int piece, int offset, const QByteArray &data)
+void PeerWireClient::sendBlock(qint32 piece, qint32 offset, const QByteArray &data)
{
QByteArray block;
char message[] = {0, 0, 0, 1, 7};
- toNetworkData(9 + data.size(), &message[0]);
+ qToBigEndian<qint32>(9 + data.size(), &message[0]);
block += QByteArray(message, sizeof(message));
char numbers[4 * 2];
- toNetworkData(piece, &numbers[0]);
- toNetworkData(offset, &numbers[4]);
+ qToBigEndian(piece, &numbers[0]);
+ qToBigEndian(offset, &numbers[4]);
block += QByteArray(numbers, sizeof(numbers));
block += data;
@@ -468,7 +451,7 @@ void PeerWireClient::processIncomingData()
char tmp[4];
read(tmp, sizeof(tmp));
- nextPacketLength = fromNetworkData(tmp);
+ nextPacketLength = qFromBigEndian<qint32>(tmp);
if (nextPacketLength < 0 || nextPacketLength > 200000) {
// Prevent DoS
@@ -520,7 +503,7 @@ void PeerWireClient::processIncomingData()
break;
case HavePacket: {
// The peer has a new piece available.
- quint32 index = fromNetworkData(&packet.data()[1]);
+ quint32 index = qFromBigEndian<quint32>(&packet.data()[1]);
if (index < quint32(peerPieces.size())) {
// Only accept indexes within the valid range.
peerPieces.setBit(int(index));
@@ -533,7 +516,7 @@ void PeerWireClient::processIncomingData()
for (int i = 1; i < packet.size(); ++i) {
for (int bit = 0; bit < 8; ++bit) {
if (packet.at(i) & (1 << (7 - bit))) {
- int bitIndex = int(((i - 1) * 8) + bit);
+ qint32 bitIndex = qint32(((i - 1) * 8) + bit);
if (bitIndex >= 0 && bitIndex < peerPieces.size()) {
// Occasionally, broken clients claim to have
// pieces whose index is outside the valid range.
@@ -548,15 +531,15 @@ void PeerWireClient::processIncomingData()
break;
case RequestPacket: {
// The peer requests a block.
- quint32 index = fromNetworkData(&packet.data()[1]);
- quint32 begin = fromNetworkData(&packet.data()[5]);
- quint32 length = fromNetworkData(&packet.data()[9]);
- emit blockRequested(int(index), int(begin), int(length));
+ quint32 index = qFromBigEndian<quint32>(&packet.data()[1]);
+ quint32 begin = qFromBigEndian<quint32>(&packet.data()[5]);
+ quint32 length = qFromBigEndian<quint32>(&packet.data()[9]);
+ emit blockRequested(qint32(index), qint32(begin), qint32(length));
break;
}
case PiecePacket: {
- int index = int(fromNetworkData(&packet.data()[1]));
- int begin = int(fromNetworkData(&packet.data()[5]));
+ qint32 index = qint32(qFromBigEndian<quint32>(&packet.data()[1]));
+ qint32 begin = qint32(qFromBigEndian<quint32>(&packet.data()[5]));
incoming.removeAll(TorrentBlock(index, begin, packet.size() - 9));
@@ -572,14 +555,14 @@ void PeerWireClient::processIncomingData()
}
case CancelPacket: {
// The peer cancels a block request.
- quint32 index = fromNetworkData(&packet.data()[1]);
- quint32 begin = fromNetworkData(&packet.data()[5]);
- quint32 length = fromNetworkData(&packet.data()[9]);
+ quint32 index = qFromBigEndian<quint32>(&packet.data()[1]);
+ quint32 begin = qFromBigEndian<quint32>(&packet.data()[5]);
+ quint32 length = qFromBigEndian<quint32>(&packet.data()[9]);
for (int i = 0; i < pendingBlocks.size(); ++i) {
const BlockInfo &blockInfo = pendingBlocks.at(i);
- if (blockInfo.pieceIndex == int(index)
- && blockInfo.offset == int(begin)
- && blockInfo.length == int(length)) {
+ if (blockInfo.pieceIndex == qint32(index)
+ && blockInfo.offset == qint32(begin)
+ && blockInfo.length == qint32(length)) {
pendingBlocks.removeAt(i);
break;
}
diff --git a/examples/network/torrent/peerwireclient.h b/examples/network/torrent/peerwireclient.h
index 96e6ac6ed2..a605ea1cbf 100644
--- a/examples/network/torrent/peerwireclient.h
+++ b/examples/network/torrent/peerwireclient.h
@@ -16,7 +16,7 @@ class TorrentPeer;
struct TorrentBlock
{
- inline TorrentBlock(int p, int o, int l)
+ inline TorrentBlock(qint32 p, qint32 o, qint32 l)
: pieceIndex(p), offset(o), length(l)
{
}
@@ -27,9 +27,9 @@ struct TorrentBlock
&& length == other.length;
}
- int pieceIndex;
- int offset;
- int length;
+ qint32 pieceIndex;
+ qint32 offset;
+ qint32 length;
};
class PeerWireClient : public QTcpSocket
diff --git a/examples/network/torrent/ratecontroller.cpp b/examples/network/torrent/ratecontroller.cpp
index 3dd256a0f6..338bb596c9 100644
--- a/examples/network/torrent/ratecontroller.cpp
+++ b/examples/network/torrent/ratecontroller.cpp
@@ -33,7 +33,7 @@ void RateController::removeSocket(PeerWireClient *socket)
void RateController::setDownloadLimit(int bytesPerSecond)
{
downLimit = bytesPerSecond;
- for (PeerWireClient *socket : qAsConst(sockets))
+ for (PeerWireClient *socket : std::as_const(sockets))
socket->setReadBufferSize(downLimit * 4);
}
@@ -42,7 +42,7 @@ void RateController::scheduleTransfer()
if (transferScheduled)
return;
transferScheduled = true;
- QTimer::singleShot(50, this, SLOT(transfer()));
+ QTimer::singleShot(50, this, &RateController::transfer);
}
void RateController::transfer()
@@ -63,7 +63,7 @@ void RateController::transfer()
}
QSet<PeerWireClient *> pendingSockets;
- for (PeerWireClient *client : qAsConst(sockets)) {
+ for (PeerWireClient *client : std::as_const(sockets)) {
if (client->canTransferMore())
pendingSockets << client;
}
diff --git a/examples/network/torrent/torrentclient.cpp b/examples/network/torrent/torrentclient.cpp
index fcc1b285f1..d9e66b9a17 100644
--- a/examples/network/torrent/torrentclient.cpp
+++ b/examples/network/torrent/torrentclient.cpp
@@ -14,6 +14,7 @@
#include <QNetworkInterface>
#include <algorithm>
+#include <chrono>
// These constants could also be configurable by the user.
static const int ServerMinPort = 6881;
@@ -23,10 +24,10 @@ static const int MaxBlocksInProgress = 5;
static const int MaxBlocksInMultiMode = 2;
static const int MaxConnectionPerPeer = 1;
static const int RateControlWindowLength = 10;
-static const int RateControlTimerDelay = 1000;
+static const std::chrono::seconds RateControlTimerDelay(1);
static const int MinimumTimeBeforeRevisit = 30;
static const int MaxUploads = 4;
-static const int UploadScheduleInterval = 10000;
+static const std::chrono::seconds UploadScheduleInterval(10);
struct TorrentPiece {
QBitArray completedBlocks;
@@ -69,9 +70,9 @@ public:
int uploadScheduleTimer;
// Pieces
- QMap<int, PeerWireClient *> readIds;
+ QMap<qint32, PeerWireClient *> readIds;
QMultiMap<PeerWireClient *, TorrentPiece *> payloads;
- QMap<int, TorrentPiece *> pendingPieces;
+ QMap<qint32, TorrentPiece *> pendingPieces;
QBitArray completedPieces;
QBitArray incompletePieces;
int pieceCount;
@@ -207,6 +208,10 @@ TorrentClient::TorrentClient(QObject *parent)
TorrentClient::~TorrentClient()
{
+ auto rateController = RateController::instance();
+ const auto childSockets = findChildren<PeerWireClient *>(Qt::FindDirectChildrenOnly);
+ for (PeerWireClient *socket : childSockets)
+ rateController->removeSocket(socket);
qDeleteAll(d->peers);
qDeleteAll(d->pendingPieces);
delete d;
@@ -264,8 +269,8 @@ void TorrentClient::setDumpedState(const QByteArray &dumpedState)
stream >> d->completedPieces;
while (!stream.atEnd()) {
- int index;
- int length;
+ qint32 index;
+ qint32 length;
QBitArray completed;
stream >> index >> length >> completed;
if (stream.status() != QDataStream::Ok) {
@@ -293,7 +298,7 @@ QByteArray TorrentClient::dumpedState() const
// Save the state of all partially downloaded pieces into a format
// suitable for storing in settings.
- QMap<int, TorrentPiece *>::ConstIterator it = d->pendingPieces.constBegin();
+ auto it = d->pendingPieces.constBegin();
while (it != d->pendingPieces.constEnd()) {
TorrentPiece *piece = it.value();
if (blocksLeftForPiece(piece) > 0 && blocksLeftForPiece(piece) < piece->completedBlocks.size()) {
@@ -416,7 +421,7 @@ void TorrentClient::stop()
}
// Abort all existing connections
- for (PeerWireClient *client : qAsConst(d->connections)) {
+ for (PeerWireClient *client : std::as_const(d->connections)) {
RateController::instance()->removeSocket(client);
ConnectionManager::instance()->removeConnection(client);
client->abort();
@@ -439,7 +444,7 @@ void TorrentClient::setPaused(bool paused)
// connections to 0. Keep the list of peers, so we can quickly
// resume later.
d->setState(Paused);
- for (PeerWireClient *client : qAsConst(d->connections))
+ for (PeerWireClient *client : std::as_const(d->connections))
client->abort();
d->connections.clear();
TorrentServer::instance()->removeClient(this);
@@ -492,7 +497,8 @@ void TorrentClient::timerEvent(QTimerEvent *event)
}
}
-void TorrentClient::sendToPeer(int readId, int pieceIndex, int begin, const QByteArray &data)
+void TorrentClient::sendToPeer(qint32 readId, qint32 pieceIndex, qint32 begin,
+ const QByteArray &data)
{
// Send the requested block to the peer if the client connection
// still exists; otherwise do nothing. This slot is called by the
@@ -511,7 +517,7 @@ void TorrentClient::fullVerificationDone()
d->completedPieces = d->fileManager.completedPieces();
d->incompletePieces.resize(d->completedPieces.size());
d->pieceCount = d->completedPieces.size();
- for (int i = 0; i < d->fileManager.pieceCount(); ++i) {
+ for (qint32 i = 0; i < d->fileManager.pieceCount(); ++i) {
if (!d->completedPieces.testBit(i))
d->incompletePieces.setBit(i);
}
@@ -520,7 +526,7 @@ void TorrentClient::fullVerificationDone()
// If the checksums show that what the dumped state thought was
// partial was in fact complete, then we trust the checksums.
- QMap<int, TorrentPiece *>::Iterator it = d->pendingPieces.begin();
+ auto it = d->pendingPieces.begin();
while (it != d->pendingPieces.end()) {
if (d->completedPieces.testBit(it.key()))
it = d->pendingPieces.erase(it);
@@ -550,7 +556,7 @@ void TorrentClient::fullVerificationDone()
d->trackerClient.start(d->metaInfo);
}
-void TorrentClient::pieceVerified(int pieceIndex, bool ok)
+void TorrentClient::pieceVerified(qint32 pieceIndex, bool ok)
{
TorrentPiece *piece = d->pendingPieces.value(pieceIndex);
@@ -574,11 +580,11 @@ void TorrentClient::pieceVerified(int pieceIndex, bool ok)
}
// Update the peer list so we know who's still interesting.
- for (TorrentPeer *peer : qAsConst(d->peers)) {
+ for (TorrentPeer *peer : std::as_const(d->peers)) {
if (!peer->interesting)
continue;
bool interesting = false;
- for (int i = 0; i < d->pieceCount; ++i) {
+ for (qint32 i = 0; i < d->pieceCount; ++i) {
if (peer->pieces.testBit(i) && d->incompletePieces.testBit(i)) {
interesting = true;
break;
@@ -594,7 +600,7 @@ void TorrentClient::pieceVerified(int pieceIndex, bool ok)
d->incompletePieces.clearBit(pieceIndex);
// Notify connected peers.
- for (PeerWireClient *client : qAsConst(d->connections)) {
+ for (PeerWireClient *client : std::as_const(d->connections)) {
if (client->state() == QAbstractSocket::ConnectedState
&& !client->availablePieces().testBit(pieceIndex)) {
client->sendPieceNotification(pieceIndex);
@@ -672,9 +678,9 @@ QList<TorrentPeer *> TorrentClient::weighedFreePeers() const
qint64 now = QDateTime::currentSecsSinceEpoch();
QList<TorrentPeer *> freePeers;
QMap<QString, int> connectionsPerPeer;
- for (TorrentPeer *peer : qAsConst(d->peers)) {
+ for (TorrentPeer *peer : std::as_const(d->peers)) {
bool busy = false;
- for (PeerWireClient *client : qAsConst(d->connections)) {
+ for (PeerWireClient *client : std::as_const(d->connections)) {
if (client->state() == PeerWireClient::ConnectedState
&& client->peerAddress() == peer->address
&& client->peerPort() == peer->port) {
@@ -694,7 +700,7 @@ QList<TorrentPeer *> TorrentClient::weighedFreePeers() const
// Assign points based on connection speed and pieces available.
QList<QPair<int, TorrentPeer *> > points;
- for (TorrentPeer *peer : qAsConst(freePeers)) {
+ for (TorrentPeer *peer : std::as_const(freePeers)) {
int tmp = 0;
if (peer->interesting) {
tmp += peer->numCompletedPieces;
@@ -717,7 +723,7 @@ QList<TorrentPeer *> TorrentClient::weighedFreePeers() const
QMultiMap<int, TorrentPeer *> pointMap;
int lowestScore = 0;
int lastIndex = 0;
- for (const PointPair &point : qAsConst(points)) {
+ for (const PointPair &point : std::as_const(points)) {
if (point.first > lowestScore) {
lowestScore = point.first;
++lastIndex;
@@ -768,7 +774,7 @@ void TorrentClient::setupOutgoingConnection()
PeerWireClient *client = qobject_cast<PeerWireClient *>(sender());
// Update connection statistics.
- for (TorrentPeer *peer : qAsConst(d->peers)) {
+ for (TorrentPeer *peer : std::as_const(d->peers)) {
if (peer->port == client->peerPort() && peer->address == client->peerAddress()) {
peer->connectTime = peer->lastVisited - peer->connectStart;
break;
@@ -896,8 +902,8 @@ void TorrentClient::peerPiecesAvailable(const QBitArray &pieces)
// Check for interesting pieces, and tell the peer whether we are
// interested or not.
bool interested = false;
- int piecesSize = pieces.size();
- for (int pieceIndex = 0; pieceIndex < piecesSize; ++pieceIndex) {
+ qint32 piecesSize = pieces.size();
+ for (qint32 pieceIndex = 0; pieceIndex < piecesSize; ++pieceIndex) {
if (!pieces.testBit(pieceIndex))
continue;
if (!d->completedPieces.testBit(pieceIndex)) {
@@ -909,7 +915,7 @@ void TorrentClient::peerPiecesAvailable(const QBitArray &pieces)
}
QMultiMap<PeerWireClient *, TorrentPiece *>::Iterator it = d->payloads.find(client);
- int inProgress = 0;
+ qint32 inProgress = 0;
while (it != d->payloads.end() && it.key() == client) {
if (it.value()->inProgress)
inProgress += it.value()->requestedBlocks.count(true);
@@ -927,7 +933,7 @@ void TorrentClient::peerPiecesAvailable(const QBitArray &pieces)
}
}
-void TorrentClient::peerRequestsBlock(int pieceIndex, int begin, int length)
+void TorrentClient::peerRequestsBlock(qint32 pieceIndex, qint32 begin, qint32 length)
{
PeerWireClient *client = qobject_cast<PeerWireClient *>(sender());
@@ -944,7 +950,7 @@ void TorrentClient::peerRequestsBlock(int pieceIndex, int begin, int length)
qobject_cast<PeerWireClient *>(sender()));
}
-void TorrentClient::blockReceived(int pieceIndex, int begin, const QByteArray &data)
+void TorrentClient::blockReceived(qint32 pieceIndex, qint32 begin, const QByteArray &data)
{
PeerWireClient *client = qobject_cast<PeerWireClient *>(sender());
if (data.size() == 0) {
@@ -953,7 +959,7 @@ void TorrentClient::blockReceived(int pieceIndex, int begin, const QByteArray &d
}
// Ignore it if we already have this block.
- int blockBit = begin / BlockSize;
+ qint32 blockBit = begin / BlockSize;
TorrentPiece *piece = d->pendingPieces.value(pieceIndex);
if (!piece || piece->completedBlocks.testBit(blockBit)) {
// Discard blocks that we already have, and fill up the pipeline.
@@ -1021,15 +1027,9 @@ void TorrentClient::peerWireBytesReceived(qint64 size)
emit dataSent(size);
}
-int TorrentClient::blocksLeftForPiece(const TorrentPiece *piece) const
+qint32 TorrentClient::blocksLeftForPiece(const TorrentPiece *piece) const
{
- int blocksLeft = 0;
- int completedBlocksSize = piece->completedBlocks.size();
- for (int i = 0; i < completedBlocksSize; ++i) {
- if (!piece->completedBlocks.testBit(i))
- ++blocksLeft;
- }
- return blocksLeft;
+ return piece->completedBlocks.count(false);
}
void TorrentClient::scheduleUploads()
@@ -1040,7 +1040,7 @@ void TorrentClient::scheduleUploads()
// no use in unchoking them.
QList<PeerWireClient *> allClients = d->connections;
QList<QPair<qint64, PeerWireClient *>> transferSpeeds;
- for (PeerWireClient *client : qAsConst(allClients)) {
+ for (PeerWireClient *client : std::as_const(allClients)) {
if (client->state() == QAbstractSocket::ConnectedState
&& client->availablePieces().count(true) != d->pieceCount) {
if (d->state == Seeding) {
@@ -1098,7 +1098,7 @@ void TorrentClient::scheduleDownloads()
// Check what each client is doing, and assign payloads to those
// who are either idle or done.
- for (PeerWireClient *client : qAsConst(d->connections))
+ for (PeerWireClient *client : std::as_const(d->connections))
schedulePieceForClient(client);
}
@@ -1114,7 +1114,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client)
// Make a list of all the client's pending pieces, and count how
// many blocks have been requested.
- QList<int> currentPieces;
+ QList<qint32> currentPieces;
bool somePiecesAreNotInProgress = false;
TorrentPiece *lastPendingPiece = nullptr;
QMultiMap<PeerWireClient *, TorrentPiece *>::Iterator it = d->payloads.find(client);
@@ -1165,7 +1165,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client)
// the same piece. In endgame mode, this only applies to
// clients that are currently uploading (more than 1.0KB/s).
if ((d->state == Endgame && client->uploadSpeed() < 1024) || d->state != WarmingUp) {
- QMap<int, TorrentPiece *>::ConstIterator it = d->pendingPieces.constBegin();
+ auto it = d->pendingPieces.constBegin();
while (it != d->pendingPieces.constEnd()) {
if (it.value()->inProgress)
incompletePiecesAvailableToClient.clearBit(it.key());
@@ -1177,7 +1177,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client)
incompletePiecesAvailableToClient &= client->availablePieces();
// Remove all pieces that this client has already requested.
- for (int i : qAsConst(currentPieces))
+ for (qint32 i : std::as_const(currentPieces))
incompletePiecesAvailableToClient.clearBit(i);
// Only continue if more pieces can be scheduled. If no pieces
@@ -1189,7 +1189,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client)
// Check if any of the partially completed pieces can be
// recovered, and if so, pick a random one of them.
QList<TorrentPiece *> partialPieces;
- QMap<int, TorrentPiece *>::ConstIterator it = d->pendingPieces.constBegin();
+ auto it = d->pendingPieces.constBegin();
while (it != d->pendingPieces.constEnd()) {
TorrentPiece *tmp = it.value();
if (incompletePiecesAvailableToClient.testBit(it.key())) {
@@ -1213,7 +1213,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client)
memset(occurrences, 0, d->pieceCount * sizeof(int));
// Count how many of each piece are available.
- for (PeerWireClient *peer : qAsConst(d->connections)) {
+ for (PeerWireClient *peer : std::as_const(d->connections)) {
QBitArray peerPieces = peer->availablePieces();
int peerPiecesSize = peerPieces.size();
for (int i = 0; i < peerPiecesSize; ++i) {
@@ -1311,7 +1311,7 @@ void TorrentClient::requestMore(PeerWireClient *client)
// Starting with the first piece that we're waiting for, request
// blocks until the quota is filled up.
- for (TorrentPiece *piece : qAsConst(piecesInProgress)) {
+ for (TorrentPiece *piece : std::as_const(piecesInProgress)) {
numBlocksInProgress += requestBlocks(client, piece, maxInProgress - numBlocksInProgress);
if (numBlocksInProgress == maxInProgress)
break;
@@ -1414,7 +1414,7 @@ void TorrentClient::addToPeerList(const QList<TorrentPeer> &peerList)
}
bool known = false;
- for (const TorrentPeer *knownPeer : qAsConst(d->peers)) {
+ for (const TorrentPeer *knownPeer : std::as_const(d->peers)) {
if (knownPeer->port == peer.port
&& knownPeer->address == peer.address) {
known = true;
@@ -1445,7 +1445,7 @@ void TorrentClient::addToPeerList(const QList<TorrentPeer> &peerList)
const auto firstNInactivePeers = [&tooMany, this] (TorrentPeer *peer) {
if (!tooMany)
return false;
- for (const PeerWireClient *client : qAsConst(d->connections)) {
+ for (const PeerWireClient *client : std::as_const(d->connections)) {
if (client->peer() == peer && (client->downloadSpeed() + client->uploadSpeed()) > 1024)
return false;
}
diff --git a/examples/network/torrent/torrentclient.h b/examples/network/torrent/torrentclient.h
index 4ff346e374..c06f0c41d2 100644
--- a/examples/network/torrent/torrentclient.h
+++ b/examples/network/torrent/torrentclient.h
@@ -69,9 +69,6 @@ public:
bool setTorrent(const QByteArray &torrentData);
MetaInfo metaInfo() const;
- void setMaxConnections(int connections);
- int maxConnections() const;
-
void setDestinationFolder(const QString &directory);
QString destinationFolder() const;
diff --git a/examples/network/torrent/torrentserver.cpp b/examples/network/torrent/torrentserver.cpp
index 8bdf98dd49..9751c25497 100644
--- a/examples/network/torrent/torrentserver.cpp
+++ b/examples/network/torrent/torrentserver.cpp
@@ -55,7 +55,7 @@ void TorrentServer::removeClient()
void TorrentServer::processInfoHash(const QByteArray &infoHash)
{
PeerWireClient *peer = qobject_cast<PeerWireClient *>(sender());
- for (TorrentClient *client : qAsConst(clients)) {
+ for (TorrentClient *client : std::as_const(clients)) {
if (client->state() >= TorrentClient::Searching && client->infoHash() == infoHash) {
peer->disconnect(peer, nullptr, this, nullptr);
client->setupIncomingConnection(peer);
diff --git a/examples/network/torrent/trackerclient.cpp b/examples/network/torrent/trackerclient.cpp
index b82442b8c0..12110ba0ae 100644
--- a/examples/network/torrent/trackerclient.cpp
+++ b/examples/network/torrent/trackerclient.cpp
@@ -20,7 +20,7 @@ TrackerClient::TrackerClient(TorrentClient *downloader, QObject *parent)
void TrackerClient::start(const MetaInfo &info)
{
metaInfo = info;
- QTimer::singleShot(0, this, SLOT(fetchPeerList()));
+ QTimer::singleShot(0, this, &TrackerClient::fetchPeerList);
if (metaInfo.fileForm() == MetaInfo::SingleFileForm) {
length = metaInfo.singleFile().length;
@@ -54,18 +54,16 @@ void TrackerClient::timerEvent(QTimerEvent *event)
void TrackerClient::fetchPeerList()
{
+ if (metaInfo.announceUrl().isEmpty())
+ return;
QUrl url(metaInfo.announceUrl());
// Base the query on announce url to include a passkey (if any)
QUrlQuery query(url);
// Percent encode the hash
- QByteArray infoHash = torrentDownloader->infoHash();
- QByteArray encodedSum;
- for (int i = 0; i < infoHash.size(); ++i) {
- encodedSum += '%';
- encodedSum += QByteArray::number(infoHash[i], 16).right(2).rightJustified(2, '0');
- }
+ const QByteArray infoHash = torrentDownloader->infoHash();
+ const QByteArray encodedSum = infoHash.toPercentEncoding();
bool seeding = (torrentDownloader->state() == TorrentClient::Seeding);
@@ -155,7 +153,7 @@ void TrackerClient::httpRequestDone(QNetworkReply *reply)
// Mandatory item
if (requestIntervalTimer != -1)
killTimer(requestIntervalTimer);
- requestIntervalTimer = startTimer(dict.value("interval").toInt() * 1000);
+ requestIntervalTimer = startTimer(std::chrono::seconds(dict.value("interval").toInt()));
}
if (dict.contains("peers")) {
diff --git a/examples/network/torrent/trackerclient.h b/examples/network/torrent/trackerclient.h
index 63368ec499..334ce42332 100644
--- a/examples/network/torrent/trackerclient.h
+++ b/examples/network/torrent/trackerclient.h
@@ -51,7 +51,6 @@ private slots:
private:
TorrentClient *torrentDownloader;
- int requestInterval = 5 * 60;
int requestIntervalTimer = -1;
QNetworkAccessManager http;
MetaInfo metaInfo;