Qt6 migration: LtsWidgets API fixes, LtsWebSocket logger init, RTI Docker install
- LtsWidgets: Fixed Qt6 API compatibility issues - QWheelEvent::delta() → angleDelta().y() - QStyleOption::init() → initFrom() - QComboBox activated signal signature change - QTextCodec removal (UTF-8 default in Qt6) - Missing widget includes added - LtsWebSocket: Fixed m_logger reference initialization - Added NGLLoggerBootstrap includes - Proper initialization in constructor initializer lists - CMake: Added BUILD_LTSWEBSOCKET option for temporary exclusion - Docker: RTI Connext permanent installation script added - ci/install-rti-in-docker.sh for persistent RTI setup - Removes need for volume mounting RTI into container - BUILD options: FilterManagement, RTI, Codification, Grantlee, LtsWebSocket can be disabled for partial builds during migration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
69 files changed
+12765
-14202
No files matched your search
+42
-1
@@ -18,9 +18,50 @@ RUN apt-get update && \
|
||||
qt6-base-dev \
|
||||
qt6-base-dev-tools \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools && \
|
||||
qt6-tools-dev-tools \
|
||||
qt6-svg-dev \
|
||||
qt6-websockets-dev \
|
||||
qt6-serialport-dev \
|
||||
qt6-multimedia-dev \
|
||||
qt6-declarative-dev \
|
||||
libpoppler-qt6-dev \
|
||||
libpq-dev \
|
||||
libbz2-dev \
|
||||
libboost-all-dev \
|
||||
libxml2-dev \
|
||||
libssl-dev \
|
||||
libcurl4-openssl-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Log4Qt for Qt6
|
||||
RUN git clone --depth 1 https://github.com/MEONMedical/Log4Qt.git /tmp/log4qt && \
|
||||
cd /tmp/log4qt && \
|
||||
mkdir -p build && cd build && \
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CXX_STANDARD=20 \
|
||||
-DCMAKE_CXX_EXTENSIONS=OFF \
|
||||
-DCMAKE_PREFIX_PATH="/usr" \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr/local" \
|
||||
-DBUILD_SHARED_LIBS=ON .. && \
|
||||
cmake --build . -- -j$(nproc) && \
|
||||
cmake --install . && \
|
||||
rm -rf /tmp/log4qt
|
||||
|
||||
# Create minimal CMake config for Log4Qt
|
||||
RUN mkdir -p /usr/local/lib/cmake/Log4Qt && \
|
||||
cat > /usr/local/lib/cmake/Log4Qt/Log4QtConfig.cmake << 'EOF'
|
||||
if (NOT TARGET Log4Qt::log4qt)
|
||||
add_library(Log4Qt::log4qt UNKNOWN IMPORTED)
|
||||
set_target_properties(Log4Qt::log4qt PROPERTIES
|
||||
IMPORTED_LOCATION "/usr/local/lib/liblog4qt.so"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "/usr/local/include"
|
||||
)
|
||||
endif()
|
||||
set(Log4Qt_FOUND TRUE CACHE INTERNAL "Log4Qt found by package config")
|
||||
set(Log4Qt_INCLUDE_DIRS "/usr/local/include" CACHE INTERNAL "Log4Qt include dir")
|
||||
set(Log4Qt_LIBRARIES "/usr/local/lib/liblog4qt.so" CACHE INTERNAL "Log4Qt library")
|
||||
EOF
|
||||
|
||||
# Set Qt platform for headless testing
|
||||
ENV QT_QPA_PLATFORM=offscreen
|
||||
|
||||
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
# Install RTI Connext into existing Docker image
|
||||
|
||||
set -e
|
||||
|
||||
RTI_SOURCE="/home/torsten/swy/sandbox/external/rti_connext_dds-7.7.0"
|
||||
BASE_IMAGE="lifemaps/ci-cpp:latest"
|
||||
TARGET_IMAGE="lifemaps/ci-cpp:rti"
|
||||
|
||||
echo "Step 1: Create container from base image..."
|
||||
CONTAINER_ID=$(docker create --name rti-install-temp $BASE_IMAGE /bin/bash)
|
||||
|
||||
echo "Step 2: Copy RTI Connext into container..."
|
||||
docker cp "$RTI_SOURCE" "$CONTAINER_ID:/opt/rti_connext_dds-7.7.0"
|
||||
|
||||
echo "Step 3: Commit container as new image..."
|
||||
docker commit $CONTAINER_ID $TARGET_IMAGE
|
||||
|
||||
echo "Step 4: Remove temporary container..."
|
||||
docker rm $CONTAINER_ID
|
||||
|
||||
echo "Step 5: Set environment variables in image..."
|
||||
docker run --rm $TARGET_IMAGE /bin/bash -c '
|
||||
echo "RTI Connext installed successfully"
|
||||
ls -la /opt/rti_connext_dds-7.7.0 | head -10
|
||||
'
|
||||
|
||||
echo ""
|
||||
echo "RTI Connext installed in image: $TARGET_IMAGE"
|
||||
echo "To use this image, set environment variables:"
|
||||
echo " docker run -e RTI_CONNEXT_HOME=/opt/rti_connext_dds-7.7.0 \\"
|
||||
echo " -e NDDSHOME=/opt/rti_connext_dds-7.7.0 \\"
|
||||
echo " -e PATH=/opt/rti_connext_dds-7.7.0/bin:\$PATH \\"
|
||||
echo " -e LD_LIBRARY_PATH=/opt/rti_connext_dds-7.7.0/lib/x64Linux4gcc7.3.0:\$LD_LIBRARY_PATH \\"
|
||||
echo " -e CMAKE_PREFIX_PATH=/opt/rti_connext_dds-7.7.0/lib/cmake:\$CMAKE_PREFIX_PATH \\"
|
||||
echo " $TARGET_IMAGE"
|
||||
@@ -75,6 +75,10 @@ OPTION(BUILD_PLUGINS_PARTICIPANT_ORG_CHART "Build ParticipantOrgChart (requires
|
||||
OPTION(BUILD_PLUGINS_MSDL "Build MSDL module (requires Qt6 XmlPatterns)" OFF)
|
||||
OPTION(BUILD_PLUGINS_SAAB "Build Saab module (requires Qt6 XmlPatterns)" OFF)
|
||||
OPTION(BUILD_RTI "Build RTI Connext DDS dependent modules" OFF)
|
||||
OPTION(BUILD_FILTERMANAGEMENT "Build FilterManagement plugins (temporarily disabled for migration)" OFF)
|
||||
OPTION(BUILD_CODIFICATION "Build CodificationManagement plugins (requires KDReports)" OFF)
|
||||
OPTION(BUILD_GRANTLEE "Build CodeGen Grantlee templates (requires Grantlee5/Qt5)" OFF)
|
||||
OPTION(BUILD_LTSWEBSOCKET "Build LtsWebSocket module (requires NGLLogger)" OFF)
|
||||
|
||||
IF(WIN32)
|
||||
SET(EXTERNAL_LIBRARY_DIR "C:/Development/Projekte/SituationMap/ExtFw" CACHE STRING "Library dir with all external dependencies")
|
||||
@@ -113,21 +117,12 @@ SET(CMAKE_AUTOMOC TRUE)
|
||||
SET(CMAKE_AUTOUIC TRUE)
|
||||
SET(QT_USE_IMPORTED_TARGETS TRUE)
|
||||
# Prefer Qt6, fallback to Qt5. Create Qt6::*-aliases when Qt6 is found so existing CMakeLists continue to work.
|
||||
# Try to detect Qt6 with a minimal check and then create aliases/placeholders for components used across the project.
|
||||
# Prefer Qt6, fallback to Qt5. Create Qt6::* aliases only when the corresponding
|
||||
# Qt6:: component target exists. Avoid creating IMPORTED placeholder targets which
|
||||
# have no LOCATION and later inject 'NOTFOUND' into autogen timestamp deps.
|
||||
# Find minimal Qt6 Core first, then probe for other components (non-fatal).
|
||||
find_package(Qt6 6.8 COMPONENTS Core QUIET)
|
||||
# Find Qt6 with all required components in one call to ensure all targets are properly created
|
||||
find_package(Qt6 6.8 COMPONENTS Concurrent Core Gui Location LinguistTools Network OpenGL PrintSupport
|
||||
Sensors Multimedia Sql Svg SerialPort Test UiTools WebSockets WebEngineCore WebEngineWidgets
|
||||
Widgets Xml XmlPatterns QUIET)
|
||||
if(Qt6_FOUND)
|
||||
message(STATUS "Found Qt6: ${Qt6Core_VERSION}")
|
||||
set(_qlist Concurrent Core Gui Location LinguistTools Network OpenGL PrintSupport
|
||||
Sensors Multimedia Sql Svg SerialPort Test UiTools WebSockets WebEngineCore WebEngineWidgets
|
||||
Widgets Xml XmlPatterns)
|
||||
foreach(_comp ${_qlist})
|
||||
# Probe for each component (non-fatal).
|
||||
find_package(Qt6 COMPONENTS ${_comp} QUIET)
|
||||
endforeach()
|
||||
# Map version variable for compatibility if available
|
||||
if(Qt6Core_VERSION)
|
||||
set(Qt5Core_VERSION ${Qt6Core_VERSION} CACHE INTERNAL "Compatibility Qt5Core_VERSION mapped from Qt6")
|
||||
@@ -146,12 +141,12 @@ if(Qt6_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
find_package(Qt6 5.9.0 COMPONENTS Concurrent Core Gui Location LinguistTools
|
||||
Network OpenGL PrintSupport Sensors Multimedia
|
||||
find_package(Qt6 5.9.0 COMPONENTS Concurrent Core Gui LinguistTools
|
||||
Network OpenGL PrintSupport Multimedia
|
||||
Sql Svg SerialPort Test UiTools WebSockets
|
||||
WebEngineCore WebEngineWidgets Widgets
|
||||
Xml XmlPatterns
|
||||
Widgets Xml
|
||||
REQUIRED)
|
||||
find_package(Qt6 COMPONENTS Location Sensors WebEngineCore WebEngineWidgets XmlPatterns OPTIONAL)
|
||||
MESSAGE(STATUS "Qt version is ${Qt6Core_VERSION}")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@ ADD_SUBDIRECTORY(LtsTimeline)
|
||||
ADD_SUBDIRECTORY(LtsPrinting)
|
||||
ADD_SUBDIRECTORY(LtsSerialPortQuerry)
|
||||
ADD_SUBDIRECTORY(LtsScriptTimeline)
|
||||
IF(BUILD_LTSWEBSOCKET)
|
||||
ADD_SUBDIRECTORY(LtsWebSocket)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(LtsProjectionWorkstation)
|
||||
ADD_SUBDIRECTORY(LtsVirtualKeyboard)
|
||||
ADD_SUBDIRECTORY(PluginInterfaces)
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
#
|
||||
|
||||
FIND_PACKAGE(RTI)
|
||||
FIND_PACKAGE(Grantlee5 REQUIRED COMPONENTS Templates)
|
||||
|
||||
# Grantlee5 is Qt5-based and optional for Qt6 migration
|
||||
IF(BUILD_GRANTLEE)
|
||||
FIND_PACKAGE(Grantlee5 REQUIRED COMPONENTS Templates)
|
||||
ENDIF()
|
||||
|
||||
NGL_ADD_LIBRARY2(ALL codegen_base SHARED
|
||||
codegen_export.h
|
||||
@@ -45,7 +49,8 @@ else()
|
||||
endif()
|
||||
NGL_INSTALL_TARGET(codegen_base)
|
||||
|
||||
if (TARGET Grantlee5::Templates)
|
||||
# Grantlee5 is Qt5-based and optional for Qt6 migration
|
||||
IF(BUILD_GRANTLEE AND TARGET Grantlee5::Templates)
|
||||
NGL_ADD_LIBRARY(ALL codegen_grantlee STATIC
|
||||
CppTopicGeneratorGrantlee.cpp
|
||||
CppTopicGeneratorGrantlee.h
|
||||
@@ -111,12 +116,8 @@ if (TARGET Grantlee5::Templates)
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
else()
|
||||
message(STATUS "Grantlee not found; skipping codegen_grantlee target")
|
||||
endif()
|
||||
|
||||
# Smoke-test: parse all .grantlee templates in this directory to detect parse/render regressions
|
||||
if (TARGET Grantlee5::Templates)
|
||||
# Smoke-test: parse all .grantlee templates in this directory to detect parse/render regressions
|
||||
find_package(Qt6 COMPONENTS Core QUIET)
|
||||
if (Qt6_FOUND)
|
||||
set(QTCORE_TARGET Qt6::Core)
|
||||
@@ -128,30 +129,32 @@ if (TARGET Grantlee5::Templates)
|
||||
add_executable(grantlee_parser_smoke tests/GrantleeParserSmoke.cpp)
|
||||
target_link_libraries(grantlee_parser_smoke PRIVATE Grantlee5::Templates ${QTCORE_TARGET})
|
||||
add_test(NAME GrantleeParserSmoke COMMAND grantlee_parser_smoke ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
NGL_ADD_EXECUTABLE(ALL ngl_codegen
|
||||
main_grantlee.cpp
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(ngl_codegen
|
||||
codegen_grantlee
|
||||
LtsCommandLineParser
|
||||
nglcoreapplication
|
||||
Qt6::Core
|
||||
)
|
||||
NGL_ADD_EXECUTABLE(ALL ngl_codegen
|
||||
main_grantlee.cpp
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(ngl_codegen
|
||||
codegen_grantlee
|
||||
LtsCommandLineParser
|
||||
nglcoreapplication
|
||||
Qt6::Core
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(codegen_gui_uics
|
||||
NGL_WRAP_UI(codegen_gui_uics
|
||||
main_grantlee_gui.ui
|
||||
)
|
||||
NGL_ADD_EXECUTABLE(WS AAR SV NO_TRANSLATION codegen_gui
|
||||
${codegen_gui_uics}
|
||||
main_grantlee_gui.cpp
|
||||
main_grantlee_gui.ui
|
||||
)
|
||||
NGL_ADD_EXECUTABLE(WS AAR SV NO_TRANSLATION codegen_gui
|
||||
${codegen_gui_uics}
|
||||
main_grantlee_gui.cpp
|
||||
main_grantlee_gui.ui
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(codegen_gui
|
||||
codegen_grantlee
|
||||
LtsCommandLineParser
|
||||
nglapplication
|
||||
Qt6::Widgets
|
||||
Grantlee5::Templates
|
||||
)
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(codegen_gui
|
||||
codegen_grantlee
|
||||
LtsCommandLineParser
|
||||
nglapplication
|
||||
Qt6::Widgets
|
||||
Grantlee5::Templates
|
||||
)
|
||||
ELSE()
|
||||
message(STATUS "BUILD_GRANTLEE disabled or Grantlee not found; skipping codegen_grantlee, ngl_codegen, and codegen_gui targets")
|
||||
ENDIF()
|
||||
@@ -24,6 +24,7 @@ endif()
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsCoordTrans
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
SET(ltsCoordWidget_SRCS
|
||||
@@ -48,6 +49,7 @@ NGL_TARGET_INCLUDE_DIRECTORIES(ltsCoordWidget
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../LtsUtils/LtsUtilsCore
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
IF(TARGET LtsCoordTrans)
|
||||
|
||||
Executable → Regular
+46
-58
@@ -1,10 +1,9 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include "sv_export.h"
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <LtsCoordTrans/ltscoordwidget_export.h>
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
|
||||
class QToolButton;
|
||||
@@ -12,68 +11,57 @@ class QToolButton;
|
||||
namespace LtsCoordWidget
|
||||
{
|
||||
class LtsCoordInputWidgetHandler;
|
||||
|
||||
class LTSCOORDWIDGET_EXPORT LtsCoordWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum class DisplayType
|
||||
{
|
||||
MGRS5,
|
||||
MGRS7,
|
||||
UTM,
|
||||
WGS84,
|
||||
MGRS = DisplayType::MGRS5
|
||||
};
|
||||
Q_ENUM(DisplayType)
|
||||
Q_PROPERTY(DisplayType displayType READ displayType WRITE setDisplayType)
|
||||
Q_PROPERTY(bool withResetButton READ withResetButton WRITE setWithResetButton)
|
||||
Q_PROPERTY(bool showToolTip READ showToolTip WRITE setShowToolTip)
|
||||
Q_PROPERTY(bool mgrsSquareEditable READ mgrsSquareEditable WRITE setMgrsSquareEditable)
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum class DisplayType { MGRS5, MGRS7, UTM, WGS84, MGRS = DisplayType::MGRS5 };
|
||||
Q_ENUM(DisplayType)
|
||||
Q_PROPERTY(DisplayType displayType READ displayType WRITE setDisplayType)
|
||||
Q_PROPERTY(bool withResetButton READ withResetButton WRITE setWithResetButton)
|
||||
Q_PROPERTY(bool showToolTip READ showToolTip WRITE setShowToolTip)
|
||||
Q_PROPERTY(bool mgrsSquareEditable READ mgrsSquareEditable WRITE setMgrsSquareEditable)
|
||||
|
||||
|
||||
explicit LtsCoordWidget(QWidget* parent = nullptr) : LtsCoordWidget(LtsCoordWidget::DisplayType::MGRS, parent) {}
|
||||
|
||||
explicit LtsCoordWidget(QWidget *parent = nullptr)
|
||||
: LtsCoordWidget(LtsCoordWidget::DisplayType::MGRS, parent)
|
||||
{}
|
||||
explicit LtsCoordWidget(DisplayType dt, QWidget* parent = nullptr);
|
||||
|
||||
|
||||
QPointF coordinate() const;
|
||||
DisplayType displayType() const;
|
||||
bool withResetButton() const;
|
||||
bool showToolTip() const;
|
||||
bool mgrsSquareEditable() const;
|
||||
bool event(QEvent* event) override;
|
||||
public Q_SLOTS:
|
||||
|
||||
explicit LtsCoordWidget(DisplayType dt, QWidget *parent = nullptr);
|
||||
void setCoordinate(const QPointF& geoCoord, bool bUseAsDefaultValue = true);
|
||||
void setCoordinate(double lon, double lat, bool bUseAsDefaultValue = true);
|
||||
void setDisplayType(LtsCoordWidget::DisplayType dt);
|
||||
void setWithResetButton(bool bWith);
|
||||
void setShowToolTip(bool bShow);
|
||||
void setMgrsSquareEditable(bool bEditable);
|
||||
void setWithSurroundingMgrsSquares(bool bEnable);
|
||||
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCoords);
|
||||
void clear();
|
||||
|
||||
QPointF coordinate() const;
|
||||
DisplayType displayType() const;
|
||||
bool withResetButton() const;
|
||||
bool showToolTip() const;
|
||||
bool mgrsSquareEditable() const;
|
||||
bool event(QEvent *event) override;
|
||||
public Q_SLOTS:
|
||||
|
||||
Q_SIGNALS:
|
||||
void coordinateChanged(const QPointF& newGeoCoord);
|
||||
void invalidCoordinate();
|
||||
|
||||
void setCoordinate(const QPointF &geoCoord, bool bUseAsDefaultValue = true);
|
||||
void setCoordinate(double lon, double lat, bool bUseAsDefaultValue = true);
|
||||
void setDisplayType(LtsCoordWidget::DisplayType dt);
|
||||
void setWithResetButton(bool bWith);
|
||||
void setShowToolTip(bool bShow);
|
||||
void setMgrsSquareEditable(bool bEditable);
|
||||
void setWithSurroundingMgrsSquares(bool bEnable);
|
||||
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords);
|
||||
void clear();
|
||||
private:
|
||||
void rebuildUi();
|
||||
void updateToolTip();
|
||||
private Q_SLOTS:
|
||||
void onResetToDefaultCoordinate();
|
||||
|
||||
Q_SIGNALS:
|
||||
void coordinateChanged(const QPointF &newGeoCoord);
|
||||
void invalidCoordinate();
|
||||
private:
|
||||
void rebuildUi();
|
||||
void updateToolTip();
|
||||
private Q_SLOTS:
|
||||
void onResetToDefaultCoordinate();
|
||||
private:
|
||||
bool m_bWithResetButton = false;
|
||||
bool m_bShowToolTip = true;
|
||||
bool m_bMgrsSquareEditable = false;
|
||||
LtsCoordWidget::DisplayType m_displayType = LtsCoordWidget::DisplayType::MGRS;
|
||||
LtsCoordInputWidgetHandler *m_inputWidgetHandler = nullptr;
|
||||
QPointF m_coordinate;
|
||||
QPointF m_defaultCoordinate;
|
||||
private:
|
||||
bool m_bWithResetButton = false;
|
||||
bool m_bShowToolTip = true;
|
||||
bool m_bMgrsSquareEditable = false;
|
||||
LtsCoordWidget::DisplayType m_displayType = LtsCoordWidget::DisplayType::MGRS;
|
||||
LtsCoordInputWidgetHandler* m_inputWidgetHandler = nullptr;
|
||||
QPointF m_coordinate;
|
||||
QPointF m_defaultCoordinate;
|
||||
};
|
||||
}
|
||||
} // namespace LtsCoordWidget
|
||||
@@ -15,7 +15,7 @@ SET(SRCS
|
||||
printing.h
|
||||
)
|
||||
|
||||
if (KDReports_FOUND AND BUILD_RTI)
|
||||
if (KDReports_FOUND AND BUILD_CODIFICATION)
|
||||
NGL_ADD_LIBRARY2(WS LtsPrinting SHARED ${SRCS})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsPrinting
|
||||
PUBLIC
|
||||
|
||||
@@ -13,6 +13,7 @@ NGL_ADD_LIBRARY2(ALL LtsUtilsSettings SHARED ${SRCS})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsUtilsSettings
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(LtsUtilsSettings
|
||||
|
||||
Executable → Regular
+48
-46
@@ -2,82 +2,84 @@
|
||||
|
||||
#include "client_connection.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QWebSocket>
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
ClientConnection::ClientConnection(QWebSocket *socket, QObject *parent)
|
||||
: QThread(parent)
|
||||
, m_socket(socket ? socket : new QWebSocket)
|
||||
ClientConnection::ClientConnection(QWebSocket* socket, QObject* parent)
|
||||
: QThread(parent), m_logger(NGL::NGLLoggerBootstrap::getLogger()), m_socket(socket ? socket : new QWebSocket)
|
||||
{
|
||||
}
|
||||
|
||||
ClientConnection::~ClientConnection()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Thread closed" << this;
|
||||
delete m_socket;
|
||||
qDeleteAll(m_messageQueue);
|
||||
DEBUG_LOG(m_logger) << "Thread closed" << this;
|
||||
delete m_socket;
|
||||
qDeleteAll(m_messageQueue);
|
||||
}
|
||||
|
||||
bool ClientConnection::init()
|
||||
{
|
||||
if (m_socket == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation failed due to an invalid socket";
|
||||
return false;
|
||||
}
|
||||
if (m_socket == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation failed due to an invalid socket";
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Started new thread" << this;
|
||||
connect(m_socket, &QWebSocket::textMessageReceived, this, &ClientConnection::onNewTextMessageFromSocket, Qt::DirectConnection);
|
||||
connect(m_socket, &QWebSocket::connected, this, &ClientConnection::sendMessagesFromQueue);
|
||||
connect(m_socket, &QWebSocket::disconnected, this, &ClientConnection::onSocketDisconnect);
|
||||
DEBUG_LOG(m_logger) << "Started new thread" << this;
|
||||
connect(m_socket, &QWebSocket::textMessageReceived, this, &ClientConnection::onNewTextMessageFromSocket,
|
||||
Qt::DirectConnection);
|
||||
connect(m_socket, &QWebSocket::connected, this, &ClientConnection::sendMessagesFromQueue);
|
||||
connect(m_socket, &QWebSocket::disconnected, this, &ClientConnection::onSocketDisconnect);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientConnection::addReply(ReplyMessage *message)
|
||||
void ClientConnection::addReply(ReplyMessage* message)
|
||||
{
|
||||
if (!m_socket || m_socket->state() != QAbstractSocket::ConnectedState)
|
||||
{
|
||||
m_messageQueue.enqueue(message);
|
||||
DEBUG_LOG(m_logger) << "Adding message to queue, size: " << m_messageQueue.size();
|
||||
return;
|
||||
}
|
||||
const QString msg(message->toJsonString());
|
||||
DEBUG_LOG(m_logger) << "Sending message: " << msg ;
|
||||
m_socket->sendTextMessage(msg);
|
||||
delete message;
|
||||
if (!m_socket || m_socket->state() != QAbstractSocket::ConnectedState)
|
||||
{
|
||||
m_messageQueue.enqueue(message);
|
||||
DEBUG_LOG(m_logger) << "Adding message to queue, size: " << m_messageQueue.size();
|
||||
return;
|
||||
}
|
||||
const QString msg(message->toJsonString());
|
||||
DEBUG_LOG(m_logger) << "Sending message: " << msg;
|
||||
m_socket->sendTextMessage(msg);
|
||||
delete message;
|
||||
}
|
||||
|
||||
void ClientConnection::onNewTextMessageFromSocket(const QString &message)
|
||||
void ClientConnection::onNewTextMessageFromSocket(const QString& message)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Recv msg: " << message << this;
|
||||
emit newTextMessage(this, message);
|
||||
DEBUG_LOG(m_logger) << "Recv msg: " << message << this;
|
||||
emit newTextMessage(this, message);
|
||||
}
|
||||
|
||||
void ClientConnection::sendMessagesFromQueue()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Client connected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
|
||||
INFO_LOG(m_logger) << "Client connected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
|
||||
|
||||
if (m_socket->state() != QAbstractSocket::ConnectedState)
|
||||
return;
|
||||
while (!m_messageQueue.isEmpty())
|
||||
{
|
||||
ReplyMessage *message = m_messageQueue.dequeue();
|
||||
const QString msg(message->toJsonString());
|
||||
TRACE_LOG(m_logger) << "Send msg: " << msg;
|
||||
m_socket->sendTextMessage(msg);
|
||||
delete message;
|
||||
DEBUG_LOG(m_logger) << "Sent message from queue, new size: " << m_messageQueue.size();
|
||||
}
|
||||
if (m_socket->state() != QAbstractSocket::ConnectedState)
|
||||
return;
|
||||
while (!m_messageQueue.isEmpty())
|
||||
{
|
||||
ReplyMessage* message = m_messageQueue.dequeue();
|
||||
const QString msg(message->toJsonString());
|
||||
TRACE_LOG(m_logger) << "Send msg: " << msg;
|
||||
m_socket->sendTextMessage(msg);
|
||||
delete message;
|
||||
DEBUG_LOG(m_logger) << "Sent message from queue, new size: " << m_messageQueue.size();
|
||||
}
|
||||
}
|
||||
|
||||
void ClientConnection::onSocketDisconnect()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Client disconnected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
|
||||
exit(0);
|
||||
emit disconnected(this);
|
||||
DEBUG_LOG(m_logger) << "Client disconnected ip: " << m_socket->peerAddress().toString() << ":"
|
||||
<< m_socket->peerPort();
|
||||
exit(0);
|
||||
emit disconnected(this);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWebSocket
|
||||
Executable → Regular
+30
-48
@@ -1,69 +1,51 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QQueue>
|
||||
|
||||
#include "reply_message.h"
|
||||
#include "logger.h"
|
||||
#include "ltswebsocketserver_export.h"
|
||||
#include "reply_message.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QtCore/QQueue>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
class QWebSocket;
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETSERVER_EXPORT ClientConnection
|
||||
: public QThread
|
||||
, public ReplyHandler
|
||||
class LTSWEBSOCKETSERVER_EXPORT ClientConnection : public QThread, public ReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ClientConnection(QWebSocket* socket, QObject* parent = nullptr);
|
||||
|
||||
explicit ClientConnection(QWebSocket *socket, QObject *parent = nullptr);
|
||||
~ClientConnection();
|
||||
|
||||
bool init();
|
||||
|
||||
|
||||
void addReply(ReplyMessage* message) override;
|
||||
|
||||
~ClientConnection();
|
||||
QWebSocket* webSocket()
|
||||
{
|
||||
return m_socket;
|
||||
}
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
bool init();
|
||||
void newTextMessage(ClientConnection* client, const QString& message);
|
||||
|
||||
|
||||
void disconnected(ClientConnection* client);
|
||||
|
||||
void addReply(ReplyMessage *message) override;
|
||||
private slots:
|
||||
void onNewTextMessageFromSocket(const QString& message);
|
||||
void sendMessagesFromQueue();
|
||||
void onSocketDisconnect();
|
||||
|
||||
QWebSocket *webSocket() { return m_socket; }
|
||||
signals:
|
||||
|
||||
|
||||
void newTextMessage(ClientConnection *client, const QString &message);
|
||||
|
||||
|
||||
|
||||
void disconnected(ClientConnection *client);
|
||||
|
||||
|
||||
private slots:
|
||||
void onNewTextMessageFromSocket(const QString &message);
|
||||
void sendMessagesFromQueue();
|
||||
void onSocketDisconnect();
|
||||
private:
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
void sendMessages();
|
||||
|
||||
private:
|
||||
NGL::INGLLogger &m_logger;
|
||||
QWebSocket *m_socket;
|
||||
QQueue<ReplyMessage *> m_messageQueue;
|
||||
};
|
||||
}
|
||||
private:
|
||||
NGL::INGLLogger& m_logger;
|
||||
void sendMessages();
|
||||
QWebSocket* m_socket;
|
||||
QQueue<ReplyMessage*> m_messageQueue;
|
||||
};
|
||||
} // namespace LtsWebSocket
|
||||
Executable → Regular
+39
-40
@@ -3,67 +3,66 @@
|
||||
#pragma once
|
||||
|
||||
#include "client_message.h"
|
||||
#include "reply_message.h"
|
||||
#include "ltswebsocketcommon_export.h"
|
||||
#include "reply_message.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonParseError>
|
||||
#include <QString>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
namespace LtsWebSocket
|
||||
{
|
||||
|
||||
|
||||
|
||||
class LTSWEBSOCKETCOMMON_EXPORT AbstractClientMessageFactory
|
||||
{
|
||||
public:
|
||||
explicit AbstractClientMessageFactory(NGL::INGLLogger &logger)
|
||||
: m_logger(logger)
|
||||
{}
|
||||
public:
|
||||
explicit AbstractClientMessageFactory(NGL::INGLLogger& logger) : m_logger(logger) {}
|
||||
|
||||
virtual ~AbstractClientMessageFactory() {}
|
||||
virtual ~AbstractClientMessageFactory() {}
|
||||
|
||||
|
||||
QJsonParseError parseMessage(const QString& message);
|
||||
|
||||
QJsonParseError parseMessage(const QString &message);
|
||||
virtual AbstractClientMessage* createMessage(ReplyHandler* client, const QString& message) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
AbstractClientMessage* checkAttributes(ReplyHandler* client, const QString& message) const;
|
||||
AbstractClientMessage* checkResult(ReplyHandler* client, const QString& message,
|
||||
AbstractClientMessage* result) const;
|
||||
|
||||
virtual AbstractClientMessage *createMessage(ReplyHandler *client, const QString &message) = 0;
|
||||
|
||||
protected:
|
||||
AbstractClientMessage *checkAttributes(ReplyHandler *client,
|
||||
const QString &message) const;
|
||||
AbstractClientMessage *checkResult(ReplyHandler *client,
|
||||
const QString &message,
|
||||
AbstractClientMessage *result) const;
|
||||
protected:
|
||||
QString m_type;
|
||||
int m_typeId;
|
||||
QString m_uuid;
|
||||
QJsonValue m_data;
|
||||
};
|
||||
protected:
|
||||
NGL::INGLLogger& m_logger;
|
||||
QString m_type;
|
||||
int m_typeId;
|
||||
QString m_uuid;
|
||||
QJsonValue m_data;
|
||||
};
|
||||
|
||||
class PongMessage final : public ReplyMessage
|
||||
{
|
||||
public:
|
||||
static QString strPong() { return QStringLiteral("pong"); }
|
||||
static int idPong() { return 2; }
|
||||
explicit PongMessage(const QString &payload)
|
||||
: ReplyMessage(strPong(), idPong(), QString())
|
||||
, m_payload(payload)
|
||||
{}
|
||||
public:
|
||||
static QString strPong()
|
||||
{
|
||||
return QStringLiteral("pong");
|
||||
}
|
||||
|
||||
QString toJsonString() const override
|
||||
{
|
||||
return m_payload.isEmpty() ? strPong() : QStringLiteral("%1 %2").arg(strPong(), m_payload);
|
||||
}
|
||||
private:
|
||||
QString m_payload;
|
||||
static int idPong()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
explicit PongMessage(const QString& payload) : ReplyMessage(strPong(), idPong(), QString()), m_payload(payload) {}
|
||||
|
||||
QString toJsonString() const override
|
||||
{
|
||||
return m_payload.isEmpty() ? strPong() : QStringLiteral("%1 %2").arg(strPong(), m_payload);
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_payload;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace LtsWebSocket
|
||||
Executable → Regular
+54
-53
@@ -1,88 +1,89 @@
|
||||
|
||||
|
||||
#include "connection_handler.h"
|
||||
#include <utility>
|
||||
|
||||
#include "client_connection.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QtWebSockets/QWebSocket>
|
||||
#include <utility>
|
||||
|
||||
using namespace LtsWebSocket;
|
||||
|
||||
ConnectionHandler::ConnectionHandler(QObject *parent) : QObject(parent)
|
||||
, m_server(nullptr),
|
||||
m_logger(NGL::NGLLoggerBootstrap::getLogger()) {}
|
||||
ConnectionHandler::ConnectionHandler(QObject* parent)
|
||||
: QObject(parent), m_server(nullptr), m_logger(NGL::NGLLoggerBootstrap::getLogger())
|
||||
{
|
||||
}
|
||||
|
||||
ConnectionHandler::~ConnectionHandler()
|
||||
{
|
||||
for (auto connection : std::as_const(m_connections))
|
||||
connection->disconnect(this);
|
||||
for (auto connection : std::as_const(m_connections))
|
||||
connection->disconnect(this);
|
||||
}
|
||||
|
||||
bool ConnectionHandler::init(const QString &serviceName, unsigned short port)
|
||||
bool ConnectionHandler::init(const QString& serviceName, unsigned short port)
|
||||
{
|
||||
if (m_server != nullptr)
|
||||
{
|
||||
m_server->disconnect();
|
||||
delete m_server;
|
||||
}
|
||||
|
||||
m_server = new QWebSocketServer(QStringLiteral("RME-") + serviceName, QWebSocketServer::NonSecureMode, this);
|
||||
if (m_server != nullptr)
|
||||
{
|
||||
m_server->disconnect();
|
||||
delete m_server;
|
||||
}
|
||||
|
||||
connect(m_server, &QWebSocketServer::newConnection, this, &ConnectionHandler::onNewConnection);
|
||||
connect(m_server, &QWebSocketServer::serverError, this, &ConnectionHandler::onServerError);
|
||||
m_server = new QWebSocketServer(QStringLiteral("RME-") + serviceName, QWebSocketServer::NonSecureMode, this);
|
||||
|
||||
DEBUG_LOG(m_logger) << "Trying to listen ";
|
||||
if (!m_server->listen(QHostAddress::Any, port))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Not possible to listen to port " << port;
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "... ok, port " << m_server->serverPort();
|
||||
connect(m_server, &QWebSocketServer::newConnection, this, &ConnectionHandler::onNewConnection);
|
||||
connect(m_server, &QWebSocketServer::serverError, this, &ConnectionHandler::onServerError);
|
||||
|
||||
return true;
|
||||
DEBUG_LOG(m_logger) << "Trying to listen ";
|
||||
if (!m_server->listen(QHostAddress::Any, port))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Not possible to listen to port " << port;
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "... ok, port " << m_server->serverPort();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConnectionHandler::sendToAllClients(ReplyMessage *message)
|
||||
void ConnectionHandler::sendToAllClients(ReplyMessage* message)
|
||||
{
|
||||
for (auto connection : std::as_const(m_connections))
|
||||
connection->addReply(new ReplyMessage(*message));
|
||||
for (auto connection : std::as_const(m_connections))
|
||||
connection->addReply(new ReplyMessage(*message));
|
||||
|
||||
delete message;
|
||||
delete message;
|
||||
}
|
||||
|
||||
void ConnectionHandler::onServerError(QWebSocketProtocol::CloseCode closeCode)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Got server error with close code " << closeCode;
|
||||
ERROR_LOG(m_logger) << "Got server error with close code " << closeCode;
|
||||
}
|
||||
|
||||
void ConnectionHandler::onNewConnection()
|
||||
{
|
||||
while (m_server->hasPendingConnections())
|
||||
{
|
||||
QWebSocket *socket = m_server->nextPendingConnection();
|
||||
|
||||
ClientConnection *newConnection = new ClientConnection(socket, this);
|
||||
connect(newConnection, &ClientConnection::destroyed, this, [this](QObject* o)
|
||||
while (m_server->hasPendingConnections())
|
||||
{
|
||||
m_connections.remove(static_cast<ClientConnection*>(o));
|
||||
});
|
||||
QWebSocket* socket = m_server->nextPendingConnection();
|
||||
|
||||
if (!newConnection->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Failed to initialise new client";
|
||||
delete newConnection;
|
||||
newConnection = nullptr;
|
||||
continue;
|
||||
ClientConnection* newConnection = new ClientConnection(socket, this);
|
||||
connect(newConnection, &ClientConnection::destroyed, this,
|
||||
[this](QObject* o) { m_connections.remove(static_cast<ClientConnection*>(o)); });
|
||||
|
||||
if (!newConnection->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Failed to initialise new client";
|
||||
delete newConnection;
|
||||
newConnection = nullptr;
|
||||
continue;
|
||||
}
|
||||
newConnection->start();
|
||||
|
||||
connect(newConnection, &ClientConnection::newTextMessage, this, &ConnectionHandler::newTextMessageFromClient);
|
||||
connect(newConnection, &ClientConnection::disconnected, this, &ConnectionHandler::clientDisconnected);
|
||||
connect(newConnection, &ClientConnection::finished, newConnection, &ClientConnection::deleteLater);
|
||||
|
||||
m_connections.insert(newConnection);
|
||||
emit clientConnected(newConnection);
|
||||
INFO_LOG(m_logger) << "New client connected ip: " << socket->localAddress().toString() << ":"
|
||||
<< socket->localPort();
|
||||
}
|
||||
newConnection->start();
|
||||
|
||||
connect(newConnection, &ClientConnection::newTextMessage, this, &ConnectionHandler::newTextMessageFromClient);
|
||||
connect(newConnection, &ClientConnection::disconnected, this, &ConnectionHandler::clientDisconnected);
|
||||
connect(newConnection, &ClientConnection::finished, newConnection, &ClientConnection::deleteLater);
|
||||
|
||||
m_connections.insert(newConnection);
|
||||
emit clientConnected(newConnection);
|
||||
INFO_LOG(m_logger) << "New client connected ip: " << socket->localAddress().toString() << ":" << socket->localPort();
|
||||
}
|
||||
}
|
||||
@@ -172,6 +172,7 @@ NGL_TARGET_LINK_LIBRARIES(LtsWidgets
|
||||
TabBarTabStyle
|
||||
LtsSessionData
|
||||
LtsUtilsSettings
|
||||
NGLLogger
|
||||
PUBLIC
|
||||
LtsUtilsCore
|
||||
Qt6::Core
|
||||
|
||||
Executable → Regular
+59
-64
@@ -2,25 +2,21 @@
|
||||
|
||||
#include "lts_abstract_sequence_widget.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QToolButton>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
LtsAbstractSequenceWidget::LtsAbstractSequenceWidget(QWidget *parent, const bool &readOnly)
|
||||
: QGroupBox(parent)
|
||||
, m_readOnly(readOnly)
|
||||
, m_pbAddMember(new QToolButton)
|
||||
LtsAbstractSequenceWidget::LtsAbstractSequenceWidget(QWidget* parent, const bool& readOnly)
|
||||
: QGroupBox(parent), m_readOnly(readOnly), m_pbAddMember(new QToolButton)
|
||||
{
|
||||
m_pbAddMember->setIcon(QIcon(QLatin1String(":/icons/png/add.png")));
|
||||
m_pbAddMember->setIcon(QIcon(QLatin1String(":/icons/png/add.png")));
|
||||
|
||||
connect(m_pbAddMember, &QToolButton::clicked, this, &LtsAbstractSequenceWidget::addMember);
|
||||
connect(m_pbAddMember, &QToolButton::clicked, this, &LtsAbstractSequenceWidget::addMember);
|
||||
}
|
||||
|
||||
LtsAbstractSequenceWidget::~LtsAbstractSequenceWidget()
|
||||
{
|
||||
|
||||
}
|
||||
LtsAbstractSequenceWidget::~LtsAbstractSequenceWidget() {}
|
||||
|
||||
void LtsAbstractSequenceWidget::addWidget(QWidget* widget, bool isReadOnly, bool isButtonVisible)
|
||||
{
|
||||
@@ -29,92 +25,91 @@ void LtsAbstractSequenceWidget::addWidget(QWidget* widget, bool isReadOnly, bool
|
||||
m_pbAddMember->setVisible(isButtonVisible);
|
||||
}
|
||||
|
||||
int LtsAbstractSequenceWidget::getMemberlistSize(){
|
||||
return m_memberList.size();
|
||||
int LtsAbstractSequenceWidget::getMemberlistSize()
|
||||
{
|
||||
return m_memberList.size();
|
||||
}
|
||||
|
||||
void LtsAbstractSequenceWidget::getValue(QWidget *data,
|
||||
const QString &findObjectName) const
|
||||
void LtsAbstractSequenceWidget::getValue(QWidget* data, const QString& findObjectName) const
|
||||
{
|
||||
|
||||
if(!findChild<QWidget *>(findObjectName))
|
||||
return;
|
||||
if (!findChild<QWidget*>(findObjectName))
|
||||
return;
|
||||
|
||||
data = findChild<QWidget *>(findObjectName);
|
||||
data = findChild<QWidget*>(findObjectName);
|
||||
}
|
||||
|
||||
void LtsAbstractSequenceWidget::setMemberCount(int count)
|
||||
{
|
||||
QWidget *child = nullptr;
|
||||
do
|
||||
{
|
||||
child = findChild<QWidget *>(getObjectName(++count));
|
||||
delete child;
|
||||
}
|
||||
while (child);
|
||||
m_memberList.removeAll(nullptr);
|
||||
QWidget* child = nullptr;
|
||||
do
|
||||
{
|
||||
child = findChild<QWidget*>(getObjectName(++count));
|
||||
delete child;
|
||||
} while (child);
|
||||
m_memberList.removeAll(nullptr);
|
||||
}
|
||||
|
||||
uint32_t LtsAbstractSequenceWidget::getMemberCount() const
|
||||
{
|
||||
int count = 0;
|
||||
QWidget *child = findChild<QWidget *>(getObjectName(count+1));
|
||||
while(child)
|
||||
{
|
||||
count++;
|
||||
child = findChild<QWidget *>(getObjectName(count+1));
|
||||
}
|
||||
return count;
|
||||
int count = 0;
|
||||
QWidget* child = findChild<QWidget*>(getObjectName(count + 1));
|
||||
while (child)
|
||||
{
|
||||
count++;
|
||||
child = findChild<QWidget*>(getObjectName(count + 1));
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
QToolButton *LtsAbstractSequenceWidget::pbAddMember() const
|
||||
QToolButton* LtsAbstractSequenceWidget::pbAddMember() const
|
||||
{
|
||||
return m_pbAddMember;
|
||||
return m_pbAddMember;
|
||||
}
|
||||
|
||||
QString LtsAbstractSequenceWidget::getObjectName(int index) const
|
||||
{
|
||||
return QString::number(index);
|
||||
return QString::number(index);
|
||||
}
|
||||
|
||||
void LtsAbstractSequenceWidget::addMemberWidget(QWidget *member, bool isReadOnly, bool isButtonVisible)
|
||||
void LtsAbstractSequenceWidget::addMemberWidget(QWidget* member, bool isReadOnly, bool isButtonVisible)
|
||||
{
|
||||
QToolButton *button = new QToolButton();
|
||||
button->setIcon(QIcon(QLatin1String(":/icons/png/remove.png")));
|
||||
button->setDisabled(isReadOnly);
|
||||
QToolButton* button = new QToolButton();
|
||||
button->setIcon(QIcon(QLatin1String(":/icons/png/remove.png")));
|
||||
button->setDisabled(isReadOnly);
|
||||
|
||||
connect(button, &QToolButton::clicked, member, &QWidget::deleteLater);
|
||||
connect(member, &QWidget::destroyed, this, &LtsAbstractSequenceWidget::deleteMemberWidget);
|
||||
connect(member, &QWidget::destroyed, button, &QToolButton::deleteLater);
|
||||
connect(button, &QToolButton::clicked, member, &QWidget::deleteLater);
|
||||
connect(member, &QWidget::destroyed, this, &LtsAbstractSequenceWidget::deleteMemberWidget);
|
||||
connect(member, &QWidget::destroyed, button, &QToolButton::deleteLater);
|
||||
|
||||
m_memberList.push_back(member);
|
||||
setupMemberWidget(member, button, member->objectName(), isButtonVisible);
|
||||
m_memberList.push_back(member);
|
||||
setupMemberWidget(member, button, member->objectName(), isButtonVisible);
|
||||
}
|
||||
|
||||
void LtsAbstractSequenceWidget::deleteMemberWidget(QObject *member)
|
||||
void LtsAbstractSequenceWidget::deleteMemberWidget(QObject* member)
|
||||
{
|
||||
QWidget *w = qobject_cast<QWidget*>(member);
|
||||
QWidget* w = qobject_cast<QWidget*>(member);
|
||||
|
||||
if(!w)
|
||||
return;
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
for(auto child : w->children())
|
||||
child->deleteLater();
|
||||
for (auto child : w->children())
|
||||
child->deleteLater();
|
||||
|
||||
m_memberList.removeAll(w);
|
||||
for(int i=0; i<m_memberList.size(); i++)
|
||||
{
|
||||
m_memberList[i]->setObjectName(getObjectName(i + 1));
|
||||
|
||||
for(auto child : m_memberList[i]->children())
|
||||
m_memberList.removeAll(w);
|
||||
for (int i = 0; i < m_memberList.size(); i++)
|
||||
{
|
||||
if(child->objectName().isEmpty())
|
||||
continue;
|
||||
m_memberList[i]->setObjectName(getObjectName(i + 1));
|
||||
|
||||
QString childName = child->objectName();
|
||||
QString newId = QString::number(i + 1);
|
||||
child->setObjectName(childName.replace(QRegExp(QLatin1String(".([0-9]*)")), newId));
|
||||
for (auto child : m_memberList[i]->children())
|
||||
{
|
||||
if (child->objectName().isEmpty())
|
||||
continue;
|
||||
|
||||
QString childName = child->objectName();
|
||||
QString newId = QString::number(i + 1);
|
||||
child->setObjectName(childName.replace(QRegularExpression(QLatin1String("\\.([0-9]*)")), newId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+70
-84
@@ -1,137 +1,123 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_background_widget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QtPlatformHeaders/qwindowswindowfunctions.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
LtsBackgroundWidget::LtsBackgroundWidget(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_isUltraWide(false)
|
||||
LtsBackgroundWidget::LtsBackgroundWidget(QWidget* parent) : QDialog(parent), m_isUltraWide(false)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setWindowFlags(windowFlags() | Qt::FramelessWindowHint );
|
||||
setWindowTitle(QStringLiteral("Splash"));
|
||||
setMouseTracking(true);
|
||||
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
setWindowTitle(QStringLiteral("Splash"));
|
||||
|
||||
setBackground();
|
||||
setBackground();
|
||||
}
|
||||
|
||||
|
||||
void LtsBackgroundWidget::setBackground()
|
||||
{
|
||||
static const auto backgroundFiles =
|
||||
{
|
||||
QStringLiteral(":/project/background.png"),
|
||||
QStringLiteral(":/project/background.jpg"),
|
||||
};
|
||||
static const auto backgroundFilesWide =
|
||||
{
|
||||
QStringLiteral(":/project/background_wide.png"),
|
||||
QStringLiteral(":/project/background_wide.jpg"),
|
||||
};
|
||||
static const auto backgroundFiles = {
|
||||
QStringLiteral(":/project/background.png"),
|
||||
QStringLiteral(":/project/background.jpg"),
|
||||
};
|
||||
static const auto backgroundFilesWide = {
|
||||
QStringLiteral(":/project/background_wide.png"),
|
||||
QStringLiteral(":/project/background_wide.jpg"),
|
||||
};
|
||||
|
||||
m_pixmap = QPixmap();
|
||||
for (const QString& f : m_isUltraWide ? backgroundFilesWide : backgroundFiles)
|
||||
{
|
||||
if (!QFile::exists(f))
|
||||
continue;
|
||||
m_pixmap = QPixmap(f);
|
||||
if (m_pixmap.isNull())
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
m_pixmap = QPixmap();
|
||||
for (const QString &f : m_isUltraWide ? backgroundFilesWide : backgroundFiles)
|
||||
{
|
||||
if (!QFile::exists(f))
|
||||
continue;
|
||||
m_pixmap = QPixmap(f);
|
||||
if (m_pixmap.isNull())
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_pixmap.isNull())
|
||||
{
|
||||
if (m_isUltraWide)
|
||||
{
|
||||
m_isUltraWide = false;
|
||||
setBackground();
|
||||
if (m_isUltraWide)
|
||||
{
|
||||
m_isUltraWide = false;
|
||||
setBackground();
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "BackgroundWidget::c_tor: file missing or is not a valid image ':/project/background.png'";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning() << "BackgroundWidget::c_tor: file missing or is not a valid image ':/project/background.png'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LtsBackgroundWidget::setUltraWide(bool set)
|
||||
{
|
||||
if (set == m_isUltraWide)
|
||||
return;
|
||||
if (set == m_isUltraWide)
|
||||
return;
|
||||
|
||||
m_isUltraWide = set;
|
||||
setBackground();
|
||||
update();
|
||||
m_isUltraWide = set;
|
||||
setBackground();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void LtsBackgroundWidget::resizeEvent(QResizeEvent *e)
|
||||
void LtsBackgroundWidget::resizeEvent(QResizeEvent* e)
|
||||
{
|
||||
setUltraWide(width() > 3000);
|
||||
QDialog::resizeEvent(e);
|
||||
setUltraWide(width() > 3000);
|
||||
QDialog::resizeEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void LtsBackgroundWidget::paintEvent(QPaintEvent *e)
|
||||
void LtsBackgroundWidget::paintEvent(QPaintEvent* e)
|
||||
{
|
||||
if (!m_pixmap.isNull())
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter.drawPixmap(0, 0, width(), height(), m_pixmap);
|
||||
}
|
||||
QDialog::paintEvent(e);
|
||||
if (!m_pixmap.isNull())
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter.drawPixmap(0, 0, width(), height(), m_pixmap);
|
||||
}
|
||||
QDialog::paintEvent(e);
|
||||
}
|
||||
|
||||
|
||||
bool LtsBackgroundWidget::event(QEvent *e)
|
||||
bool LtsBackgroundWidget::event(QEvent* e)
|
||||
{
|
||||
if (e->type() == QEvent::KeyPress ||
|
||||
e->type() == QEvent::MouseButtonPress ||
|
||||
e->type() == QEvent::MouseButtonRelease ||
|
||||
e->type() == QEvent::MouseMove)
|
||||
{
|
||||
|
||||
emit signalOperatorAction();
|
||||
e->ignore();
|
||||
return true;
|
||||
}
|
||||
if (e->type() == QEvent::KeyPress || e->type() == QEvent::MouseButtonPress ||
|
||||
e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove)
|
||||
{
|
||||
|
||||
return QDialog::event(e);
|
||||
emit signalOperatorAction();
|
||||
e->ignore();
|
||||
return true;
|
||||
}
|
||||
|
||||
return QDialog::event(e);
|
||||
}
|
||||
|
||||
|
||||
void LtsBackgroundWidget::showFullScreen()
|
||||
{
|
||||
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
winId();
|
||||
QWindowsWindowFunctions::setHasBorderInFullScreen(windowHandle(), true);
|
||||
winId();
|
||||
QWindowsWindowFunctions::setHasBorderInFullScreen(windowHandle(), true);
|
||||
#endif
|
||||
QDialog::showFullScreen();
|
||||
raise();
|
||||
QDialog::showFullScreen();
|
||||
raise();
|
||||
}
|
||||
|
||||
|
||||
void LtsBackgroundWidget::closeEvent(QCloseEvent *e)
|
||||
void LtsBackgroundWidget::closeEvent(QCloseEvent* e)
|
||||
{
|
||||
#ifdef DEVEL
|
||||
deleteLater();
|
||||
deleteLater();
|
||||
#else
|
||||
e->ignore();
|
||||
e->ignore();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+1211
-1410
File diff suppressed because it is too large.
Load diff
Executable → Regular
+90
-80
@@ -1,123 +1,133 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include "ltswidgets_export.h"
|
||||
#include <LtsUtilsCore/variant_operators.h>
|
||||
|
||||
#include <LtsUtilsCore/variant_operators.h>
|
||||
#include <QDataStream>
|
||||
#include <QIODevice>
|
||||
#include <QIcon>
|
||||
#include <QObject>
|
||||
#include <QRegularExpression>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
struct ComboboxFilterData
|
||||
{
|
||||
QString text;
|
||||
QVariant data;
|
||||
QIcon icon;
|
||||
QString text;
|
||||
QVariant data;
|
||||
QIcon icon;
|
||||
|
||||
inline bool operator<(const ComboboxFilterData &cfd)
|
||||
{
|
||||
return LtsUtils::lessThan(data, cfd.data);
|
||||
}
|
||||
inline friend QDataStream &operator<<(QDataStream &ds, const ComboboxFilterData &cfd)
|
||||
{
|
||||
ds << cfd.text << cfd.data << cfd.icon;
|
||||
return ds;
|
||||
}
|
||||
inline friend QDataStream &operator>>(QDataStream &ds, ComboboxFilterData &cfd)
|
||||
{
|
||||
ds >> cfd.text >> cfd.data >> cfd.icon;
|
||||
return ds;
|
||||
}
|
||||
inline bool operator<(const ComboboxFilterData& cfd)
|
||||
{
|
||||
return LtsUtils::lessThan(data, cfd.data);
|
||||
}
|
||||
|
||||
inline friend QDataStream& operator<<(QDataStream& ds, const ComboboxFilterData& cfd)
|
||||
{
|
||||
ds << cfd.text << cfd.data << cfd.icon;
|
||||
return ds;
|
||||
}
|
||||
|
||||
inline friend QDataStream& operator>>(QDataStream& ds, ComboboxFilterData& cfd)
|
||||
{
|
||||
ds >> cfd.text >> cfd.data >> cfd.icon;
|
||||
return ds;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct ComboboxFilterContent
|
||||
{
|
||||
QVector<ComboboxFilterData> data;
|
||||
bool sortItems = false;
|
||||
bool isValid() const { return m_isValid; }
|
||||
QVector<ComboboxFilterData> data;
|
||||
bool sortItems = false;
|
||||
|
||||
QVariant toVariant() const
|
||||
{
|
||||
if (!isValid())
|
||||
return QVariant();
|
||||
QByteArray ba;
|
||||
QDataStream ds(&ba, QIODevice::WriteOnly);
|
||||
ds << (*this);
|
||||
return ba;
|
||||
}
|
||||
bool isValid() const
|
||||
{
|
||||
return m_isValid;
|
||||
}
|
||||
|
||||
static ComboboxFilterContent fromVariant(const QVariant &v)
|
||||
{
|
||||
ComboboxFilterContent ret;
|
||||
QDataStream ds(v.toByteArray());
|
||||
ds.startTransaction();
|
||||
ds >> ret;
|
||||
ds.commitTransaction();
|
||||
ret.m_isValid = ds.status() == QDataStream::Ok;
|
||||
QVariant toVariant() const
|
||||
{
|
||||
if (!isValid())
|
||||
return QVariant();
|
||||
QByteArray ba;
|
||||
QDataStream ds(&ba, QIODevice::WriteOnly);
|
||||
ds << (*this);
|
||||
return ba;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
static ComboboxFilterContent fromVariant(const QVariant& v)
|
||||
{
|
||||
ComboboxFilterContent ret;
|
||||
QDataStream ds(v.toByteArray());
|
||||
ds.startTransaction();
|
||||
ds >> ret;
|
||||
ds.commitTransaction();
|
||||
ret.m_isValid = ds.status() == QDataStream::Ok;
|
||||
|
||||
inline friend QDataStream &operator<<(QDataStream &ds, const ComboboxFilterContent &cfc)
|
||||
{
|
||||
ds << cfc.data << cfc.sortItems;
|
||||
return ds;
|
||||
}
|
||||
inline friend QDataStream &operator>>(QDataStream &ds, ComboboxFilterContent &cfc)
|
||||
{
|
||||
ds >> cfc.data >> cfc.sortItems;
|
||||
return ds;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isValid = true;
|
||||
inline friend QDataStream& operator<<(QDataStream& ds, const ComboboxFilterContent& cfc)
|
||||
{
|
||||
ds << cfc.data << cfc.sortItems;
|
||||
return ds;
|
||||
}
|
||||
|
||||
inline friend QDataStream& operator>>(QDataStream& ds, ComboboxFilterContent& cfc)
|
||||
{
|
||||
ds >> cfc.data >> cfc.sortItems;
|
||||
return ds;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isValid = true;
|
||||
};
|
||||
|
||||
|
||||
class LTSWIDGETS_EXPORT LtsColumnFilterProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static constexpr int ComboboxFilterRole = Qt::UserRole + 17;
|
||||
Q_OBJECT
|
||||
public:
|
||||
static constexpr int ComboboxFilterRole = Qt::UserRole + 17;
|
||||
|
||||
explicit LtsColumnFilterProxyModel(QObject *parent = nullptr);
|
||||
explicit LtsColumnFilterProxyModel(QObject* parent = nullptr);
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
void setRecursiveFilteringEnabled(bool recursive);
|
||||
bool recursiveFilteringEnabled() const;
|
||||
void setRecursiveFilteringEnabled(bool recursive);
|
||||
bool recursiveFilteringEnabled() const;
|
||||
#endif
|
||||
|
||||
const QHash<int, QRegularExpression> &columnStringFilters() const { return m_columnStringFilters; }
|
||||
const QHash<int, QVariant> &columnDataFilters() const { return m_columnDataFilters; }
|
||||
const QHash<int, QRegularExpression>& columnStringFilters() const
|
||||
{
|
||||
return m_columnStringFilters;
|
||||
}
|
||||
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
const QHash<int, QVariant>& columnDataFilters() const
|
||||
{
|
||||
return m_columnDataFilters;
|
||||
}
|
||||
|
||||
virtual void setColumnStringFilter(const QString &newFilterString, int column);
|
||||
virtual void setColumnDataFilter(const QVariant &newFilterData, int column);
|
||||
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
|
||||
|
||||
public slots:
|
||||
void onSetColumnStringFilter(const QString &newFilterString, int column);
|
||||
void onSetColumnDataFilter(const QVariant &newFilterData, int column);
|
||||
virtual void setColumnStringFilter(const QString& newFilterString, int column);
|
||||
virtual void setColumnDataFilter(const QVariant& newFilterData, int column);
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
public slots:
|
||||
void onSetColumnStringFilter(const QString& newFilterString, int column);
|
||||
void onSetColumnDataFilter(const QVariant& newFilterData, int column);
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
bool checkIfOneChildIsVisible(const QModelIndex &parent) const;
|
||||
bool checkIfOneChildIsVisible(const QModelIndex& parent) const;
|
||||
#endif
|
||||
private:
|
||||
QHash<int, QRegularExpression> m_columnStringFilters;
|
||||
QHash<int, QVariant> m_columnDataFilters;
|
||||
private:
|
||||
QHash<int, QRegularExpression> m_columnStringFilters;
|
||||
QHash<int, QVariant> m_columnDataFilters;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
bool m_bRecursiveFiltering = false;
|
||||
bool m_bRecursiveFiltering = false;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+46
-65
@@ -1,118 +1,99 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_combo_box.h"
|
||||
#include "lts_selection_popup.h"
|
||||
|
||||
#include "lts_message_dialog.h"
|
||||
#include "lts_selection_popup.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QShowEvent>
|
||||
|
||||
|
||||
#ifdef NEVER
|
||||
# include <QDebug>
|
||||
#endif
|
||||
#include <QDebug>
|
||||
#endif
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
bool LtsComboBox::s_useSelectionDialog = false;
|
||||
|
||||
LtsComboBox::LtsComboBox(QWidget *parent)
|
||||
: QComboBox(parent)
|
||||
, m_currentIndex(-1)
|
||||
LtsComboBox::LtsComboBox(QWidget* parent) : QComboBox(parent), m_currentIndex(-1)
|
||||
{
|
||||
connect(this, &LtsComboBox::signalExternallyChanged,
|
||||
this, &LtsComboBox::signalRefill);
|
||||
connect(this, &LtsComboBox::signalExternallyChanged, this, &LtsComboBox::signalRefill);
|
||||
}
|
||||
|
||||
void LtsComboBox::setUseSelectionDialog(bool bUseSelectionDialog)
|
||||
{
|
||||
s_useSelectionDialog = bUseSelectionDialog;
|
||||
s_useSelectionDialog = bUseSelectionDialog;
|
||||
}
|
||||
|
||||
void LtsComboBox::showEvent(QShowEvent *e)
|
||||
void LtsComboBox::showEvent(QShowEvent* e)
|
||||
{
|
||||
QComboBox::showEvent(e);
|
||||
QComboBox::showEvent(e);
|
||||
|
||||
m_currentIndex = currentIndex();
|
||||
m_currentIndex = currentIndex();
|
||||
}
|
||||
|
||||
void LtsComboBox::enterEvent(QEvent *e)
|
||||
void LtsComboBox::enterEvent(QEnterEvent* e)
|
||||
{
|
||||
BaseClass::enterEvent(e);
|
||||
emit signalEnterEvent();
|
||||
BaseClass::enterEvent(e);
|
||||
emit signalEnterEvent();
|
||||
}
|
||||
|
||||
void LtsComboBox::leaveEvent(QEvent *e)
|
||||
void LtsComboBox::leaveEvent(QEvent* e)
|
||||
{
|
||||
BaseClass::leaveEvent(e);
|
||||
emit signalLeaveEvent();
|
||||
BaseClass::leaveEvent(e);
|
||||
emit signalLeaveEvent();
|
||||
}
|
||||
|
||||
void LtsComboBox::showPopup()
|
||||
{
|
||||
bool bUseSelectionDialog = s_useSelectionDialog;
|
||||
if (QGuiApplication::queryKeyboardModifiers() == Qt::ControlModifier)
|
||||
bUseSelectionDialog = !bUseSelectionDialog;
|
||||
if (!bUseSelectionDialog)
|
||||
{
|
||||
QComboBox::showPopup();
|
||||
return;
|
||||
}
|
||||
bool bUseSelectionDialog = s_useSelectionDialog;
|
||||
if (QGuiApplication::queryKeyboardModifiers() == Qt::ControlModifier)
|
||||
bUseSelectionDialog = !bUseSelectionDialog;
|
||||
if (!bUseSelectionDialog)
|
||||
{
|
||||
QComboBox::showPopup();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!model()->rowCount())
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("There are no items available!"));
|
||||
return;
|
||||
}
|
||||
if (!model()->rowCount())
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("There are no items available!"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LtsSelectionPopup* popup = new LtsSelectionPopup(model(), currentIndex(), this);
|
||||
popup->setAttribute(Qt::WA_DeleteOnClose);
|
||||
LtsSelectionPopup* popup = new LtsSelectionPopup(model(), currentIndex(), this);
|
||||
popup->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
#ifdef NEVER
|
||||
|
||||
|
||||
|
||||
connect(popup, static_cast<void (LtsSelectionPopup::*)(int)>(&LtsSelectionPopup::currentIndexChanged), this,
|
||||
[](int idx) { qCritical() << " LtsComboBox: called: currentIndexChanged(int), idx=" << idx; });
|
||||
|
||||
connect(popup, static_cast<void (LtsSelectionPopup::*)(int)>(&LtsSelectionPopup::activated), this,
|
||||
[](int idx) { qCritical() << " LtsComboBox: called: activated(int), idx=" << idx; });
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
connect(popup, static_cast<void (LtsSelectionPopup::*)(int)>(&LtsSelectionPopup::currentIndexChanged), this, [](int idx){
|
||||
qCritical() << " LtsComboBox: called: currentIndexChanged(int), idx=" << idx;
|
||||
});
|
||||
connect(popup, &LtsSelectionPopup::currentIndexChanged, this, &LtsComboBox::userChangedIndex);
|
||||
connect(popup, &LtsSelectionPopup::activated, this,
|
||||
static_cast<void (LtsComboBox::*)(int)>(&LtsComboBox::activated));
|
||||
|
||||
|
||||
connect(popup, static_cast<void (LtsSelectionPopup::*)(int)>(&LtsSelectionPopup::activated), this, [](int idx){
|
||||
qCritical() << " LtsComboBox: called: activated(int), idx=" << idx;
|
||||
});
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
connect(popup, &LtsSelectionPopup::currentIndexChanged,
|
||||
this, &LtsComboBox::userChangedIndex);
|
||||
connect(popup, &LtsSelectionPopup::activated,
|
||||
this, static_cast<void (LtsComboBox::*)(int)>(&LtsComboBox::activated));
|
||||
|
||||
popup->show();
|
||||
popup->show();
|
||||
}
|
||||
|
||||
|
||||
void LtsComboBox::userChangedIndex(int index)
|
||||
{
|
||||
m_currentIndex = index;
|
||||
setCurrentIndex(index);
|
||||
m_currentIndex = index;
|
||||
setCurrentIndex(index);
|
||||
}
|
||||
|
||||
|
||||
bool LtsComboBox::hasValueChanged() const
|
||||
{
|
||||
if (m_currentIndex == -1)
|
||||
return false;
|
||||
return !(currentIndex() == m_currentIndex);
|
||||
if (m_currentIndex == -1)
|
||||
return false;
|
||||
return !(currentIndex() == m_currentIndex);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+34
-38
@@ -1,60 +1,56 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include "ltswidgets_export.h"
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
|
||||
|
||||
class LTSWIDGETS_EXPORT LtsComboBox : public QComboBox
|
||||
class LTSWIDGETS_EXPORT LtsComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = QComboBox;
|
||||
Q_OBJECT
|
||||
using BaseClass = QComboBox;
|
||||
|
||||
public:
|
||||
explicit LtsComboBox(QWidget *parent = nullptr);
|
||||
~LtsComboBox() = default;
|
||||
public:
|
||||
explicit LtsComboBox(QWidget* parent = nullptr);
|
||||
~LtsComboBox() = default;
|
||||
|
||||
|
||||
static void setUseSelectionDialog(bool bUseSelectionDialog);
|
||||
|
||||
static void setUseSelectionDialog(bool bUseSelectionDialog);
|
||||
bool hasValueChanged() const;
|
||||
|
||||
|
||||
void setExternalContentType(int ect)
|
||||
{
|
||||
m_externalContentType = ect;
|
||||
}
|
||||
|
||||
bool hasValueChanged() const;
|
||||
int externalContentType() const
|
||||
{
|
||||
return m_externalContentType;
|
||||
}
|
||||
|
||||
void setExternalContentType(int ect) { m_externalContentType = ect; }
|
||||
int externalContentType() const { return m_externalContentType; }
|
||||
protected:
|
||||
void showPopup() override;
|
||||
|
||||
protected:
|
||||
|
||||
void showEvent(QShowEvent* e) override;
|
||||
void enterEvent(QEnterEvent* e) override;
|
||||
void leaveEvent(QEvent*) override;
|
||||
|
||||
void showPopup() override;
|
||||
protected slots:
|
||||
void userChangedIndex(int index);
|
||||
|
||||
void showEvent(QShowEvent *e) override;
|
||||
void enterEvent(QEvent *e) override;
|
||||
void leaveEvent(QEvent *) override;
|
||||
signals:
|
||||
void signalExternallyChanged();
|
||||
void signalRefill();
|
||||
void signalEnterEvent();
|
||||
void signalLeaveEvent();
|
||||
|
||||
protected slots:
|
||||
void userChangedIndex(int index);
|
||||
|
||||
signals:
|
||||
void signalExternallyChanged();
|
||||
void signalRefill();
|
||||
void signalEnterEvent();
|
||||
void signalLeaveEvent();
|
||||
|
||||
private:
|
||||
int m_currentIndex;
|
||||
int m_externalContentType;
|
||||
static bool s_useSelectionDialog;
|
||||
private:
|
||||
int m_currentIndex;
|
||||
int m_externalContentType;
|
||||
static bool s_useSelectionDialog;
|
||||
};
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+1214
-1285
File diff suppressed because it is too large.
Load diff
Executable → Regular
+55
-64
@@ -1,118 +1,109 @@
|
||||
#include "lts_date_time_edit_p.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
#include <QRegularExpression>
|
||||
#include <QValidator>
|
||||
#include <QKeyEvent>
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
void LineEdit::clear()
|
||||
{
|
||||
setStyleSheet(QString());
|
||||
QLineEdit::clear();
|
||||
setStyleSheet(QString());
|
||||
QLineEdit::clear();
|
||||
}
|
||||
|
||||
bool LineEdit::isEmpty() const
|
||||
{
|
||||
return text().isEmpty();
|
||||
return text().isEmpty();
|
||||
}
|
||||
|
||||
void LineEdit::keyPressEvent(QKeyEvent *event)
|
||||
void LineEdit::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
const bool wasEmpty = isEmpty();
|
||||
QLineEdit::keyPressEvent(event);
|
||||
int keyCode = event->key();
|
||||
if (keyCode == Qt::Key_Backspace && wasEmpty)
|
||||
{
|
||||
emit focusOutBackspace();
|
||||
focusPreviousChild();
|
||||
event->accept();
|
||||
}
|
||||
const bool wasEmpty = isEmpty();
|
||||
QLineEdit::keyPressEvent(event);
|
||||
int keyCode = event->key();
|
||||
if (keyCode == Qt::Key_Backspace && wasEmpty)
|
||||
{
|
||||
emit focusOutBackspace();
|
||||
focusPreviousChild();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void LineEdit::contextMenuEvent(QContextMenuEvent *e)
|
||||
void LineEdit::contextMenuEvent(QContextMenuEvent* e)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
|
||||
Q_UNUSED(e);
|
||||
}
|
||||
|
||||
void LineEdit::focusOutEvent(QFocusEvent *event)
|
||||
void LineEdit::focusOutEvent(QFocusEvent* event)
|
||||
{
|
||||
QLineEdit::focusOutEvent(event);
|
||||
emit focusOut();
|
||||
QLineEdit::focusOutEvent(event);
|
||||
emit focusOut();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DigitsLineEdit::DigitsLineEdit(QWidget *parent)
|
||||
: LineEdit(parent)
|
||||
DigitsLineEdit::DigitsLineEdit(QWidget* parent) : LineEdit(parent)
|
||||
{
|
||||
setAlignment(Qt::AlignRight);
|
||||
QRegularExpression rx(QLatin1String("[-]{0,1}[0-9 ]*"));
|
||||
setValidator(new QRegularExpressionValidator(rx, this));
|
||||
setAlignment(Qt::AlignRight);
|
||||
QRegularExpression rx(QLatin1String("[-]{0,1}[0-9 ]*"));
|
||||
setValidator(new QRegularExpressionValidator(rx, this));
|
||||
}
|
||||
|
||||
void DigitsLineEdit::setExactNumDigits(int num)
|
||||
{
|
||||
m_exactNumDigits = num;
|
||||
m_exactNumDigits = num;
|
||||
|
||||
QRegularExpression rx(QString::asprintf("^[0-9 ]{%d}$", num));
|
||||
setValidator(new QRegularExpressionValidator(rx, this));
|
||||
QRegularExpression rx(QString::asprintf("^[0-9 ]{%d}$", num));
|
||||
setValidator(new QRegularExpressionValidator(rx, this));
|
||||
}
|
||||
|
||||
void DigitsLineEdit::setValue(int val)
|
||||
{
|
||||
QString str;
|
||||
QString str;
|
||||
|
||||
if (m_exactNumDigits == -1)
|
||||
str.setNum(val);
|
||||
else
|
||||
str = QStringLiteral("%1").arg(val, m_exactNumDigits, 10, QLatin1Char('0'));
|
||||
if (m_exactNumDigits == -1)
|
||||
str.setNum(val);
|
||||
else
|
||||
str = QStringLiteral("%1").arg(val, m_exactNumDigits, 10, QLatin1Char('0'));
|
||||
|
||||
setText(str);
|
||||
setText(str);
|
||||
}
|
||||
|
||||
int DigitsLineEdit::getValue() const
|
||||
{
|
||||
if (text().isEmpty())
|
||||
return 0;
|
||||
return text().remove(QLatin1Char(' ')).toInt();
|
||||
if (text().isEmpty())
|
||||
return 0;
|
||||
return text().remove(QLatin1Char(' ')).toInt();
|
||||
}
|
||||
|
||||
void DigitsLineEdit::setCursorPosition(int curPos)
|
||||
{
|
||||
|
||||
curPos = curPos < 0 ? 1 : curPos;
|
||||
QLineEdit::setCursorPosition(curPos);
|
||||
|
||||
curPos = curPos < 0 ? 1 : curPos;
|
||||
QLineEdit::setCursorPosition(curPos);
|
||||
}
|
||||
|
||||
void DigitsLineEdit::wheelEvent(QWheelEvent *event)
|
||||
void DigitsLineEdit::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
LineEdit::wheelEvent(event);
|
||||
const QString txt = text();
|
||||
if (m_exactNumDigits > 0 && txt.length() != m_exactNumDigits)
|
||||
return;
|
||||
event->accept();
|
||||
int cursorPos = cursorPosition();
|
||||
emit wheelEventReceived(event->delta() > 0, cursorPos);
|
||||
LineEdit::wheelEvent(event);
|
||||
const QString txt = text();
|
||||
if (m_exactNumDigits > 0 && txt.length() != m_exactNumDigits)
|
||||
return;
|
||||
event->accept();
|
||||
int cursorPos = cursorPosition();
|
||||
emit wheelEventReceived(event->angleDelta().y() > 0, cursorPos);
|
||||
}
|
||||
|
||||
void DigitsLineEdit::keyPressEvent(QKeyEvent *event)
|
||||
void DigitsLineEdit::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
LineEdit::keyPressEvent(event);
|
||||
if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)
|
||||
{
|
||||
const bool bUp = event->key() == Qt::Key_Up;
|
||||
const int cursorPos = cursorPosition();
|
||||
emit wheelEventReceived(bUp, cursorPos);
|
||||
}
|
||||
LineEdit::keyPressEvent(event);
|
||||
if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)
|
||||
{
|
||||
const bool bUp = event->key() == Qt::Key_Up;
|
||||
const int cursorPos = cursorPosition();
|
||||
emit wheelEventReceived(bUp, cursorPos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+1229
-1300
File diff suppressed because it is too large.
Load diff
Executable → Regular
+441
-552
File diff suppressed because it is too large.
Load diff
Executable → Regular
+393
-394
@@ -1,57 +1,79 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include "lts_base.h"
|
||||
#include "lts_dialog_button_box.h"
|
||||
#include "ltswidgets_export.h"
|
||||
#include "requirement_widget.h"
|
||||
#include "lts_dialog_button_box.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QLineEdit>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QSlider>
|
||||
#include <QDebug>
|
||||
#include <QLineEdit>
|
||||
#include <QObject>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPointer>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QSlider>
|
||||
#include <QSpinBox>
|
||||
#include <QTextEdit>
|
||||
#include <QWidget>
|
||||
#include <QRadioButton>
|
||||
#include <QPointer>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class TopicInfo
|
||||
{
|
||||
public:
|
||||
int entityId() const { return m_entityId; }
|
||||
const QString &topicName() const { return m_topicName; }
|
||||
bool isLocked() const { return m_locked; }
|
||||
bool isValid() const { return m_valid; }
|
||||
public:
|
||||
int entityId() const
|
||||
{
|
||||
return m_entityId;
|
||||
}
|
||||
|
||||
void setEntity(int entityId) { m_entityId = entityId; }
|
||||
void setTopicName(const QString &topicName) { m_topicName = topicName; }
|
||||
void setLocked(bool locked = true) { m_locked = locked; }
|
||||
void setValid() { m_valid = true; }
|
||||
const QString& topicName() const
|
||||
{
|
||||
return m_topicName;
|
||||
}
|
||||
|
||||
private:
|
||||
bool isLocked() const
|
||||
{
|
||||
return m_locked;
|
||||
}
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
QString m_topicName;
|
||||
int m_entityId{0};
|
||||
bool m_locked{false};
|
||||
bool m_valid{false};
|
||||
bool isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
void setEntity(int entityId)
|
||||
{
|
||||
m_entityId = entityId;
|
||||
}
|
||||
|
||||
void setTopicName(const QString& topicName)
|
||||
{
|
||||
m_topicName = topicName;
|
||||
}
|
||||
|
||||
void setLocked(bool locked = true)
|
||||
{
|
||||
m_locked = locked;
|
||||
}
|
||||
|
||||
void setValid()
|
||||
{
|
||||
m_valid = true;
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_topicName;
|
||||
int m_entityId{0};
|
||||
bool m_locked{false};
|
||||
bool m_valid{false};
|
||||
};
|
||||
|
||||
|
||||
class LtsBaseLayoutWidget;
|
||||
class LtsDialogHelper;
|
||||
class LtsProgressDialogHelper;
|
||||
@@ -59,416 +81,393 @@ class LtsDialogButtonBox;
|
||||
class LtsToolBarArea;
|
||||
class OverlayContainer;
|
||||
|
||||
enum class ButtonCombination {
|
||||
OkApplyCancel,
|
||||
|
||||
enum class ButtonCombination
|
||||
{
|
||||
OkApplyCancel,
|
||||
OkCancel,
|
||||
|
||||
OkCancel,
|
||||
|
||||
|
||||
|
||||
CloseOnly,
|
||||
SeamlessDialog,
|
||||
CloseOnly,
|
||||
SeamlessDialog,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class LTSWIDGETS_EXPORT LtsDialog : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool unchangeable READ unchangeable WRITE setUnchangeable)
|
||||
public:
|
||||
static int s_object_count;
|
||||
Q_PROPERTY(bool unchangeable READ unchangeable WRITE setUnchangeable)
|
||||
public:
|
||||
static int s_object_count;
|
||||
|
||||
|
||||
explicit LtsDialog(QWidget* parent = nullptr, ButtonCombination buttonCombination = ButtonCombination::CloseOnly,
|
||||
bool closeable = true);
|
||||
~LtsDialog();
|
||||
|
||||
explicit LtsDialog(QWidget *parent = nullptr, ButtonCombination buttonCombination = ButtonCombination::CloseOnly, bool closeable = true);
|
||||
~LtsDialog();
|
||||
LtsDialogHelper* getHelper();
|
||||
|
||||
|
||||
|
||||
LtsDialogHelper *getHelper();
|
||||
|
||||
bool hasUnsavedChanges() const { return m_changesMade || m_currentlyBlocking; }
|
||||
|
||||
|
||||
|
||||
virtual void retranslate() = 0;
|
||||
|
||||
void closeRequest();
|
||||
void setUnchangeable(bool unchangeable = true);
|
||||
bool unchangeable() const { return m_unchangeableDialog; }
|
||||
|
||||
|
||||
|
||||
bool addDialog(LtsDialog *dialog, const QString &menuGroup, const QString &identifier, const LayoutArea &layoutArea = LayoutArea::eDialogTab, bool setClosable = true, bool focusNewTab = true);
|
||||
|
||||
|
||||
Q_DECL_DEPRECATED bool addDialogFixed(LtsDialog *dialog, const char *menuGroupUntranslated, const QString &identifier, const LayoutArea &layoutArea = LayoutArea::eDialogTab, bool setClosable = true, bool focusNewTab = true);
|
||||
bool focusDialog(const QString &menuGroup, const QString &identifier, const LayoutArea &layoutArea);
|
||||
bool amIFocused() const;
|
||||
void setBaseLayoutWidget(LtsBaseLayoutWidget *baseLayoutWidget);
|
||||
void __unchange__() { resetChanges(); }
|
||||
void setClosable(bool closable) { m_isClosable = closable; }
|
||||
bool isClosable() const { return m_isClosable; }
|
||||
virtual void aboutToClose() {}
|
||||
void setMenuGroup(const QString &menuGroup) { m_menuGroup = menuGroup; }
|
||||
const QString &menuGroup() const { return m_menuGroup; }
|
||||
void setIdentifier(const QString &identifier);
|
||||
virtual void tableColumnOrganiserSetting(){};
|
||||
const QString &identifier() const { return m_identifier; }
|
||||
|
||||
void setOverlay(QWidget *widget);
|
||||
void unsetOverlay();
|
||||
|
||||
|
||||
|
||||
static inline void setMinWidthForWidgetHelper(QWidget *w)
|
||||
{
|
||||
int width = w->sizeHint().width();
|
||||
w->setMinimumWidth(width);
|
||||
}
|
||||
|
||||
QString windowTitle() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void tryLockTopicNew();
|
||||
|
||||
|
||||
|
||||
virtual void tryLockTopicNew (const QString &topicName, int entityId = -1);
|
||||
|
||||
|
||||
void triggerTopicLock();
|
||||
|
||||
void setOnlineHelpFilename(const QString &fileName);
|
||||
void setCurrentlyBlocking(bool currentlyBlocking = true) { m_currentlyBlocking = currentlyBlocking; }
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
void startMainSelect(LtsWidgets::LayoutArea);
|
||||
|
||||
|
||||
|
||||
void endMainSelect(LtsWidgets::LayoutArea);
|
||||
|
||||
|
||||
|
||||
void signalChangesMade();
|
||||
|
||||
void signalHide(QObject *object);
|
||||
|
||||
|
||||
|
||||
void signalChangesReset();
|
||||
|
||||
void signalFocused();
|
||||
void visibilityChanged(bool visible);
|
||||
void signalLockTopic(const LtsWidgets::TopicInfo &topicInfo);
|
||||
void signalShowOnlineHelp(const QString &fileName);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
void translate(const QString &title);
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
|
||||
|
||||
void translate(T *ui, const QString &title)
|
||||
{
|
||||
translate(title);
|
||||
if (ui)
|
||||
ui->retranslateUi(this);
|
||||
|
||||
m_uiRequirements->retranslate();
|
||||
}
|
||||
|
||||
void hideEvent(QHideEvent *event) override
|
||||
{
|
||||
QWidget::hideEvent(event);
|
||||
emit visibilityChanged(false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
|
||||
void translate(T *ui, const QString &custom, bool isNew, const QString &title)
|
||||
{
|
||||
QString newTitle;
|
||||
if (!isNew)
|
||||
bool hasUnsavedChanges() const
|
||||
{
|
||||
if (unchangeable())
|
||||
{
|
||||
if (custom.isEmpty())
|
||||
newTitle = (tr("Show %1").arg(title));
|
||||
return m_changesMade || m_currentlyBlocking;
|
||||
}
|
||||
|
||||
virtual void retranslate() = 0;
|
||||
|
||||
void closeRequest();
|
||||
void setUnchangeable(bool unchangeable = true);
|
||||
|
||||
bool unchangeable() const
|
||||
{
|
||||
return m_unchangeableDialog;
|
||||
}
|
||||
|
||||
bool addDialog(LtsDialog* dialog, const QString& menuGroup, const QString& identifier,
|
||||
const LayoutArea& layoutArea = LayoutArea::eDialogTab, bool setClosable = true,
|
||||
bool focusNewTab = true);
|
||||
|
||||
Q_DECL_DEPRECATED bool addDialogFixed(LtsDialog* dialog, const char* menuGroupUntranslated,
|
||||
const QString& identifier,
|
||||
const LayoutArea& layoutArea = LayoutArea::eDialogTab,
|
||||
bool setClosable = true, bool focusNewTab = true);
|
||||
bool focusDialog(const QString& menuGroup, const QString& identifier, const LayoutArea& layoutArea);
|
||||
bool amIFocused() const;
|
||||
void setBaseLayoutWidget(LtsBaseLayoutWidget* baseLayoutWidget);
|
||||
|
||||
void __unchange__()
|
||||
{
|
||||
resetChanges();
|
||||
}
|
||||
|
||||
void setClosable(bool closable)
|
||||
{
|
||||
m_isClosable = closable;
|
||||
}
|
||||
|
||||
bool isClosable() const
|
||||
{
|
||||
return m_isClosable;
|
||||
}
|
||||
|
||||
virtual void aboutToClose() {}
|
||||
|
||||
void setMenuGroup(const QString& menuGroup)
|
||||
{
|
||||
m_menuGroup = menuGroup;
|
||||
}
|
||||
|
||||
const QString& menuGroup() const
|
||||
{
|
||||
return m_menuGroup;
|
||||
}
|
||||
|
||||
void setIdentifier(const QString& identifier);
|
||||
virtual void tableColumnOrganiserSetting(){};
|
||||
|
||||
const QString& identifier() const
|
||||
{
|
||||
return m_identifier;
|
||||
}
|
||||
|
||||
void setOverlay(QWidget* widget);
|
||||
void unsetOverlay();
|
||||
|
||||
static inline void setMinWidthForWidgetHelper(QWidget* w)
|
||||
{
|
||||
int width = w->sizeHint().width();
|
||||
w->setMinimumWidth(width);
|
||||
}
|
||||
|
||||
QString windowTitle() const
|
||||
{
|
||||
return m_title;
|
||||
}
|
||||
|
||||
void tryLockTopicNew();
|
||||
|
||||
virtual void tryLockTopicNew(const QString& topicName, int entityId = -1);
|
||||
|
||||
void triggerTopicLock();
|
||||
|
||||
void setOnlineHelpFilename(const QString& fileName);
|
||||
|
||||
void setCurrentlyBlocking(bool currentlyBlocking = true)
|
||||
{
|
||||
m_currentlyBlocking = currentlyBlocking;
|
||||
}
|
||||
|
||||
signals:
|
||||
|
||||
void startMainSelect(LtsWidgets::LayoutArea);
|
||||
|
||||
void endMainSelect(LtsWidgets::LayoutArea);
|
||||
|
||||
void signalChangesMade();
|
||||
|
||||
void signalHide(QObject* object);
|
||||
|
||||
void signalChangesReset();
|
||||
|
||||
void signalFocused();
|
||||
void visibilityChanged(bool visible);
|
||||
void signalLockTopic(const LtsWidgets::TopicInfo& topicInfo);
|
||||
void signalShowOnlineHelp(const QString& fileName);
|
||||
|
||||
protected:
|
||||
void translate(const QString& title);
|
||||
|
||||
template <typename T>
|
||||
|
||||
void translate(T* ui, const QString& title)
|
||||
{
|
||||
translate(title);
|
||||
if (ui)
|
||||
ui->retranslateUi(this);
|
||||
|
||||
m_uiRequirements->retranslate();
|
||||
}
|
||||
|
||||
void hideEvent(QHideEvent* event) override
|
||||
{
|
||||
QWidget::hideEvent(event);
|
||||
emit visibilityChanged(false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
void translate(T* ui, const QString& custom, bool isNew, const QString& title)
|
||||
{
|
||||
QString newTitle;
|
||||
if (!isNew)
|
||||
{
|
||||
if (unchangeable())
|
||||
{
|
||||
if (custom.isEmpty())
|
||||
newTitle = (tr("Show %1").arg(title));
|
||||
else
|
||||
newTitle = (tr("Show %1: %2").arg(title, custom));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (custom.isEmpty())
|
||||
newTitle = (tr("Edit %1").arg(title));
|
||||
else
|
||||
newTitle = (tr("Edit %1: %2").arg(title, custom));
|
||||
|
||||
tryLockTopicNew();
|
||||
}
|
||||
}
|
||||
else
|
||||
newTitle = (tr("Show %1: %2").arg(title, custom));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (custom.isEmpty())
|
||||
newTitle = (tr("Edit %1").arg(title));
|
||||
else
|
||||
newTitle = (tr("Edit %1: %2").arg(title, custom));
|
||||
{
|
||||
newTitle = (tr("New %1").arg(title));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Apply)->hide();
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setText(tr("Create"));
|
||||
}
|
||||
|
||||
|
||||
tryLockTopicNew();
|
||||
}
|
||||
translate(ui, newTitle);
|
||||
}
|
||||
else
|
||||
|
||||
template <typename T>
|
||||
|
||||
void translate(T* ui, const QString& customUniqueTopicName, int topicId, const QString& custom,
|
||||
const QString& title)
|
||||
{
|
||||
newTitle = (tr("New %1").arg(title));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Apply)->hide();
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setText(tr("Create"));
|
||||
Q_UNUSED(customUniqueTopicName);
|
||||
|
||||
initTopicLockHandler(customUniqueTopicName, topicId);
|
||||
|
||||
translate(ui, custom, (topicId < 1), title);
|
||||
}
|
||||
|
||||
translate(ui, newTitle);
|
||||
}
|
||||
template <typename T, typename S>
|
||||
|
||||
|
||||
template <typename T>
|
||||
|
||||
|
||||
void translate(T* ui, const QString &customUniqueTopicName, int topicId, const QString &custom, const QString &title)
|
||||
{
|
||||
Q_UNUSED(customUniqueTopicName);
|
||||
|
||||
initTopicLockHandler(customUniqueTopicName, topicId);
|
||||
|
||||
translate(ui, custom ,
|
||||
(topicId < 1 ),
|
||||
title);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename S>
|
||||
|
||||
|
||||
void translate(T *ui, const S &data, const QString &custom, const QString &title)
|
||||
{
|
||||
translate(ui, QString::fromUtf8(typeid(data).name()), data.id(), custom , title);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename S>
|
||||
|
||||
|
||||
void translate(T *ui, const S &data, const QString &title)
|
||||
{
|
||||
translate(ui, data, QString::fromStdString(data.name()), title);
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void dialogCanceled() {}
|
||||
LtsBaseLayoutWidget* baseLayoutWidget();
|
||||
void setNoTopicLock() { m_noLockTopic = true; }
|
||||
|
||||
private:
|
||||
friend class LtsDialogHelper;
|
||||
|
||||
bool m_changesMade;
|
||||
bool m_currentlyBlocking { false };
|
||||
bool m_firstShow;
|
||||
QPointer<LtsBaseLayoutWidget> m_baseLayoutWidget;
|
||||
bool m_isClosable;
|
||||
TopicInfo m_topicInfo;
|
||||
|
||||
public:
|
||||
QString m_topicLockedBy;
|
||||
|
||||
private:
|
||||
bool m_noLockTopic;
|
||||
bool m_unchangeableDialog;
|
||||
QPointer<LtsDialogHelper> m_dialogHelper;
|
||||
|
||||
QString m_title;
|
||||
QString m_onlineHelpFileName;
|
||||
QString m_menuGroup;
|
||||
QString m_identifier;
|
||||
|
||||
|
||||
QPointer<OverlayContainer> m_overlayContainer;
|
||||
QPointer<QWidget> m_overlayWidget;
|
||||
|
||||
bool _apply();
|
||||
void _close();
|
||||
void _discard();
|
||||
void _hide();
|
||||
void resetChanges();
|
||||
void addDebugMenuButton();
|
||||
void tryLockTopic();
|
||||
void initTopicLockHandler(const QString &topicName, int entityId);
|
||||
|
||||
|
||||
|
||||
void setWindowTitle(const QString &title);
|
||||
void updateWindowTitle();
|
||||
void addConnections(QWidget *widget);
|
||||
|
||||
template <typename WidgetType, typename SignalFunc>
|
||||
bool addChangesMadeSignal(QWidget *widget, SignalFunc signal)
|
||||
{
|
||||
WidgetType *concreteWidget = qobject_cast<WidgetType *>(widget);
|
||||
|
||||
if (!concreteWidget)
|
||||
return false;
|
||||
|
||||
connect(concreteWidget, signal, this, &LtsDialog::slotChangesMade);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <typename WidgetType>
|
||||
void setWidgetsReadonly(bool readonly)
|
||||
{
|
||||
const auto children = findChildren<WidgetType *>();
|
||||
for (WidgetType *widget : children )
|
||||
void translate(T* ui, const S& data, const QString& custom, const QString& title)
|
||||
{
|
||||
widget->setProperty("lastReadOnlyState", widget->isReadOnly());
|
||||
widget->setReadOnly(readonly);
|
||||
translate(ui, QString::fromUtf8(typeid(data).name()), data.id(), custom, title);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
|
||||
template <typename WidgetType>
|
||||
void setWidgetsDisabled(bool disabled)
|
||||
{
|
||||
const auto children = findChildren<WidgetType *>();
|
||||
for (WidgetType *widget : children)
|
||||
void translate(T* ui, const S& data, const QString& title)
|
||||
{
|
||||
widget->setProperty("lastEnabledState", widget->isEnabled());
|
||||
widget->setEnabled(!disabled);
|
||||
translate(ui, data, QString::fromStdString(data.name()), title);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
void restoreReadonly()
|
||||
{
|
||||
const auto children = findChildren<WidgetType *>();
|
||||
for (WidgetType *widget : children)
|
||||
virtual void dialogCanceled() {}
|
||||
|
||||
LtsBaseLayoutWidget* baseLayoutWidget();
|
||||
|
||||
void setNoTopicLock()
|
||||
{
|
||||
QVariant lastState = widget->property("lastReadOnlyState");
|
||||
if (lastState.isValid() && !lastState.isNull() && lastState.canConvert(QMetaType::Bool))
|
||||
widget->setReadOnly(lastState.toBool());
|
||||
m_noLockTopic = true;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename WidgetType>
|
||||
void restoreEnabled()
|
||||
{
|
||||
const auto children = findChildren<WidgetType *>();
|
||||
for (WidgetType *widget : children)
|
||||
private:
|
||||
friend class LtsDialogHelper;
|
||||
|
||||
bool m_changesMade;
|
||||
bool m_currentlyBlocking{false};
|
||||
bool m_firstShow;
|
||||
QPointer<LtsBaseLayoutWidget> m_baseLayoutWidget;
|
||||
bool m_isClosable;
|
||||
TopicInfo m_topicInfo;
|
||||
|
||||
public:
|
||||
QString m_topicLockedBy;
|
||||
|
||||
private:
|
||||
bool m_noLockTopic;
|
||||
bool m_unchangeableDialog;
|
||||
QPointer<LtsDialogHelper> m_dialogHelper;
|
||||
NGL::INGLLogger& m_logger;
|
||||
|
||||
QString m_title;
|
||||
QString m_onlineHelpFileName;
|
||||
QString m_menuGroup;
|
||||
QString m_identifier;
|
||||
|
||||
QPointer<OverlayContainer> m_overlayContainer;
|
||||
QPointer<QWidget> m_overlayWidget;
|
||||
|
||||
bool _apply();
|
||||
void _close();
|
||||
void _discard();
|
||||
void _hide();
|
||||
void resetChanges();
|
||||
void addDebugMenuButton();
|
||||
void tryLockTopic();
|
||||
void initTopicLockHandler(const QString& topicName, int entityId);
|
||||
|
||||
void setWindowTitle(const QString& title);
|
||||
void updateWindowTitle();
|
||||
void addConnections(QWidget* widget);
|
||||
|
||||
template <typename WidgetType, typename SignalFunc> bool addChangesMadeSignal(QWidget* widget, SignalFunc signal)
|
||||
{
|
||||
QVariant lastState = widget->property("lastEnabledState");
|
||||
if (lastState.isValid() && !lastState.isNull() && lastState.canConvert(QMetaType::Bool))
|
||||
widget->setEnabled(lastState.toBool());
|
||||
WidgetType* concreteWidget = qobject_cast<WidgetType*>(widget);
|
||||
|
||||
if (!concreteWidget)
|
||||
return false;
|
||||
|
||||
connect(concreteWidget, signal, this, &LtsDialog::slotChangesMade);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
template <typename WidgetType> void setWidgetsReadonly(bool readonly)
|
||||
{
|
||||
const auto children = findChildren<WidgetType*>();
|
||||
for (WidgetType* widget : children)
|
||||
{
|
||||
widget->setProperty("lastReadOnlyState", widget->isReadOnly());
|
||||
widget->setReadOnly(readonly);
|
||||
}
|
||||
}
|
||||
|
||||
void slotChangesMade();
|
||||
template <typename WidgetType> void setWidgetsDisabled(bool disabled)
|
||||
{
|
||||
const auto children = findChildren<WidgetType*>();
|
||||
for (WidgetType* widget : children)
|
||||
{
|
||||
widget->setProperty("lastEnabledState", widget->isEnabled());
|
||||
widget->setEnabled(!disabled);
|
||||
}
|
||||
}
|
||||
|
||||
void slotHide();
|
||||
void slotLock(const QString &lockedBy);
|
||||
void slotUnlock();
|
||||
template <typename WidgetType> void restoreReadonly()
|
||||
{
|
||||
const auto children = findChildren<WidgetType*>();
|
||||
for (WidgetType* widget : children)
|
||||
{
|
||||
QVariant lastState = widget->property("lastReadOnlyState");
|
||||
if (lastState.isValid() && !lastState.isNull() && lastState.canConvert(QMetaType::Bool))
|
||||
widget->setReadOnly(lastState.toBool());
|
||||
}
|
||||
}
|
||||
|
||||
private slots:
|
||||
void slotApply();
|
||||
void slotOkay();
|
||||
void slotClose();
|
||||
|
||||
void onReadOnlyButtonClicked();
|
||||
template <typename WidgetType> void restoreEnabled()
|
||||
{
|
||||
const auto children = findChildren<WidgetType*>();
|
||||
for (WidgetType* widget : children)
|
||||
{
|
||||
QVariant lastState = widget->property("lastEnabledState");
|
||||
if (lastState.isValid() && !lastState.isNull() && lastState.canConvert(QMetaType::Bool))
|
||||
widget->setEnabled(lastState.toBool());
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
public slots:
|
||||
|
||||
virtual bool apply() { return true; }
|
||||
void showEvent(QShowEvent *event) override;
|
||||
Button askApplyDiscardCancel();
|
||||
void slotChangesMade();
|
||||
|
||||
LtsDialogButtonBox *m_buttonBox;
|
||||
UiRequirementList *m_uiRequirements;
|
||||
void slotHide();
|
||||
void slotLock(const QString& lockedBy);
|
||||
void slotUnlock();
|
||||
|
||||
private slots:
|
||||
void slotApply();
|
||||
void slotOkay();
|
||||
void slotClose();
|
||||
|
||||
void onReadOnlyButtonClicked();
|
||||
|
||||
protected:
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
|
||||
virtual bool apply()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void showEvent(QShowEvent* event) override;
|
||||
Button askApplyDiscardCancel();
|
||||
|
||||
LtsDialogButtonBox* m_buttonBox;
|
||||
UiRequirementList* m_uiRequirements;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
T *initDialog(T *dialog)
|
||||
template <typename T> T* initDialog(T* dialog)
|
||||
{
|
||||
if (!dialog->init())
|
||||
{
|
||||
dialog->deleteLater();
|
||||
return nullptr;
|
||||
}
|
||||
return dialog;
|
||||
if (!dialog->init())
|
||||
{
|
||||
dialog->deleteLater();
|
||||
return nullptr;
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename ... F>
|
||||
T *initDialog(T *dialog, F&&... f)
|
||||
template <typename T, typename... F> T* initDialog(T* dialog, F&&... f)
|
||||
{
|
||||
if (!dialog->init(std::forward<F>(f)...))
|
||||
{
|
||||
dialog->deleteLater();
|
||||
return nullptr;
|
||||
}
|
||||
return dialog;
|
||||
if (!dialog->init(std::forward<F>(f)...))
|
||||
{
|
||||
dialog->deleteLater();
|
||||
return nullptr;
|
||||
}
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename ... F>
|
||||
T *createThrowableDialog(F&&... f)
|
||||
template <typename T, typename... F> T* createThrowableDialog(F&&... f)
|
||||
{
|
||||
T *dlg = nullptr;
|
||||
T* dlg = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
dlg = new T(std::forward<F>(f)...);
|
||||
}
|
||||
catch (const char *s)
|
||||
{
|
||||
fprintf(stderr, "Dialog could not be created: %s\n", s);
|
||||
return nullptr;
|
||||
}
|
||||
catch (const QString &msg)
|
||||
{
|
||||
fprintf(stderr, "Dialog could not be created: %s\n", msg.toStdString().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
fprintf(stderr, "Dialog could not be created: unknown error\n");
|
||||
return nullptr;
|
||||
}
|
||||
try
|
||||
{
|
||||
dlg = new T(std::forward<F>(f)...);
|
||||
}
|
||||
catch (const char* s)
|
||||
{
|
||||
fprintf(stderr, "Dialog could not be created: %s\n", s);
|
||||
return nullptr;
|
||||
}
|
||||
catch (const QString& msg)
|
||||
{
|
||||
fprintf(stderr, "Dialog could not be created: %s\n", msg.toStdString().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
fprintf(stderr, "Dialog could not be created: unknown error\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dlg;
|
||||
return dlg;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+301
-307
@@ -1,489 +1,483 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_drag_icon.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QButtonGroup>
|
||||
#include <QDrag>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QDragLeaveEvent>
|
||||
#include <QDropEvent>
|
||||
#include <QMimeData>
|
||||
#include <QAction>
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QToolButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QPainter>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
class LtsToolButton : public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LtsToolButton(QWidget *parent)
|
||||
: QToolButton(parent)
|
||||
, m_sameWidgetDrop(false)
|
||||
, m_isDraggable(true)
|
||||
, m_startPos(QPoint())
|
||||
{
|
||||
setAutoFillBackground(false);
|
||||
setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
}
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LtsToolButton(QWidget* parent)
|
||||
: QToolButton(parent), m_sameWidgetDrop(false), m_isDraggable(true), m_startPos(QPoint())
|
||||
{
|
||||
setAutoFillBackground(false);
|
||||
setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
}
|
||||
|
||||
virtual ~LtsToolButton() = default;
|
||||
virtual ~LtsToolButton() = default;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void setSameWidgetDrop(bool drop) { m_sameWidgetDrop = drop; }
|
||||
bool sameWidgetDrop() const { return m_sameWidgetDrop; }
|
||||
void setDraggable(bool isDraggable) { m_isDraggable = isDraggable; }
|
||||
void dropEvent(QDropEvent *event) override
|
||||
{
|
||||
emit newDropEvent(event);
|
||||
QToolButton::dropEvent(event);
|
||||
}
|
||||
void addMimeData(const QString &mimeType, const QByteArray &data);
|
||||
bool removeMimeData(const QString &mimeType);
|
||||
void removeAllMimeData() { m_mimeData.clear(); }
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
|
||||
protected:
|
||||
void initButton();
|
||||
void setSameWidgetDrop(bool drop)
|
||||
{
|
||||
m_sameWidgetDrop = drop;
|
||||
}
|
||||
|
||||
signals:
|
||||
void newDropEvent(QDropEvent *e);
|
||||
void dropSuc();
|
||||
bool sameWidgetDrop() const
|
||||
{
|
||||
return m_sameWidgetDrop;
|
||||
}
|
||||
|
||||
private:
|
||||
void performDrag(QMouseEvent *event);
|
||||
bool m_sameWidgetDrop;
|
||||
bool m_isDraggable;
|
||||
QPoint m_startPos;
|
||||
QMap<QString, QByteArray> m_mimeData;
|
||||
void setDraggable(bool isDraggable)
|
||||
{
|
||||
m_isDraggable = isDraggable;
|
||||
}
|
||||
|
||||
void dropEvent(QDropEvent* event) override
|
||||
{
|
||||
emit newDropEvent(event);
|
||||
QToolButton::dropEvent(event);
|
||||
}
|
||||
|
||||
void addMimeData(const QString& mimeType, const QByteArray& data);
|
||||
bool removeMimeData(const QString& mimeType);
|
||||
|
||||
void removeAllMimeData()
|
||||
{
|
||||
m_mimeData.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
void initButton();
|
||||
|
||||
signals:
|
||||
void newDropEvent(QDropEvent* e);
|
||||
void dropSuc();
|
||||
|
||||
private:
|
||||
void performDrag(QMouseEvent* event);
|
||||
bool m_sameWidgetDrop;
|
||||
bool m_isDraggable;
|
||||
QPoint m_startPos;
|
||||
QMap<QString, QByteArray> m_mimeData;
|
||||
};
|
||||
|
||||
|
||||
|
||||
LtsDragIcon::LtsDragIcon(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_lay(nullptr)
|
||||
, m_toolButton(nullptr)
|
||||
, m_icon()
|
||||
, m_dragLabel(new QLabel(this))
|
||||
, m_text()
|
||||
, m_style(ButtonStyle::eAll)
|
||||
, m_forceFixedSize(false)
|
||||
, m_isDraggable(true)
|
||||
, m_dropHandlerKey(0L)
|
||||
, m_buttonSize(ButtonSize::eDefault)
|
||||
, m_showDragIcon(true)
|
||||
LtsDragIcon::LtsDragIcon(QWidget* parent)
|
||||
: QWidget(parent), m_lay(nullptr), m_toolButton(nullptr), m_icon(), m_dragLabel(new QLabel(this)), m_text(),
|
||||
m_style(ButtonStyle::eAll), m_forceFixedSize(false), m_isDraggable(true), m_dropHandlerKey(0L),
|
||||
m_buttonSize(ButtonSize::eDefault), m_showDragIcon(true)
|
||||
{
|
||||
setAutoFillBackground(false);
|
||||
initButton();
|
||||
setAutoFillBackground(false);
|
||||
initButton();
|
||||
}
|
||||
|
||||
|
||||
void LtsDragIcon::setStyleToButton()
|
||||
{
|
||||
if (nullptr == m_toolButton) return;
|
||||
if (nullptr == m_toolButton)
|
||||
return;
|
||||
|
||||
switch (m_style)
|
||||
{
|
||||
case ButtonStyle::eIconOnly:
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
m_toolButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
setFixedSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||
} break;
|
||||
switch (m_style)
|
||||
{
|
||||
case ButtonStyle::eIconOnly: {
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
m_toolButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
setFixedSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonStyle::eTextOnly:
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
setFixedSize( QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX) );
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
layout()->setSizeConstraint( QLayout::SetDefaultConstraint );
|
||||
} break;
|
||||
case ButtonStyle::eTextOnly: {
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
setFixedSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
|
||||
layout()->setSizeConstraint(QLayout::SetDefaultConstraint);
|
||||
}
|
||||
break;
|
||||
|
||||
case ButtonStyle::eTextNextToIcon:
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
setFixedSize( QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX) );
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
layout()->setSizeConstraint( QLayout::SetDefaultConstraint );
|
||||
} break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
}
|
||||
case ButtonStyle::eTextNextToIcon: {
|
||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
|
||||
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
setFixedSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
layout()->setSizeConstraint(QLayout::SetDefaultConstraint);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LtsDragIcon::initButton()
|
||||
{
|
||||
setMinimumSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize));
|
||||
setMinimumSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize));
|
||||
|
||||
delete m_toolButton;
|
||||
delete m_lay;
|
||||
delete layout();
|
||||
delete m_toolButton;
|
||||
delete m_lay;
|
||||
delete layout();
|
||||
|
||||
m_toolButton = new LtsToolButton(this);
|
||||
m_toolButton->setDraggable(m_isDraggable);
|
||||
connect(m_toolButton, &LtsToolButton::clicked, this, &LtsDragIcon::clicked);
|
||||
connect(m_toolButton, &LtsToolButton::toggled, this, &LtsDragIcon::toggled);
|
||||
connect(m_toolButton, &LtsToolButton::newDropEvent, this, &LtsDragIcon::newDropEvent);
|
||||
connect(m_toolButton, &LtsToolButton::dropSuc, this, &LtsDragIcon::dropSuc);
|
||||
m_toolButton = new LtsToolButton(this);
|
||||
m_toolButton->setDraggable(m_isDraggable);
|
||||
connect(m_toolButton, &LtsToolButton::clicked, this, &LtsDragIcon::clicked);
|
||||
connect(m_toolButton, &LtsToolButton::toggled, this, &LtsDragIcon::toggled);
|
||||
connect(m_toolButton, &LtsToolButton::newDropEvent, this, &LtsDragIcon::newDropEvent);
|
||||
connect(m_toolButton, &LtsToolButton::dropSuc, this, &LtsDragIcon::dropSuc);
|
||||
|
||||
m_toolButton->setIcon(modifyIcon(m_icon));
|
||||
m_toolButton->setText(m_text);
|
||||
generateToolTip();
|
||||
m_toolButton->setIconSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
|
||||
m_toolButton->setIcon(modifyIcon(m_icon));
|
||||
m_toolButton->setText(m_text);
|
||||
generateToolTip();
|
||||
m_toolButton->setIconSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
|
||||
|
||||
QVBoxLayout* box = new QVBoxLayout(this);
|
||||
box->setContentsMargins(0, 0, 0, 0);
|
||||
box->setSpacing(0);
|
||||
box->addWidget(m_toolButton);
|
||||
|
||||
QVBoxLayout *box = new QVBoxLayout(this);
|
||||
box->setMargin(0);
|
||||
box->setSpacing(0);
|
||||
box->addWidget(m_toolButton);
|
||||
this->setLayout(box);
|
||||
|
||||
this->setLayout(box);
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
|
||||
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
if (m_forceFixedSize)
|
||||
{
|
||||
m_toolButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
setFixedSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
if (m_forceFixedSize)
|
||||
{
|
||||
m_toolButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
setFixedSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
||||
}
|
||||
|
||||
setStyleToButton();
|
||||
setStyleToButton();
|
||||
}
|
||||
|
||||
void LtsDragIcon::addToButtonGroup(QButtonGroup *btnGrp, int btnGrpId)
|
||||
void LtsDragIcon::addToButtonGroup(QButtonGroup* btnGrp, int btnGrpId)
|
||||
{
|
||||
btnGrp->addButton(m_toolButton, btnGrpId);
|
||||
btnGrp->addButton(m_toolButton, btnGrpId);
|
||||
}
|
||||
|
||||
|
||||
void LtsDragIcon::setIcon(const QIcon &icon)
|
||||
void LtsDragIcon::setIcon(const QIcon& icon)
|
||||
{
|
||||
m_icon = icon;
|
||||
(m_toolButton) ? m_toolButton->setIcon(modifyIcon(m_icon)) : initButton();
|
||||
m_icon = icon;
|
||||
(m_toolButton) ? m_toolButton->setIcon(modifyIcon(m_icon)) : initButton();
|
||||
}
|
||||
|
||||
|
||||
void LtsDragIcon::setMenu(QMenu *menu)
|
||||
void LtsDragIcon::setMenu(QMenu* menu)
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setMenu(menu);
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setMenu(menu);
|
||||
}
|
||||
|
||||
QMenu *LtsDragIcon::menu() const
|
||||
QMenu* LtsDragIcon::menu() const
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
return nullptr;
|
||||
if (nullptr == m_toolButton)
|
||||
return nullptr;
|
||||
|
||||
return m_toolButton->menu();
|
||||
return m_toolButton->menu();
|
||||
}
|
||||
|
||||
|
||||
void LtsDragIcon::setText(const QString &text)
|
||||
void LtsDragIcon::setText(const QString& text)
|
||||
{
|
||||
m_text = text;
|
||||
(m_toolButton) ? generateToolTip() : initButton();
|
||||
m_text = text;
|
||||
(m_toolButton) ? generateToolTip() : initButton();
|
||||
}
|
||||
|
||||
void LtsDragIcon::setContext(const QString &context)
|
||||
void LtsDragIcon::setContext(const QString& context)
|
||||
{
|
||||
m_context = context;
|
||||
generateToolTip();
|
||||
m_context = context;
|
||||
generateToolTip();
|
||||
}
|
||||
|
||||
void LtsDragIcon::generateToolTip()
|
||||
{
|
||||
if (!m_toolButton || m_text.isEmpty())
|
||||
return;
|
||||
if (!m_toolButton || m_text.isEmpty())
|
||||
return;
|
||||
|
||||
QString text(m_text);
|
||||
if (!m_context.isEmpty())
|
||||
text.prepend(m_context + QLatin1String(" - "));
|
||||
QString text(m_text);
|
||||
if (!m_context.isEmpty())
|
||||
text.prepend(m_context + QLatin1String(" - "));
|
||||
|
||||
m_toolButton->setText(m_text);
|
||||
m_toolButton->setToolTip(text);
|
||||
m_toolButton->setText(m_text);
|
||||
m_toolButton->setToolTip(text);
|
||||
}
|
||||
|
||||
bool LtsDragIcon::isCheckable()
|
||||
{
|
||||
return (m_toolButton) ? m_toolButton->isCheckable() : false;
|
||||
return (m_toolButton) ? m_toolButton->isCheckable() : false;
|
||||
}
|
||||
|
||||
void LtsDragIcon::setDraggable(bool draggable)
|
||||
{
|
||||
m_isDraggable = draggable;
|
||||
m_toolButton->setDraggable(m_isDraggable);
|
||||
m_isDraggable = draggable;
|
||||
m_toolButton->setDraggable(m_isDraggable);
|
||||
}
|
||||
|
||||
void LtsDragIcon::setCheckable(bool checkable)
|
||||
{
|
||||
m_toolButton->setCheckable(checkable);
|
||||
m_toolButton->setCheckable(checkable);
|
||||
}
|
||||
|
||||
bool LtsDragIcon::isChecked() const
|
||||
{
|
||||
return (m_toolButton) ? m_toolButton->isChecked() : false;
|
||||
return (m_toolButton) ? m_toolButton->isChecked() : false;
|
||||
}
|
||||
|
||||
void LtsDragIcon::setChecked(bool checked)
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setChecked(checked);
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setChecked(checked);
|
||||
}
|
||||
|
||||
void LtsDragIcon::setSameWidgetDrop(bool drop)
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setSameWidgetDrop(drop);
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setSameWidgetDrop(drop);
|
||||
}
|
||||
|
||||
bool LtsDragIcon::sameWidgetDrop() const
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
return false;
|
||||
return m_toolButton->sameWidgetDrop();
|
||||
if (nullptr == m_toolButton)
|
||||
return false;
|
||||
return m_toolButton->sameWidgetDrop();
|
||||
}
|
||||
|
||||
void LtsDragIcon::addMimeData(const QString &mimeType, const QByteArray &data)
|
||||
void LtsDragIcon::addMimeData(const QString& mimeType, const QByteArray& data)
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->addMimeData(mimeType, data);
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->addMimeData(mimeType, data);
|
||||
}
|
||||
|
||||
bool LtsDragIcon::removeMimeData(const QString &mimeType)
|
||||
bool LtsDragIcon::removeMimeData(const QString& mimeType)
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
return m_toolButton->removeMimeData(mimeType);
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
return m_toolButton->removeMimeData(mimeType);
|
||||
}
|
||||
|
||||
void LtsDragIcon::removeAllMimeData()
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->removeAllMimeData();
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->removeAllMimeData();
|
||||
}
|
||||
|
||||
void LtsDragIcon::setAcceptDrops(bool on)
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setAcceptDrops(on);
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setAcceptDrops(on);
|
||||
}
|
||||
|
||||
void LtsDragIcon::dragEnterEvent(QDragEnterEvent *e)
|
||||
void LtsDragIcon::dragEnterEvent(QDragEnterEvent* e)
|
||||
{
|
||||
if (m_toolButton)
|
||||
m_toolButton->dragEnterEvent(e);
|
||||
if (m_toolButton)
|
||||
m_toolButton->dragEnterEvent(e);
|
||||
}
|
||||
void LtsDragIcon::dropEvent(QDropEvent *e)
|
||||
|
||||
void LtsDragIcon::dropEvent(QDropEvent* e)
|
||||
{
|
||||
QWidget::dropEvent(e);
|
||||
QWidget::dropEvent(e);
|
||||
}
|
||||
|
||||
void LtsDragIcon::setButtonStyle(ButtonStyle style)
|
||||
{
|
||||
m_style = style;
|
||||
setStyleToButton();
|
||||
m_style = style;
|
||||
setStyleToButton();
|
||||
}
|
||||
|
||||
void LtsDragIcon::setIconSize(ButtonSize buttonSize)
|
||||
{
|
||||
m_buttonSize = buttonSize;
|
||||
(m_toolButton) ? m_toolButton->setIconSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize))) : initButton();
|
||||
m_buttonSize = buttonSize;
|
||||
(m_toolButton) ? m_toolButton->setIconSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)))
|
||||
: initButton();
|
||||
}
|
||||
|
||||
void LtsDragIcon::setForceFixedSize(bool force)
|
||||
{
|
||||
m_forceFixedSize = force;
|
||||
initButton();
|
||||
m_forceFixedSize = force;
|
||||
initButton();
|
||||
}
|
||||
|
||||
void LtsDragIcon::setButtonVisible(bool visible)
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setVisible(visible);
|
||||
if (nullptr == m_toolButton)
|
||||
initButton();
|
||||
m_toolButton->setVisible(visible);
|
||||
}
|
||||
|
||||
bool LtsDragIcon::buttonVisible() const
|
||||
{
|
||||
if (nullptr == m_toolButton)
|
||||
return false;
|
||||
return m_toolButton->isVisible();
|
||||
if (nullptr == m_toolButton)
|
||||
return false;
|
||||
return m_toolButton->isVisible();
|
||||
}
|
||||
|
||||
void LtsDragIcon::setAction(QAction *action)
|
||||
void LtsDragIcon::setAction(QAction* action)
|
||||
{
|
||||
QIcon icon = action->icon();
|
||||
if(!icon.isNull())
|
||||
m_icon = icon;
|
||||
m_toolButton->setDefaultAction(action);
|
||||
this->setObjectName(action->objectName());
|
||||
QIcon icon = action->icon();
|
||||
if (!icon.isNull())
|
||||
m_icon = icon;
|
||||
m_toolButton->setDefaultAction(action);
|
||||
this->setObjectName(action->objectName());
|
||||
}
|
||||
|
||||
void LtsDragIcon::changeEvent(QEvent *event)
|
||||
void LtsDragIcon::changeEvent(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::EnabledChange)
|
||||
emit enabledChanged(isEnabled());
|
||||
if (event->type() == QEvent::EnabledChange)
|
||||
emit enabledChanged(isEnabled());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LtsToolButton::mousePressEvent(QMouseEvent *event)
|
||||
void LtsToolButton::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
m_startPos = event->pos();
|
||||
QToolButton::mousePressEvent(event);
|
||||
if (event->button() == Qt::LeftButton)
|
||||
m_startPos = event->pos();
|
||||
QToolButton::mousePressEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void LtsToolButton::mouseReleaseEvent(QMouseEvent *event)
|
||||
void LtsToolButton::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
QToolButton::mouseReleaseEvent(event);
|
||||
QToolButton::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void LtsToolButton::mouseMoveEvent(QMouseEvent *event)
|
||||
void LtsToolButton::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
if (!m_isDraggable)
|
||||
return;
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
int distance = (event->pos() - m_startPos).manhattanLength();
|
||||
if (distance >= 5)
|
||||
if (!m_isDraggable)
|
||||
return;
|
||||
if (event->buttons() & Qt::LeftButton)
|
||||
{
|
||||
this->setDown(false);
|
||||
performDrag(event);
|
||||
return;
|
||||
int distance = (event->pos() - m_startPos).manhattanLength();
|
||||
if (distance >= 5)
|
||||
{
|
||||
this->setDown(false);
|
||||
performDrag(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
QToolButton::mouseMoveEvent(event);
|
||||
QToolButton::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void LtsToolButton::performDrag(QMouseEvent *)
|
||||
void LtsToolButton::performDrag(QMouseEvent*)
|
||||
{
|
||||
QWidget *item = this;
|
||||
if (item)
|
||||
{
|
||||
|
||||
LtsDragIcon *dragIcon = nullptr;
|
||||
QString name;
|
||||
|
||||
while (dragIcon == nullptr)
|
||||
QWidget* item = this;
|
||||
if (item)
|
||||
{
|
||||
if ((!item->objectName().isEmpty()) && (name.isNull()))
|
||||
{
|
||||
name = item->objectName();
|
||||
}
|
||||
item = item->parentWidget();
|
||||
if (nullptr == item) return;
|
||||
dragIcon = dynamic_cast<LtsDragIcon*>(item);
|
||||
|
||||
LtsDragIcon* dragIcon = nullptr;
|
||||
QString name;
|
||||
|
||||
while (dragIcon == nullptr)
|
||||
{
|
||||
if ((!item->objectName().isEmpty()) && (name.isNull()))
|
||||
{
|
||||
name = item->objectName();
|
||||
}
|
||||
item = item->parentWidget();
|
||||
if (nullptr == item)
|
||||
return;
|
||||
dragIcon = dynamic_cast<LtsDragIcon*>(item);
|
||||
}
|
||||
QMimeData* mimeData = new QMimeData();
|
||||
mimeData->setText(name);
|
||||
for (auto it = m_mimeData.cbegin(); it != m_mimeData.cend(); ++it)
|
||||
mimeData->setData(it.key(), it.value());
|
||||
|
||||
if (dragIcon->dropHandlerKey() != 0L)
|
||||
{
|
||||
QByteArray data = QByteArray(QByteArray::number(dragIcon->dropHandlerKey()));
|
||||
mimeData->setData(QLatin1String("DropHandlerPtr"), data);
|
||||
}
|
||||
|
||||
QDrag* drag = new QDrag(item);
|
||||
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
QAction* action = defaultAction();
|
||||
|
||||
if ((action) && (dragIcon->showDragIcon()))
|
||||
{
|
||||
drag->setPixmap(action->icon().pixmap(16, 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
drag->setPixmap(dragIcon->icon().pixmap(16, 16));
|
||||
}
|
||||
Qt::DropAction drop = drag->exec(Qt::CopyAction | Qt::MoveAction);
|
||||
if (drop == Qt::MoveAction || drop == Qt::CopyAction)
|
||||
emit dropSuc();
|
||||
}
|
||||
QMimeData *mimeData = new QMimeData();
|
||||
mimeData->setText(name);
|
||||
for(auto it = m_mimeData.cbegin(); it != m_mimeData.cend(); ++it)
|
||||
mimeData->setData(it.key(), it.value());
|
||||
|
||||
|
||||
if (dragIcon->dropHandlerKey() != 0L)
|
||||
{
|
||||
QByteArray data = QByteArray(QByteArray::number(dragIcon->dropHandlerKey()));
|
||||
mimeData->setData(QLatin1String("DropHandlerPtr"),data);
|
||||
}
|
||||
|
||||
QDrag *drag = new QDrag(item);
|
||||
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
QAction *action = defaultAction();
|
||||
|
||||
if ((action) && (dragIcon->showDragIcon()))
|
||||
{
|
||||
drag->setPixmap(action->icon().pixmap(16,16) );
|
||||
}
|
||||
else
|
||||
{
|
||||
drag->setPixmap(dragIcon->icon().pixmap(16, 16));
|
||||
}
|
||||
Qt::DropAction drop = drag->exec(Qt::CopyAction | Qt::MoveAction);
|
||||
if (drop == Qt::MoveAction || drop == Qt::CopyAction )
|
||||
emit dropSuc();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LtsToolButton::dragEnterEvent(QDragEnterEvent *event)
|
||||
void LtsToolButton::dragEnterEvent(QDragEnterEvent* event)
|
||||
{
|
||||
QWidget *source =
|
||||
qobject_cast<QWidget *>(event->source());
|
||||
if (source && source != this) {
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
}
|
||||
QWidget::dragEnterEvent(event);
|
||||
QWidget* source = qobject_cast<QWidget*>(event->source());
|
||||
if (source && source != this)
|
||||
{
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
}
|
||||
QWidget::dragEnterEvent(event);
|
||||
}
|
||||
|
||||
void LtsToolButton::addMimeData(const QString &mimeType, const QByteArray &data)
|
||||
void LtsToolButton::addMimeData(const QString& mimeType, const QByteArray& data)
|
||||
{
|
||||
m_mimeData.insert(mimeType,data);
|
||||
m_mimeData.insert(mimeType, data);
|
||||
}
|
||||
|
||||
bool LtsToolButton::removeMimeData(const QString &mimeType)
|
||||
bool LtsToolButton::removeMimeData(const QString& mimeType)
|
||||
{
|
||||
return (m_mimeData.remove(mimeType) > 0);
|
||||
return (m_mimeData.remove(mimeType) > 0);
|
||||
}
|
||||
|
||||
#define SIZE 40
|
||||
|
||||
QIcon LtsDragIcon::modifyIcon(const QIcon &icon)
|
||||
QIcon LtsDragIcon::modifyIcon(const QIcon& icon)
|
||||
{
|
||||
if (m_modification.isEmpty())
|
||||
return icon;
|
||||
if (m_modification.isEmpty())
|
||||
return icon;
|
||||
|
||||
QPixmap iconImage(icon.pixmap(SIZE*0.8, SIZE*0.8));
|
||||
QPainter painter(&iconImage);
|
||||
QPixmap iconImage(icon.pixmap(SIZE * 0.8, SIZE * 0.8));
|
||||
QPainter painter(&iconImage);
|
||||
|
||||
painter.save();
|
||||
painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter.setBrush(QColor("red"));
|
||||
painter.setPen(QPen(QColor("red"), 3));
|
||||
painter.save();
|
||||
painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter.setBrush(QColor("red"));
|
||||
painter.setPen(QPen(QColor("red"), 3));
|
||||
|
||||
QFont f;
|
||||
f.setFamily(QStringLiteral("Monospace"));
|
||||
f.setPointSize(12);
|
||||
f.setBold(true);
|
||||
painter.setFont(f);
|
||||
QFont f;
|
||||
f.setFamily(QStringLiteral("Monospace"));
|
||||
f.setPointSize(12);
|
||||
f.setBold(true);
|
||||
painter.setFont(f);
|
||||
|
||||
painter.drawText(QRect(0, 0, 28, 28), m_modification);
|
||||
painter.restore();
|
||||
painter.drawText(QRect(0, 0, 28, 28), m_modification);
|
||||
painter.restore();
|
||||
|
||||
return iconImage;
|
||||
return iconImage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace LtsWidgets
|
||||
|
||||
#include "lts_drag_icon.moc"
|
||||
|
||||
Executable → Regular
+76
-103
@@ -1,153 +1,126 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_frameless_dialog.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QRect>
|
||||
#include <QStyle>
|
||||
#include <QSize>
|
||||
#include <QScreen>
|
||||
#include <QScroller>
|
||||
#include <QScrollArea>
|
||||
#include <QDesktopWidget>
|
||||
#include <QScroller>
|
||||
#include <QShowEvent>
|
||||
#include <QSize>
|
||||
#include <QStyle>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
LtsFramelessDialog::LtsFramelessDialog(QWidget *parent, const Behaviour &behaviour)
|
||||
: QDialog(parent)
|
||||
LtsFramelessDialog::LtsFramelessDialog(QWidget* parent, const Behaviour& behaviour) : QDialog(parent)
|
||||
{
|
||||
|
||||
|
||||
Qt::WindowFlags wf;
|
||||
|
||||
|
||||
switch (behaviour)
|
||||
{
|
||||
case Behaviour::Modal:
|
||||
Qt::WindowFlags wf;
|
||||
|
||||
switch (behaviour)
|
||||
{
|
||||
case Behaviour::Modal: {
|
||||
|
||||
#ifndef TABLET_MODE
|
||||
setModal(true);
|
||||
wf |= Qt::Dialog;
|
||||
setModal(true);
|
||||
wf |= Qt::Dialog;
|
||||
#else
|
||||
wf |= Qt::Window;
|
||||
wf |= Qt::Window;
|
||||
#endif
|
||||
wf |= Qt::WindowStaysOnTopHint;
|
||||
break;
|
||||
wf |= Qt::WindowStaysOnTopHint;
|
||||
break;
|
||||
}
|
||||
|
||||
case Behaviour::Popup:
|
||||
wf |= Qt::Popup;
|
||||
break;
|
||||
}
|
||||
|
||||
case Behaviour::Popup:
|
||||
wf |= Qt::Popup;
|
||||
break;
|
||||
}
|
||||
setWindowFlags(wf);
|
||||
|
||||
setWindowFlags(wf);
|
||||
|
||||
|
||||
QTimer *t = new QTimer(this);
|
||||
t->setInterval(250);
|
||||
connect(t, &QTimer::timeout,
|
||||
this, [this]()
|
||||
{
|
||||
|
||||
|
||||
|
||||
QSize s = size();
|
||||
setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, s, screenRectFromPoint(QCursor::pos())));
|
||||
});
|
||||
|
||||
QTimer* t = new QTimer(this);
|
||||
t->setInterval(250);
|
||||
connect(t, &QTimer::timeout, this, [this]() {
|
||||
QSize s = size();
|
||||
setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, s, screenRectFromPoint(QCursor::pos())));
|
||||
});
|
||||
}
|
||||
|
||||
LtsFramelessDialog::~LtsFramelessDialog() {}
|
||||
|
||||
LtsFramelessDialog::~LtsFramelessDialog()
|
||||
QRect LtsFramelessDialog::screenRectFromPoint(const QPoint& pos) const
|
||||
{
|
||||
const auto screens = QGuiApplication::screens();
|
||||
for (QScreen* screen : screens)
|
||||
{
|
||||
QRect s = screen->geometry().adjusted(-50, -50, 50, 50);
|
||||
|
||||
bool contains = s.contains(pos);
|
||||
|
||||
if (contains)
|
||||
return screen->geometry();
|
||||
}
|
||||
|
||||
return QRect();
|
||||
}
|
||||
|
||||
|
||||
QRect LtsFramelessDialog::screenRectFromPoint(const QPoint &pos) const
|
||||
void LtsFramelessDialog::showEvent(QShowEvent* event)
|
||||
{
|
||||
const auto screens = QGuiApplication::screens();
|
||||
for (QScreen *screen : screens)
|
||||
{
|
||||
QRect s = screen->geometry().adjusted(-50, -50, 50, 50);
|
||||
|
||||
bool contains = s.contains(pos);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (contains)
|
||||
return screen->geometry();
|
||||
}
|
||||
|
||||
return QRect();
|
||||
}
|
||||
|
||||
|
||||
void LtsFramelessDialog::showEvent(QShowEvent *event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
QTimer::singleShot(0, this, &LtsFramelessDialog::onUpdateGeometry);
|
||||
|
||||
QDialog::showEvent(event);
|
||||
QTimer::singleShot(0, this, &LtsFramelessDialog::onUpdateGeometry);
|
||||
|
||||
#ifdef TABLET_MODE
|
||||
QList<QWidget *> scrollWidgets = findChildren<QWidget *>();
|
||||
QList<QWidget*> scrollWidgets = findChildren<QWidget*>();
|
||||
|
||||
for (auto i = scrollWidgets.begin(); i != scrollWidgets.end(); ++i)
|
||||
{
|
||||
QWidget *widget = *i;
|
||||
for (auto i = scrollWidgets.begin(); i != scrollWidgets.end(); ++i)
|
||||
{
|
||||
QWidget* widget = *i;
|
||||
|
||||
QVariant isConst = widget->property("const");
|
||||
if (isConst.isValid() && isConst.toBool())
|
||||
continue;
|
||||
QVariant isConst = widget->property("const");
|
||||
if (isConst.isValid() && isConst.toBool())
|
||||
continue;
|
||||
|
||||
addTouchScroll(widget);
|
||||
}
|
||||
addTouchScroll(widget);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void LtsFramelessDialog::addTouchScroll(QWidget *widget)
|
||||
void LtsFramelessDialog::addTouchScroll(QWidget* widget)
|
||||
{
|
||||
if (!widget)
|
||||
return;
|
||||
widget->setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
if (!widget)
|
||||
return;
|
||||
widget->setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
|
||||
QScrollArea *sca = qobject_cast<QScrollArea *>(widget);
|
||||
if (sca)
|
||||
{
|
||||
QScroller::grabGesture(sca->viewport(), QScroller::LeftMouseButtonGesture);
|
||||
return;
|
||||
}
|
||||
QScrollArea* sca = qobject_cast<QScrollArea*>(widget);
|
||||
if (sca)
|
||||
{
|
||||
QScroller::grabGesture(sca->viewport(), QScroller::LeftMouseButtonGesture);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LtsFramelessDialog::onUpdateGeometry()
|
||||
{
|
||||
QRect r;
|
||||
QWidget *p = parentWidget();
|
||||
QRect r;
|
||||
QWidget* p = parentWidget();
|
||||
|
||||
if (p)
|
||||
{
|
||||
QWidget *window = p->window();
|
||||
QPoint global = window->mapToGlobal(QPoint(0,0));
|
||||
QSize size = window->size();
|
||||
if (p)
|
||||
{
|
||||
QWidget* window = p->window();
|
||||
QPoint global = window->mapToGlobal(QPoint(0, 0));
|
||||
QSize size = window->size();
|
||||
|
||||
r = QRect(global, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = QGuiApplication::primaryScreen()->geometry();
|
||||
}
|
||||
r = QRect(global, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = QGuiApplication::primaryScreen()->geometry();
|
||||
}
|
||||
|
||||
QSize s = size();
|
||||
setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, s, r));
|
||||
QSize s = size();
|
||||
setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, s, r));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+79
-86
@@ -1,129 +1,122 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_grid_layout.h"
|
||||
#include <utility>
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <utility>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
LtsGridLayout::LtsGridLayout(LtsWidgets::ButtonSize buttonSize, QWidget *parent, int maxColumn)
|
||||
: QGridLayout(parent)
|
||||
, m_buttonSize(buttonSize)
|
||||
, m_defaultMaxColumn(maxColumn)
|
||||
, m_maxColumn(maxColumn)
|
||||
, m_colSize(0)
|
||||
, m_autoSize(maxColumn < 0)
|
||||
LtsGridLayout::LtsGridLayout(LtsWidgets::ButtonSize buttonSize, QWidget* parent, int maxColumn)
|
||||
: QGridLayout(parent), m_buttonSize(buttonSize), m_defaultMaxColumn(maxColumn), m_maxColumn(maxColumn),
|
||||
m_colSize(0), m_autoSize(maxColumn < 0)
|
||||
{
|
||||
setSizeConstraint(SizeConstraint::SetNoConstraint);
|
||||
|
||||
setVerticalSpacing(1);
|
||||
setMargin(0);
|
||||
setSizeConstraint(SizeConstraint::SetNoConstraint);
|
||||
|
||||
setVerticalSpacing(1);
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void LtsGridLayout::add_widget(QWidget *widget)
|
||||
void LtsGridLayout::add_widget(QWidget* widget)
|
||||
{
|
||||
for (auto it = m_widgetList.cbegin(); it != m_widgetList.cend(); ++it)
|
||||
{
|
||||
if (*it == widget)
|
||||
return;
|
||||
}
|
||||
connect(widget, &QWidget::destroyed, this, &LtsGridLayout::onWidgetDestroyed);
|
||||
addWidgetInternal(widget);
|
||||
m_widgetList.push_back(widget);
|
||||
for (auto it = m_widgetList.cbegin(); it != m_widgetList.cend(); ++it)
|
||||
{
|
||||
if (*it == widget)
|
||||
return;
|
||||
}
|
||||
connect(widget, &QWidget::destroyed, this, &LtsGridLayout::onWidgetDestroyed);
|
||||
addWidgetInternal(widget);
|
||||
m_widgetList.push_back(widget);
|
||||
}
|
||||
|
||||
void LtsGridLayout::setAutoSize(bool enable)
|
||||
{
|
||||
m_autoSize = enable;
|
||||
if (m_autoSize == false)
|
||||
setMaxColumn(1);
|
||||
else
|
||||
{
|
||||
m_maxColumn = -1;
|
||||
m_oldSize = QSize();
|
||||
m_oldGeo = QRect();
|
||||
QResizeEvent e(sizeHint(), sizeHint());
|
||||
onParentResize(&e);
|
||||
setGeometry(QRect(0, 0, sizeHint().width(), sizeHint().height()));
|
||||
}
|
||||
m_autoSize = enable;
|
||||
if (m_autoSize == false)
|
||||
setMaxColumn(1);
|
||||
else
|
||||
{
|
||||
m_maxColumn = -1;
|
||||
m_oldSize = QSize();
|
||||
m_oldGeo = QRect();
|
||||
QResizeEvent e(sizeHint(), sizeHint());
|
||||
onParentResize(&e);
|
||||
setGeometry(QRect(0, 0, sizeHint().width(), sizeHint().height()));
|
||||
}
|
||||
}
|
||||
|
||||
void LtsGridLayout::setMaxColumn(int max)
|
||||
{
|
||||
m_maxColumn = max;
|
||||
m_defaultMaxColumn = max;
|
||||
m_maxColumn = max;
|
||||
m_defaultMaxColumn = max;
|
||||
|
||||
|
||||
m_colSize = 0;
|
||||
m_colSize = 0;
|
||||
|
||||
for (QWidget *wid : std::as_const(m_widgetList))
|
||||
removeWidget(wid);
|
||||
|
||||
for (QWidget *wid : std::as_const(m_widgetList))
|
||||
addWidgetInternal(wid);
|
||||
for (QWidget* wid : std::as_const(m_widgetList))
|
||||
removeWidget(wid);
|
||||
|
||||
for (QWidget* wid : std::as_const(m_widgetList))
|
||||
addWidgetInternal(wid);
|
||||
}
|
||||
|
||||
void LtsGridLayout::addWidgetInternal(QWidget *widget)
|
||||
void LtsGridLayout::addWidgetInternal(QWidget* widget)
|
||||
{
|
||||
int current_row = 0;
|
||||
int current_column = 0;
|
||||
int current_row = 0;
|
||||
int current_column = 0;
|
||||
|
||||
while (QLayoutItem *item = itemAtPosition(current_row, current_column))
|
||||
{
|
||||
if (!item->widget())
|
||||
while (QLayoutItem* item = itemAtPosition(current_row, current_column))
|
||||
{
|
||||
removeItem(item);
|
||||
continue;
|
||||
if (!item->widget())
|
||||
{
|
||||
removeItem(item);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_column == (m_maxColumn - 1))
|
||||
{
|
||||
current_column = 0;
|
||||
++current_row;
|
||||
}
|
||||
else
|
||||
++current_column;
|
||||
}
|
||||
|
||||
if (current_column == (m_maxColumn - 1))
|
||||
{
|
||||
current_column = 0;
|
||||
++current_row;
|
||||
}
|
||||
else
|
||||
++current_column;
|
||||
}
|
||||
if (current_row == 0)
|
||||
m_colSize += 1;
|
||||
|
||||
if (current_row == 0)
|
||||
m_colSize += 1;
|
||||
|
||||
QGridLayout::addWidget(widget, current_row, current_column);
|
||||
QGridLayout::addWidget(widget, current_row, current_column);
|
||||
}
|
||||
|
||||
|
||||
void LtsGridLayout::onParentResize(QResizeEvent *e)
|
||||
void LtsGridLayout::onParentResize(QResizeEvent* e)
|
||||
{
|
||||
if (m_autoSize && m_oldSize != e->size())
|
||||
{
|
||||
bool bigger = (e->size().width() > m_oldSize.width());
|
||||
m_oldSize = e->size();
|
||||
int newWidth = m_oldSize.width();
|
||||
int maxIconsInRow = newWidth / (static_cast<int>(m_buttonSize) + 4);
|
||||
if (m_autoSize && m_oldSize != e->size())
|
||||
{
|
||||
bool bigger = (e->size().width() > m_oldSize.width());
|
||||
m_oldSize = e->size();
|
||||
int newWidth = m_oldSize.width();
|
||||
int maxIconsInRow = newWidth / (static_cast<int>(m_buttonSize) + 4);
|
||||
|
||||
if (!bigger && newWidth <= (static_cast<int>(m_buttonSize)*m_colSize - static_cast<int>(m_buttonSize) / 2))
|
||||
maxIconsInRow--;
|
||||
if (m_maxColumn != maxIconsInRow)
|
||||
setMaxColumn(maxIconsInRow);
|
||||
}
|
||||
if (!bigger && newWidth <= (static_cast<int>(m_buttonSize) * m_colSize - static_cast<int>(m_buttonSize) / 2))
|
||||
maxIconsInRow--;
|
||||
if (m_maxColumn != maxIconsInRow)
|
||||
setMaxColumn(maxIconsInRow);
|
||||
}
|
||||
}
|
||||
|
||||
void LtsGridLayout::onWidgetDestroyed()
|
||||
{
|
||||
QWidget *s = qobject_cast<QWidget*>(sender());
|
||||
for (auto it = m_widgetList.begin(); it != m_widgetList.end(); ++it)
|
||||
{
|
||||
if (*it == s)
|
||||
QWidget* s = qobject_cast<QWidget*>(sender());
|
||||
for (auto it = m_widgetList.begin(); it != m_widgetList.end(); ++it)
|
||||
{
|
||||
QGridLayout::removeWidget(s);
|
||||
m_widgetList.erase(it);
|
||||
setMaxColumn(m_maxColumn);
|
||||
break;
|
||||
if (*it == s)
|
||||
{
|
||||
QGridLayout::removeWidget(s);
|
||||
m_widgetList.erase(it);
|
||||
setMaxColumn(m_maxColumn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+484
-522
File diff suppressed because it is too large.
Load diff
Executable → Regular
+69
-84
@@ -1,116 +1,101 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_image_editor.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPaintEvent>
|
||||
#include <QBrush>
|
||||
#include <QEvent>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QRect>
|
||||
#include <QEvent>
|
||||
|
||||
using namespace LtsWidgets;
|
||||
|
||||
|
||||
LtsImageEditor::LtsImageEditor(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_isHovered(false)
|
||||
, m_menuEnabled(true)
|
||||
, m_bDrawOuterRect(true)
|
||||
{}
|
||||
|
||||
|
||||
void LtsImageEditor::setPixmap(const QPixmap &pixmap)
|
||||
LtsImageEditor::LtsImageEditor(QWidget* parent)
|
||||
: QWidget(parent), m_isHovered(false), m_menuEnabled(true), m_bDrawOuterRect(true)
|
||||
{
|
||||
if (pixmap.isNull())
|
||||
m_pixmap = QPixmap(QStringLiteral(":style/noimage.png"));
|
||||
else
|
||||
m_pixmap = pixmap;
|
||||
|
||||
update();
|
||||
emit imageChanged();
|
||||
}
|
||||
|
||||
|
||||
void LtsImageEditor::enterEvent(QEvent *)
|
||||
void LtsImageEditor::setPixmap(const QPixmap& pixmap)
|
||||
{
|
||||
|
||||
m_isHovered = true;
|
||||
update();
|
||||
}
|
||||
if (pixmap.isNull())
|
||||
m_pixmap = QPixmap(QStringLiteral(":style/noimage.png"));
|
||||
else
|
||||
m_pixmap = pixmap;
|
||||
|
||||
|
||||
void LtsImageEditor::leaveEvent(QEvent *)
|
||||
{
|
||||
|
||||
m_isHovered = false;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
bool LtsImageEditor::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress && m_menuEnabled)
|
||||
{
|
||||
emit signalClicked();
|
||||
event->accept();
|
||||
m_isHovered = false;
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
emit imageChanged();
|
||||
}
|
||||
|
||||
|
||||
void LtsImageEditor::paintEvent(QPaintEvent* event)
|
||||
void LtsImageEditor::enterEvent(QEnterEvent*)
|
||||
{
|
||||
QPainter p(this);
|
||||
|
||||
|
||||
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
QBrush brush = QColor(QStringLiteral("white"));
|
||||
m_isHovered = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void LtsImageEditor::leaveEvent(QEvent*)
|
||||
{
|
||||
|
||||
if (!m_pixmap.isNull())
|
||||
{
|
||||
if (!(m_isHovered && m_menuEnabled))
|
||||
m_isHovered = false;
|
||||
update();
|
||||
}
|
||||
|
||||
bool LtsImageEditor::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress && m_menuEnabled)
|
||||
{
|
||||
const QSize s(size());
|
||||
const QPixmap pixmap(m_pixmap.scaled(s, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
const int x = qRound((s.width() - pixmap.width()) / 2.);
|
||||
const int y = qRound((s.height() - pixmap.height()) / 2.);
|
||||
if (m_bDrawOuterRect)
|
||||
{
|
||||
p.setPen(QPen(QColor("gray"), 2));
|
||||
p.drawRect(rect());
|
||||
}
|
||||
p.drawPixmap(x, y, pixmap);
|
||||
event->accept();
|
||||
return;
|
||||
emit signalClicked();
|
||||
event->accept();
|
||||
m_isHovered = false;
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
|
||||
p.setPen(QPen(QColor("gray"), 2));
|
||||
p.setBrush(brush);
|
||||
p.drawRect(rect());
|
||||
void LtsImageEditor::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QPainter p(this);
|
||||
|
||||
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
QBrush brush = QColor(QStringLiteral("white"));
|
||||
|
||||
|
||||
if (m_isHovered && m_menuEnabled)
|
||||
{
|
||||
p.setPen(QPen(QColor(QStringLiteral("gray")), (size().height() / 48 * 2)));
|
||||
if (!m_pixmap.isNull())
|
||||
{
|
||||
if (!(m_isHovered && m_menuEnabled))
|
||||
{
|
||||
const QSize s(size());
|
||||
const QPixmap pixmap(m_pixmap.scaled(s, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
const int x = qRound((s.width() - pixmap.width()) / 2.);
|
||||
const int y = qRound((s.height() - pixmap.height()) / 2.);
|
||||
if (m_bDrawOuterRect)
|
||||
{
|
||||
p.setPen(QPen(QColor("gray"), 2));
|
||||
p.drawRect(rect());
|
||||
}
|
||||
p.drawPixmap(x, y, pixmap);
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double xc = size().width()/2.012;
|
||||
double yc = size().height()/2.012;
|
||||
p.setPen(QPen(QColor("gray"), 2));
|
||||
p.setBrush(brush);
|
||||
p.drawRect(rect());
|
||||
|
||||
p.drawLine(QPointF(xc - (xc/2.01f), yc - (yc/3.01f)), QPointF(xc + (xc/2.02f), yc - (yc/3.02f)));
|
||||
p.drawLine(QPointF(xc - (xc/2.01f), yc - 0.01f), QPointF(xc + (xc/2.02f), yc - 0));
|
||||
p.drawLine(QPointF(xc - (xc/2.01f), yc + (yc/3.01f)), QPointF(xc + (xc/2.02f), yc + (yc/3.02f)));
|
||||
}
|
||||
if (m_isHovered && m_menuEnabled)
|
||||
{
|
||||
p.setPen(QPen(QColor(QStringLiteral("gray")), (size().height() / 48 * 2)));
|
||||
|
||||
double xc = size().width() / 2.012;
|
||||
double yc = size().height() / 2.012;
|
||||
|
||||
p.drawLine(QPointF(xc - (xc / 2.01f), yc - (yc / 3.01f)), QPointF(xc + (xc / 2.02f), yc - (yc / 3.02f)));
|
||||
p.drawLine(QPointF(xc - (xc / 2.01f), yc - 0.01f), QPointF(xc + (xc / 2.02f), yc - 0));
|
||||
p.drawLine(QPointF(xc - (xc / 2.01f), yc + (yc / 3.01f)), QPointF(xc + (xc / 2.02f), yc + (yc / 3.02f)));
|
||||
}
|
||||
|
||||
event->accept();
|
||||
event->accept();
|
||||
}
|
||||
Executable → Regular
+41
-34
@@ -1,61 +1,68 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include "ltswidgets_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
class LTSWIDGETS_EXPORT LtsImageEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
|
||||
Q_PROPERTY(bool menuEnabled READ isMenuEnabled WRITE setMenuEnabled)
|
||||
Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
|
||||
Q_PROPERTY(bool menuEnabled READ isMenuEnabled WRITE setMenuEnabled)
|
||||
|
||||
public:
|
||||
explicit LtsImageEditor(QWidget *parent = nullptr);
|
||||
public:
|
||||
explicit LtsImageEditor(QWidget* parent = nullptr);
|
||||
|
||||
|
||||
void setPixmap(const QPixmap& pixmap);
|
||||
|
||||
void setPixmap(const QPixmap &pixmap);
|
||||
QPixmap pixmap() const
|
||||
{
|
||||
return m_pixmap;
|
||||
}
|
||||
|
||||
|
||||
void setMenuEnabled(bool enabled = true)
|
||||
{
|
||||
m_menuEnabled = enabled;
|
||||
}
|
||||
|
||||
QPixmap pixmap() const { return m_pixmap; }
|
||||
bool isMenuEnabled() const
|
||||
{
|
||||
return m_menuEnabled;
|
||||
}
|
||||
|
||||
|
||||
void setDrawOuterRect(bool bDraw)
|
||||
{
|
||||
m_bDrawOuterRect = bDraw;
|
||||
}
|
||||
|
||||
void setMenuEnabled(bool enabled = true) { m_menuEnabled = enabled; }
|
||||
bool isMenuEnabled() const { return m_menuEnabled; }
|
||||
bool drawOuterRect() const
|
||||
{
|
||||
return m_bDrawOuterRect;
|
||||
}
|
||||
|
||||
void setDrawOuterRect(bool bDraw) { m_bDrawOuterRect = bDraw; }
|
||||
bool drawOuterRect() const { return m_bDrawOuterRect; }
|
||||
protected:
|
||||
void paintEvent(QPaintEvent* event);
|
||||
void enterEvent(QEnterEvent*);
|
||||
void leaveEvent(QEvent*);
|
||||
bool event(QEvent* event);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void enterEvent(QEvent *);
|
||||
void leaveEvent(QEvent *);
|
||||
bool event(QEvent *event);
|
||||
private:
|
||||
QPixmap m_pixmap;
|
||||
bool m_isHovered;
|
||||
bool m_menuEnabled;
|
||||
bool m_bDrawOuterRect;
|
||||
|
||||
private:
|
||||
QPixmap m_pixmap;
|
||||
bool m_isHovered;
|
||||
bool m_menuEnabled;
|
||||
bool m_bDrawOuterRect;
|
||||
signals:
|
||||
|
||||
signals:
|
||||
|
||||
void signalClicked();
|
||||
|
||||
void signalClicked();
|
||||
|
||||
void imageChanged();
|
||||
void imageChanged();
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+79
-86
@@ -1,133 +1,126 @@
|
||||
#include "lts_message_dialog.h"
|
||||
|
||||
#include "lts_message_dialog_helper.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDebug>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QDebug>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
namespace LtsMessageDialog
|
||||
{
|
||||
Button showMessage(QWidget* parent,
|
||||
const QString& message,
|
||||
const QString &title,
|
||||
const Behaviour behaviour,
|
||||
const Buttons buttons,
|
||||
const QHash<Button, QString> &buttonTexts)
|
||||
Button showMessage(QWidget* parent, const QString& message, const QString& title, const Behaviour behaviour,
|
||||
const Buttons buttons, const QHash<Button, QString>& buttonTexts)
|
||||
{
|
||||
static QAtomicInt s_used = 0;
|
||||
static QAtomicInt s_used = 0;
|
||||
|
||||
if (s_used)
|
||||
qDebug() << "LtsMessageDialog: showMessage called while showMessage is in its Event Loop - do not open more than one Dialog at once !!";
|
||||
if (s_used)
|
||||
qDebug() << "LtsMessageDialog: showMessage called while showMessage is in its Event Loop - do not open more "
|
||||
"than one Dialog at once !!";
|
||||
|
||||
s_used = 1;
|
||||
s_used = 1;
|
||||
|
||||
LtsMessageDialogHelper *dialog = new LtsMessageDialogHelper();
|
||||
Button result = dialog->showMessage(parent, message, title, behaviour, buttons, buttonTexts);
|
||||
dialog->deleteLater();
|
||||
LtsMessageDialogHelper* dialog = new LtsMessageDialogHelper();
|
||||
Button result = dialog->showMessage(parent, message, title, behaviour, buttons, buttonTexts);
|
||||
dialog->deleteLater();
|
||||
|
||||
s_used = 0;
|
||||
s_used = 0;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
Button askApplyDiscardCancel(QWidget *parent)
|
||||
Button askApplyDiscardCancel(QWidget* parent)
|
||||
{
|
||||
const QString question = QCoreApplication::translate("LtsDialog",
|
||||
"<br>"
|
||||
"Apply - apply changes and close.<br>"
|
||||
"Discard - discard changes and close.<br>"
|
||||
"Cancel - do not close.");
|
||||
const QString title = QCoreApplication::translate("LtsDialog", "Unapplied changes made. Apply the changes?");
|
||||
return LtsMessageDialog::showMessage(parent,
|
||||
question,
|
||||
title,
|
||||
Behaviour::Modal,
|
||||
Button::Apply | Button::Discard | Button::Cancel);
|
||||
const QString question = QCoreApplication::translate("LtsDialog", "<br>"
|
||||
"Apply - apply changes and close.<br>"
|
||||
"Discard - discard changes and close.<br>"
|
||||
"Cancel - do not close.");
|
||||
const QString title = QCoreApplication::translate("LtsDialog", "Unapplied changes made. Apply the changes?");
|
||||
return LtsMessageDialog::showMessage(parent, question, title, Behaviour::Modal,
|
||||
Button::Apply | Button::Discard | Button::Cancel);
|
||||
}
|
||||
|
||||
} // namespace LtsMessageDialog
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
LtsMessageDialogNew::LtsMessageDialogNew(QWidget *parent, const QString &message, const QString &title, const Behaviour behaviour, const Buttons buttons, const QHash<Button, QString> &buttonTexts, bool deleteOnClose)
|
||||
LtsMessageDialogNew::LtsMessageDialogNew(QWidget* parent, const QString& message, const QString& title,
|
||||
const Behaviour behaviour, const Buttons buttons,
|
||||
const QHash<Button, QString>& buttonTexts, bool deleteOnClose)
|
||||
{
|
||||
m_dialog = new LtsFramelessDialog(parent, behaviour);
|
||||
m_dialog = new LtsFramelessDialog(parent, behaviour);
|
||||
|
||||
if (deleteOnClose)
|
||||
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
if (deleteOnClose)
|
||||
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
connect(m_dialog, &LtsFramelessDialog::destroyed,
|
||||
this, &LtsMessageDialogNew::deleteLater);
|
||||
connect(m_dialog, &LtsFramelessDialog::destroyed, this, &LtsMessageDialogNew::deleteLater);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(m_dialog);
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout(m_dialog);
|
||||
|
||||
QString text;
|
||||
if (!title.isEmpty())
|
||||
{
|
||||
text = QStringLiteral("<b>%1</b><br><br>").arg(title);
|
||||
}
|
||||
QString text;
|
||||
if (!title.isEmpty())
|
||||
{
|
||||
text = QStringLiteral("<b>%1</b><br><br>").arg(title);
|
||||
}
|
||||
|
||||
text += message;
|
||||
text += message;
|
||||
|
||||
QLabel *messageLabel = new QLabel(text, m_dialog);
|
||||
messageLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
mainLayout->addWidget(messageLabel);
|
||||
QLabel* messageLabel = new QLabel(text, m_dialog);
|
||||
messageLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
mainLayout->addWidget(messageLabel);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->setMargin(0);
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
|
||||
|
||||
if (buttons.testFlag(Button::Ok))
|
||||
connect(addButton(buttonTexts.value(Button::Ok, tr("Ok")), buttonLayout, m_dialog, Button::Ok, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogNew::ok);
|
||||
|
||||
if (buttons.testFlag(Button::Ok))
|
||||
connect(addButton(buttonTexts.value(Button::Ok, tr("Ok")), buttonLayout, m_dialog, Button::Ok, parent), &QPushButton::clicked, this, &LtsMessageDialogNew::ok);
|
||||
if (buttons.testFlag(Button::Yes))
|
||||
connect(addButton(buttonTexts.value(Button::Yes, tr("Yes")), buttonLayout, m_dialog, Button::Yes, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogNew::yes);
|
||||
|
||||
if (buttons.testFlag(Button::Yes))
|
||||
connect(addButton(buttonTexts.value(Button::Yes, tr("Yes")), buttonLayout, m_dialog, Button::Yes, parent), &QPushButton::clicked, this, &LtsMessageDialogNew::yes);
|
||||
if (buttons.testFlag(Button::No))
|
||||
connect(addButton(buttonTexts.value(Button::No, tr("No")), buttonLayout, m_dialog, Button::No, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogNew::no);
|
||||
|
||||
if (buttons.testFlag(Button::No))
|
||||
connect(addButton(buttonTexts.value(Button::No, tr("No")), buttonLayout, m_dialog, Button::No, parent), &QPushButton::clicked, this, &LtsMessageDialogNew::no);
|
||||
if (buttons.testFlag(Button::Apply))
|
||||
connect(addButton(buttonTexts.value(Button::Apply, tr("Apply")), buttonLayout, m_dialog, Button::Apply, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogNew::apply);
|
||||
|
||||
if (buttons.testFlag(Button::Apply))
|
||||
connect(addButton(buttonTexts.value(Button::Apply, tr("Apply")), buttonLayout, m_dialog, Button::Apply, parent), &QPushButton::clicked, this, &LtsMessageDialogNew::apply);
|
||||
if (buttons.testFlag(Button::Discard))
|
||||
connect(addButton(buttonTexts.value(Button::Discard, tr("Discard")), buttonLayout, m_dialog, Button::Discard,
|
||||
parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogNew::discard);
|
||||
|
||||
if (buttons.testFlag(Button::Discard))
|
||||
connect(addButton(buttonTexts.value(Button::Discard, tr("Discard")), buttonLayout, m_dialog, Button::Discard, parent), &QPushButton::clicked, this, &LtsMessageDialogNew::discard);
|
||||
if (buttons.testFlag(Button::Cancel))
|
||||
connect(
|
||||
addButton(buttonTexts.value(Button::Cancel, tr("Cancel")), buttonLayout, m_dialog, Button::Cancel, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogNew::cancel);
|
||||
|
||||
if (buttons.testFlag(Button::Cancel))
|
||||
connect(addButton(buttonTexts.value(Button::Cancel, tr("Cancel")), buttonLayout, m_dialog, Button::Cancel, parent), &QPushButton::clicked, this, &LtsMessageDialogNew::cancel);
|
||||
QWidget* buttonLayoutWidget = new QWidget;
|
||||
buttonLayoutWidget->setLayout(buttonLayout);
|
||||
|
||||
QWidget *buttonLayoutWidget = new QWidget;
|
||||
buttonLayoutWidget->setLayout(buttonLayout);
|
||||
mainLayout->addWidget(buttonLayoutWidget);
|
||||
|
||||
mainLayout->addWidget(buttonLayoutWidget);
|
||||
|
||||
m_dialog->show();
|
||||
m_dialog->raise();
|
||||
m_dialog->show();
|
||||
m_dialog->raise();
|
||||
}
|
||||
|
||||
|
||||
QPushButton* LtsMessageDialogNew::addButton(const QString &text, QHBoxLayout *thatLayout, LtsFramelessDialog *dialog, const Button &button, QWidget *parent)
|
||||
QPushButton* LtsMessageDialogNew::addButton(const QString& text, QHBoxLayout* thatLayout, LtsFramelessDialog* dialog,
|
||||
const Button& button, QWidget* parent)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(text, parent);
|
||||
connect(btn, &QPushButton::clicked, dialog, &LtsFramelessDialog::accept);
|
||||
thatLayout->addWidget(btn);
|
||||
QPushButton* btn = new QPushButton(text, parent);
|
||||
connect(btn, &QPushButton::clicked, dialog, &LtsFramelessDialog::accept);
|
||||
thatLayout->addWidget(btn);
|
||||
|
||||
if (button == Button::Ok ||
|
||||
button == Button::Cancel)
|
||||
{
|
||||
btn->setDefault(true);
|
||||
}
|
||||
if (button == Button::Ok || button == Button::Cancel)
|
||||
{
|
||||
btn->setDefault(true);
|
||||
}
|
||||
|
||||
return btn;
|
||||
return btn;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+101
-114
@@ -1,155 +1,142 @@
|
||||
#include "lts_message_dialog_helper.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QEventLoop>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QEventLoop>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
LtsMessageDialogHelper::LtsMessageDialogHelper(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_result(Button::Cancel)
|
||||
, m_dialog(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
Button LtsMessageDialogHelper::showMessage(QWidget *parent,
|
||||
const QString &message,
|
||||
const QString &title,
|
||||
Behaviour behaviour,
|
||||
Buttons buttons,
|
||||
const QHash<Button, QString> &buttonTexts)
|
||||
LtsMessageDialogHelper::LtsMessageDialogHelper(QObject* parent)
|
||||
: QObject(parent), m_result(Button::Cancel), m_dialog(nullptr)
|
||||
{
|
||||
m_dialog = new LtsFramelessDialog(parent, behaviour);
|
||||
|
||||
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(m_dialog);
|
||||
|
||||
QString text;
|
||||
if (!title.isEmpty())
|
||||
{
|
||||
text = QStringLiteral("<b>%1</b><br><br>").arg(title);
|
||||
}
|
||||
|
||||
text += message;
|
||||
|
||||
QLabel *messageLabel = new QLabel(text, m_dialog);
|
||||
messageLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
mainLayout->addWidget(messageLabel);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->setMargin(0);
|
||||
|
||||
|
||||
connect(m_dialog, &LtsFramelessDialog::rejected, this, &LtsMessageDialogHelper::slotCancel);
|
||||
|
||||
if (buttons.testFlag(Button::Ok))
|
||||
connect(addButton(buttonTexts.value(Button::Ok, tr("Ok")), buttonLayout, m_dialog, Button::Ok, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotOkay);
|
||||
|
||||
if (buttons.testFlag(Button::Yes))
|
||||
connect(addButton(buttonTexts.value(Button::Yes, tr("Yes")), buttonLayout, m_dialog, Button::Yes, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotYes);
|
||||
|
||||
if (buttons.testFlag(Button::No))
|
||||
connect(addButton(buttonTexts.value(Button::No, tr("No")), buttonLayout, m_dialog, Button::No, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotNo);
|
||||
|
||||
if (buttons.testFlag(Button::Apply))
|
||||
connect(addButton(buttonTexts.value(Button::Apply, tr("Apply")), buttonLayout, m_dialog, Button::Apply, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotApply);
|
||||
|
||||
if (buttons.testFlag(Button::Discard))
|
||||
connect(addButton(buttonTexts.value(Button::Discard, tr("Discard")), buttonLayout, m_dialog, Button::Discard, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotDiscard);
|
||||
|
||||
if (buttons.testFlag(Button::Cancel))
|
||||
connect(addButton(buttonTexts.value(Button::Cancel, tr("Cancel")), buttonLayout, m_dialog, Button::Cancel, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotCancel);
|
||||
|
||||
QWidget *buttonLayoutWidget = new QWidget;
|
||||
buttonLayoutWidget->setLayout(buttonLayout);
|
||||
|
||||
mainLayout->addWidget(buttonLayoutWidget);
|
||||
|
||||
m_dialog->show();
|
||||
m_dialog->raise();
|
||||
|
||||
|
||||
QEventLoop loop;
|
||||
connect(this, &LtsMessageDialogHelper::signalQuitEventLoop, &loop, &QEventLoop::quit, Qt::QueuedConnection);
|
||||
loop.exec();
|
||||
|
||||
return m_result;
|
||||
}
|
||||
|
||||
Button LtsMessageDialogHelper::showMessage(QWidget* parent, const QString& message, const QString& title,
|
||||
Behaviour behaviour, Buttons buttons,
|
||||
const QHash<Button, QString>& buttonTexts)
|
||||
{
|
||||
m_dialog = new LtsFramelessDialog(parent, behaviour);
|
||||
|
||||
m_dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout(m_dialog);
|
||||
|
||||
QString text;
|
||||
if (!title.isEmpty())
|
||||
{
|
||||
text = QStringLiteral("<b>%1</b><br><br>").arg(title);
|
||||
}
|
||||
|
||||
text += message;
|
||||
|
||||
QLabel* messageLabel = new QLabel(text, m_dialog);
|
||||
messageLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
mainLayout->addWidget(messageLabel);
|
||||
|
||||
QHBoxLayout* buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
connect(m_dialog, &LtsFramelessDialog::rejected, this, &LtsMessageDialogHelper::slotCancel);
|
||||
|
||||
if (buttons.testFlag(Button::Ok))
|
||||
connect(addButton(buttonTexts.value(Button::Ok, tr("Ok")), buttonLayout, m_dialog, Button::Ok, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotOkay);
|
||||
|
||||
if (buttons.testFlag(Button::Yes))
|
||||
connect(addButton(buttonTexts.value(Button::Yes, tr("Yes")), buttonLayout, m_dialog, Button::Yes, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotYes);
|
||||
|
||||
if (buttons.testFlag(Button::No))
|
||||
connect(addButton(buttonTexts.value(Button::No, tr("No")), buttonLayout, m_dialog, Button::No, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotNo);
|
||||
|
||||
if (buttons.testFlag(Button::Apply))
|
||||
connect(addButton(buttonTexts.value(Button::Apply, tr("Apply")), buttonLayout, m_dialog, Button::Apply, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotApply);
|
||||
|
||||
if (buttons.testFlag(Button::Discard))
|
||||
connect(addButton(buttonTexts.value(Button::Discard, tr("Discard")), buttonLayout, m_dialog, Button::Discard,
|
||||
parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotDiscard);
|
||||
|
||||
if (buttons.testFlag(Button::Cancel))
|
||||
connect(
|
||||
addButton(buttonTexts.value(Button::Cancel, tr("Cancel")), buttonLayout, m_dialog, Button::Cancel, parent),
|
||||
&QPushButton::clicked, this, &LtsMessageDialogHelper::slotCancel);
|
||||
|
||||
QWidget* buttonLayoutWidget = new QWidget;
|
||||
buttonLayoutWidget->setLayout(buttonLayout);
|
||||
|
||||
mainLayout->addWidget(buttonLayoutWidget);
|
||||
|
||||
m_dialog->show();
|
||||
m_dialog->raise();
|
||||
|
||||
QEventLoop loop;
|
||||
connect(this, &LtsMessageDialogHelper::signalQuitEventLoop, &loop, &QEventLoop::quit, Qt::QueuedConnection);
|
||||
loop.exec();
|
||||
|
||||
return m_result;
|
||||
}
|
||||
|
||||
void LtsMessageDialogHelper::slotOkay()
|
||||
{
|
||||
m_dialog->hide();
|
||||
m_result = Button::Ok;
|
||||
emit signalQuitEventLoop();
|
||||
m_dialog->hide();
|
||||
m_result = Button::Ok;
|
||||
emit signalQuitEventLoop();
|
||||
}
|
||||
|
||||
|
||||
void LtsMessageDialogHelper::slotYes()
|
||||
{
|
||||
m_dialog->hide();
|
||||
m_result = Button::Yes;
|
||||
emit signalQuitEventLoop();
|
||||
m_dialog->hide();
|
||||
m_result = Button::Yes;
|
||||
emit signalQuitEventLoop();
|
||||
}
|
||||
|
||||
|
||||
void LtsMessageDialogHelper::slotNo()
|
||||
{
|
||||
m_dialog->hide();
|
||||
m_result = Button::No;
|
||||
emit signalQuitEventLoop();
|
||||
m_dialog->hide();
|
||||
m_result = Button::No;
|
||||
emit signalQuitEventLoop();
|
||||
}
|
||||
|
||||
|
||||
void LtsMessageDialogHelper::slotApply()
|
||||
{
|
||||
m_dialog->hide();
|
||||
m_result = Button::Apply;
|
||||
emit signalQuitEventLoop();
|
||||
m_dialog->hide();
|
||||
m_result = Button::Apply;
|
||||
emit signalQuitEventLoop();
|
||||
}
|
||||
|
||||
|
||||
void LtsMessageDialogHelper::slotDiscard()
|
||||
{
|
||||
m_dialog->hide();
|
||||
m_result = Button::Discard;
|
||||
emit signalQuitEventLoop();
|
||||
m_dialog->hide();
|
||||
m_result = Button::Discard;
|
||||
emit signalQuitEventLoop();
|
||||
}
|
||||
|
||||
|
||||
void LtsMessageDialogHelper::slotCancel()
|
||||
{
|
||||
m_dialog->hide();
|
||||
m_result = Button::Cancel;
|
||||
emit signalQuitEventLoop();
|
||||
m_dialog->hide();
|
||||
m_result = Button::Cancel;
|
||||
emit signalQuitEventLoop();
|
||||
}
|
||||
|
||||
|
||||
QPushButton* LtsMessageDialogHelper::addButton(const QString &text, QHBoxLayout *thatLayout, LtsFramelessDialog *dialog, const Button &button, QWidget *parent)
|
||||
QPushButton* LtsMessageDialogHelper::addButton(const QString& text, QHBoxLayout* thatLayout, LtsFramelessDialog* dialog,
|
||||
const Button& button, QWidget* parent)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(text, parent);
|
||||
connect(btn, &QPushButton::clicked, dialog, &LtsFramelessDialog::accept);
|
||||
thatLayout->addWidget(btn);
|
||||
QPushButton* btn = new QPushButton(text, parent);
|
||||
connect(btn, &QPushButton::clicked, dialog, &LtsFramelessDialog::accept);
|
||||
thatLayout->addWidget(btn);
|
||||
|
||||
if (button == Button::Ok ||
|
||||
button == Button::Cancel)
|
||||
{
|
||||
btn->setDefault(true);
|
||||
}
|
||||
if (button == Button::Ok || button == Button::Cancel)
|
||||
{
|
||||
btn->setDefault(true);
|
||||
}
|
||||
|
||||
return btn;
|
||||
return btn;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+22
-24
@@ -1,10 +1,10 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include "ltswidgets_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
#include <QSpinBox>
|
||||
|
||||
@@ -15,39 +15,37 @@ class LTSWIDGETS_EXPORT LtsMultiRangeSpinBox : public QSpinBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LtsMultiRangeSpinBox(QWidget *parent = nullptr);
|
||||
public:
|
||||
explicit LtsMultiRangeSpinBox(QWidget* parent = nullptr);
|
||||
~LtsMultiRangeSpinBox() = default;
|
||||
|
||||
|
||||
public slots:
|
||||
void setRanges(const QVector<QPair<int, int>> &ranges);
|
||||
public slots:
|
||||
void setRanges(const QVector<QPair<int, int>>& ranges);
|
||||
void setRange(int min, int max);
|
||||
void setMinimum(int min);
|
||||
void setMaximum(int max);
|
||||
|
||||
protected:
|
||||
QValidator::State validate(QString &input, int &pos) const override;
|
||||
void fixup(QString &str) const override;
|
||||
void focusOutEvent(QFocusEvent *event) override;
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
protected:
|
||||
QValidator::State validate(QString& input, int& pos) const override;
|
||||
void fixup(QString& str) const override;
|
||||
void focusOutEvent(QFocusEvent* event) override;
|
||||
void wheelEvent(QWheelEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
private:
|
||||
static QVector<QPair<int,int>> sortRanges(const QVector<QPair<int, int> > &ranges);
|
||||
private:
|
||||
static QVector<QPair<int, int>> sortRanges(const QVector<QPair<int, int>>& ranges);
|
||||
|
||||
QValidator::State validateAll(QString& input, int& pos);
|
||||
|
||||
QValidator::State validateAll(QString &input, int &pos);
|
||||
|
||||
int fixupValue(int value) const;
|
||||
int fixupValue(int value, bool higher) const;
|
||||
private:
|
||||
|
||||
private:
|
||||
QVector<QPair<int, int>> m_rangesList;
|
||||
|
||||
int m_curVal = minimum();
|
||||
QRegExp m_regex;
|
||||
QRegularExpression m_regex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+129
-151
@@ -1,198 +1,176 @@
|
||||
#include "lts_notification_box.h"
|
||||
|
||||
#include "ui_lts_notification_box.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QLinearGradient>
|
||||
#include <QColor>
|
||||
#include <QGraphicsDropShadowEffect>
|
||||
#include <QStyleOption>
|
||||
#include <QLinearGradient>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
#ifdef NOTIBOX_DEBUG
|
||||
#include <QDebug>
|
||||
#endif
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
const int LtsNotificationBox::margin = 14;
|
||||
|
||||
LtsNotificationBox::LtsNotificationBox(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::NotiBox)
|
||||
LtsNotificationBox::LtsNotificationBox(QWidget* parent) : QWidget(parent), m_ui(new Ui::NotiBox)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->lblText->setText({});
|
||||
m_ui->setupUi(this);
|
||||
m_ui->lblText->setText({});
|
||||
|
||||
connect(m_ui->lblText, &QLabel::linkActivated,
|
||||
this, [this](const QString &link)
|
||||
{
|
||||
emit signalLinkClicked(link);
|
||||
});
|
||||
connect(m_ui->lblText, &QLabel::linkActivated, this, [this](const QString& link) { emit signalLinkClicked(link); });
|
||||
|
||||
connect(m_ui->tbClose, &QToolButton::clicked,
|
||||
this, &LtsNotificationBox::signalClose);
|
||||
connect(m_ui->tbAck, &QToolButton::clicked,
|
||||
this, &LtsNotificationBox::signalAck);
|
||||
connect(m_ui->tbClose, &QToolButton::clicked, this, &LtsNotificationBox::signalClose);
|
||||
connect(m_ui->tbAck, &QToolButton::clicked, this, &LtsNotificationBox::signalAck);
|
||||
|
||||
setObjectName(QStringLiteral("NotiBox"));
|
||||
setObjectName(QStringLiteral("NotiBox"));
|
||||
|
||||
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this);
|
||||
shadow->setOffset(0, 0);
|
||||
shadow->setBlurRadius(margin*2);
|
||||
shadow->setColor(QColor(25, 25, 25));
|
||||
QGraphicsDropShadowEffect* shadow = new QGraphicsDropShadowEffect(this);
|
||||
shadow->setOffset(0, 0);
|
||||
shadow->setBlurRadius(margin * 2);
|
||||
shadow->setColor(QColor(25, 25, 25));
|
||||
|
||||
setGraphicsEffect(shadow);
|
||||
setGraphicsEffect(shadow);
|
||||
}
|
||||
|
||||
|
||||
void LtsNotificationBox::message(const QString &title, const QString &text, MessageType type)
|
||||
void LtsNotificationBox::message(const QString& title, const QString& text, MessageType type)
|
||||
{
|
||||
static QString rgbBaseString(QStringLiteral("%1, %2, %3"));
|
||||
static QString closeDefault(QStringLiteral("close.svg"));
|
||||
static QString closeDark(QStringLiteral("close_dark.svg"));
|
||||
static QString ackDefault(QStringLiteral("ack.svg"));
|
||||
static QString ackDark(QStringLiteral("ack_dark.svg"));
|
||||
static QString lightTextColor(QStringLiteral("fbfbfb"));
|
||||
static QString darkTextColor(QStringLiteral("2c3642"));
|
||||
static QString rgbBaseString(QStringLiteral("%1, %2, %3"));
|
||||
static QString closeDefault(QStringLiteral("close.svg"));
|
||||
static QString closeDark(QStringLiteral("close_dark.svg"));
|
||||
static QString ackDefault(QStringLiteral("ack.svg"));
|
||||
static QString ackDark(QStringLiteral("ack_dark.svg"));
|
||||
static QString lightTextColor(QStringLiteral("fbfbfb"));
|
||||
static QString darkTextColor(QStringLiteral("2c3642"));
|
||||
|
||||
static QColor errorStart(254, 45, 102);
|
||||
static QColor errorEnd(255, 92, 61);
|
||||
static QColor errorStart(254, 45, 102);
|
||||
static QColor errorEnd(255, 92, 61);
|
||||
|
||||
static QColor successStart(43, 167, 70);
|
||||
static QColor successEnd(130, 180, 45);
|
||||
static QColor successStart(43, 167, 70);
|
||||
static QColor successEnd(130, 180, 45);
|
||||
|
||||
static QColor infoStart(74, 74, 74);
|
||||
static QColor infoEnd(43, 43, 43);
|
||||
static QColor infoStart(74, 74, 74);
|
||||
static QColor infoEnd(43, 43, 43);
|
||||
|
||||
static QColor warningStart(253, 151, 4);
|
||||
static QColor warningEnd(253, 202, 0);
|
||||
static QColor warningStart(253, 151, 4);
|
||||
static QColor warningEnd(253, 202, 0);
|
||||
|
||||
QColor start;
|
||||
QColor end;
|
||||
QString close;
|
||||
QString closeHover;
|
||||
QString ack;
|
||||
QString ackHover;
|
||||
QString textColor;
|
||||
|
||||
QColor start;
|
||||
QColor end;
|
||||
QString close;
|
||||
QString closeHover;
|
||||
QString ack;
|
||||
QString ackHover;
|
||||
QString textColor;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MessageType::Error:
|
||||
switch (type)
|
||||
{
|
||||
start = errorStart;
|
||||
end = errorEnd;
|
||||
close = closeDefault;
|
||||
closeHover = closeDark;
|
||||
ack = ackDefault;
|
||||
ackHover = ackDark;
|
||||
textColor = lightTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/error.svg")));
|
||||
case MessageType::Error: {
|
||||
start = errorStart;
|
||||
end = errorEnd;
|
||||
close = closeDefault;
|
||||
closeHover = closeDark;
|
||||
ack = ackDefault;
|
||||
ackHover = ackDark;
|
||||
textColor = lightTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/error.svg")));
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
case MessageType::Success: {
|
||||
start = successStart;
|
||||
end = successEnd;
|
||||
close = closeDefault;
|
||||
closeHover = closeDark;
|
||||
ack = ackDefault;
|
||||
ackHover = ackDark;
|
||||
textColor = lightTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/success.svg")));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MessageType::Info: {
|
||||
start = infoStart;
|
||||
end = infoEnd;
|
||||
close = closeDefault;
|
||||
closeHover = closeDark;
|
||||
ack = ackDefault;
|
||||
ackHover = ackDark;
|
||||
textColor = lightTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/info.svg")));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MessageType::Warning: {
|
||||
start = warningStart;
|
||||
end = warningEnd;
|
||||
close = closeDark;
|
||||
closeHover = closeDefault;
|
||||
ack = ackDark;
|
||||
ackHover = ackDefault;
|
||||
textColor = darkTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/warning.svg")));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case MessageType::Success:
|
||||
{
|
||||
start = successStart;
|
||||
end = successEnd;
|
||||
close = closeDefault;
|
||||
closeHover = closeDark;
|
||||
ack = ackDefault;
|
||||
ackHover = ackDark;
|
||||
textColor = lightTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/success.svg")));
|
||||
QStringList css;
|
||||
|
||||
break;
|
||||
}
|
||||
css << QStringLiteral("#NotiBox { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop: 0 rgb(%1), stop: 1 "
|
||||
"rgb(%2)); border: 1px solid rgb(%3); border-radius: 8px; margin: %4px }")
|
||||
.arg(rgbBaseString.arg(start.red()).arg(start.green()).arg(start.blue()),
|
||||
rgbBaseString.arg(end.red()).arg(end.green()).arg(end.blue()),
|
||||
rgbBaseString.arg(end.red()).arg(end.green()).arg(end.blue()))
|
||||
.arg(margin);
|
||||
|
||||
case MessageType::Info:
|
||||
{
|
||||
start = infoStart;
|
||||
end = infoEnd;
|
||||
close = closeDefault;
|
||||
closeHover = closeDark;
|
||||
ack = ackDefault;
|
||||
ackHover = ackDark;
|
||||
textColor = lightTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/info.svg")));
|
||||
css << QStringLiteral("QToolButton#tbClose { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: 0px; "
|
||||
"background-color: transparent; }")
|
||||
.arg(close);
|
||||
css << QStringLiteral("QToolButton#tbClose:hover { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: "
|
||||
"0px; background-color: transparent; }")
|
||||
.arg(closeHover);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case MessageType::Warning:
|
||||
{
|
||||
start = warningStart;
|
||||
end = warningEnd;
|
||||
close = closeDark;
|
||||
closeHover = closeDefault;
|
||||
ack = ackDark;
|
||||
ackHover = ackDefault;
|
||||
textColor = darkTextColor;
|
||||
m_ui->lblImage->setPixmap(QPixmap(QStringLiteral(":/warning.svg")));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList css;
|
||||
|
||||
css << QStringLiteral("#NotiBox { background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop: 0 rgb(%1), stop: 1 rgb(%2)); border: 1px solid rgb(%3); border-radius: 8px; margin: %4px }").
|
||||
arg(rgbBaseString.arg(start.red()).arg(start.green()).arg(start.blue()),
|
||||
rgbBaseString.arg(end.red()).arg(end.green()).arg(end.blue()),
|
||||
rgbBaseString.arg(end.red()).arg(end.green()).arg(end.blue())).
|
||||
arg(margin);
|
||||
|
||||
css << QStringLiteral("QToolButton#tbClose { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: 0px; background-color: transparent; }").arg(close);
|
||||
css << QStringLiteral("QToolButton#tbClose:hover { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: 0px; background-color: transparent; }").arg(closeHover);
|
||||
|
||||
css << QStringLiteral("QToolButton#tbAck { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: 0px; background-color: transparent; }").arg(ack);
|
||||
css << QStringLiteral("QToolButton#tbAck:hover { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: 0px; background-color: transparent; }").arg(ackHover);
|
||||
css << QStringLiteral("QToolButton#tbAck { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: 0px; "
|
||||
"background-color: transparent; }")
|
||||
.arg(ack);
|
||||
css << QStringLiteral("QToolButton#tbAck:hover { border-image: url(:/%1) 0 0 0 0 stretch stretch; border-width: "
|
||||
"0px; background-color: transparent; }")
|
||||
.arg(ackHover);
|
||||
|
||||
#ifdef NOTIBOX_DEBUG
|
||||
qWarning() << "css" << css;
|
||||
qWarning() << "css" << css;
|
||||
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/close.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/close_dark.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/error.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/info.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/warning.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/success.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/close.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/close_dark.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/error.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/info.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/warning.svg"));
|
||||
qWarning() << "exists?" << QFile::exists(QStringLiteral(":/success.svg"));
|
||||
#endif
|
||||
|
||||
m_ui->lblImage->setStyleSheet(QString());
|
||||
setStyleSheet(css.join(QStringLiteral(" ")));
|
||||
m_ui->lblImage->setStyleSheet(QString());
|
||||
setStyleSheet(css.join(QStringLiteral(" ")));
|
||||
|
||||
m_ui->lblText->setText(QStringLiteral("<p><span style='font-size:14pt; font-weight:600; color:#%1;'>%2</span></p><p><span style='font-size:14pt; color:#%3;'>%4</span></p>").arg(textColor, title, textColor, text));
|
||||
m_ui->lblText->setText(
|
||||
QStringLiteral("<p><span style='font-size:14pt; font-weight:600; color:#%1;'>%2</span></p><p><span "
|
||||
"style='font-size:14pt; color:#%3;'>%4</span></p>")
|
||||
.arg(textColor, title, textColor, text));
|
||||
|
||||
show();
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
void LtsNotificationBox::paintEvent(QPaintEvent *)
|
||||
void LtsNotificationBox::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
QStyleOption opt;
|
||||
opt.initFrom(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+74
-97
@@ -1,133 +1,110 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_profile_button.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QEvent>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QPaintEvent>
|
||||
#include <QBrush>
|
||||
#include <QPen>
|
||||
#include <QRect>
|
||||
#include <QEvent>
|
||||
|
||||
using namespace LtsWidgets;
|
||||
|
||||
|
||||
LtsProfileButton::LtsProfileButton(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_isHovered(false)
|
||||
, m_menuEnabled(true)
|
||||
LtsProfileButton::LtsProfileButton(QWidget* parent) : QWidget(parent), m_isHovered(false), m_menuEnabled(true)
|
||||
{
|
||||
QSizePolicy qsp = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
qsp.setHeightForWidth(true);
|
||||
setSizePolicy(qsp);
|
||||
QSizePolicy qsp = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
qsp.setHeightForWidth(true);
|
||||
setSizePolicy(qsp);
|
||||
}
|
||||
|
||||
|
||||
void LtsProfileButton::setPixmap(const QPixmap &pixmap)
|
||||
void LtsProfileButton::setPixmap(const QPixmap& pixmap)
|
||||
{
|
||||
if (pixmap.isNull())
|
||||
m_pixmap = QPixmap(QStringLiteral("icon:no_pic.svg"));
|
||||
else
|
||||
m_pixmap = pixmap;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void LtsProfileButton::enterEvent(QEvent *event)
|
||||
{
|
||||
|
||||
m_isHovered = true;
|
||||
update();
|
||||
QWidget::enterEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void LtsProfileButton::leaveEvent(QEvent *event)
|
||||
{
|
||||
|
||||
m_isHovered = false;
|
||||
update();
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
|
||||
bool LtsProfileButton::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress && m_menuEnabled)
|
||||
{
|
||||
emit signalClicked();
|
||||
event->accept();
|
||||
if (pixmap.isNull())
|
||||
m_pixmap = QPixmap(QStringLiteral("icon:no_pic.svg"));
|
||||
else
|
||||
m_pixmap = pixmap;
|
||||
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
|
||||
void LtsProfileButton::paintEvent(QPaintEvent* event)
|
||||
void LtsProfileButton::enterEvent(QEvent* event)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.save();
|
||||
|
||||
int minSize;
|
||||
QPointF center;
|
||||
minSize = height() > width() ? width() : height();
|
||||
center = QPointF(width() / 2.0, height() / 2.0);
|
||||
|
||||
|
||||
|
||||
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
|
||||
QPixmap pixmap(minSize, minSize);
|
||||
pixmap.fill(Qt::white);
|
||||
m_isHovered = true;
|
||||
update();
|
||||
QWidget::enterEvent(static_cast<QEnterEvent*>(event));
|
||||
}
|
||||
|
||||
void LtsProfileButton::leaveEvent(QEvent* event)
|
||||
{
|
||||
|
||||
m_isHovered = false;
|
||||
update();
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
bool LtsProfileButton::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::MouseButtonPress && m_menuEnabled)
|
||||
{
|
||||
emit signalClicked();
|
||||
event->accept();
|
||||
|
||||
if (!m_pixmap.isNull())
|
||||
{
|
||||
if (!(m_isHovered && m_menuEnabled))
|
||||
{
|
||||
pixmap = m_pixmap.scaled(minSize, minSize, Qt::KeepAspectRatioByExpanding);
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void LtsProfileButton::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QPainter p(this);
|
||||
p.save();
|
||||
|
||||
QPainterPath path;
|
||||
path.addEllipse(center,
|
||||
minSize / 2.0 - 4,
|
||||
minSize / 2.0 - 4);
|
||||
p.setClipPath(path);
|
||||
p.drawPixmap(center - QPointF(minSize/2.0,minSize/2.0),pixmap);
|
||||
int minSize;
|
||||
QPointF center;
|
||||
minSize = height() > width() ? width() : height();
|
||||
center = QPointF(width() / 2.0, height() / 2.0);
|
||||
|
||||
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
QPixmap pixmap(minSize, minSize);
|
||||
pixmap.fill(Qt::white);
|
||||
|
||||
|
||||
p.setPen(QPen(QColor("gray"), 2));
|
||||
p.drawEllipse(center,
|
||||
minSize / 2.0 - 4,
|
||||
minSize / 2.0 - 4);
|
||||
if (!m_pixmap.isNull())
|
||||
{
|
||||
if (!(m_isHovered && m_menuEnabled))
|
||||
{
|
||||
pixmap = m_pixmap.scaled(minSize, minSize, Qt::KeepAspectRatioByExpanding);
|
||||
}
|
||||
}
|
||||
|
||||
QPainterPath path;
|
||||
path.addEllipse(center, minSize / 2.0 - 4, minSize / 2.0 - 4);
|
||||
p.setClipPath(path);
|
||||
p.drawPixmap(center - QPointF(minSize / 2.0, minSize / 2.0), pixmap);
|
||||
|
||||
|
||||
if (m_isHovered && m_menuEnabled)
|
||||
{
|
||||
p.setPen(QPen(QColor(QStringLiteral("gray")), (minSize / 48 * 2)));
|
||||
p.setPen(QPen(QColor("gray"), 2));
|
||||
p.drawEllipse(center, minSize / 2.0 - 4, minSize / 2.0 - 4);
|
||||
|
||||
double xc = size().width()/2.012;
|
||||
double yc = size().height()/2.012;
|
||||
double diff = minSize/2.012;
|
||||
if (m_isHovered && m_menuEnabled)
|
||||
{
|
||||
p.setPen(QPen(QColor(QStringLiteral("gray")), (minSize / 48 * 2)));
|
||||
|
||||
p.drawLine(QPointF(xc - (diff/2.01f), yc - (diff/3.01f)), QPointF(xc + (diff/2.02f), yc - (diff/3.02f)));
|
||||
p.drawLine(QPointF(xc - (diff/2.01f), yc - 0.01f), QPointF(xc + (diff/2.02f), yc - 0));
|
||||
p.drawLine(QPointF(xc - (diff/2.01f), yc + (diff/3.01f)), QPointF(xc + (diff/2.02f), yc + (diff/3.02f)));
|
||||
}
|
||||
double xc = size().width() / 2.012;
|
||||
double yc = size().height() / 2.012;
|
||||
double diff = minSize / 2.012;
|
||||
|
||||
p.drawLine(QPointF(xc - (diff / 2.01f), yc - (diff / 3.01f)),
|
||||
QPointF(xc + (diff / 2.02f), yc - (diff / 3.02f)));
|
||||
p.drawLine(QPointF(xc - (diff / 2.01f), yc - 0.01f), QPointF(xc + (diff / 2.02f), yc - 0));
|
||||
p.drawLine(QPointF(xc - (diff / 2.01f), yc + (diff / 3.01f)),
|
||||
QPointF(xc + (diff / 2.02f), yc + (diff / 3.02f)));
|
||||
}
|
||||
|
||||
event->accept();
|
||||
p.restore();
|
||||
event->accept();
|
||||
p.restore();
|
||||
}
|
||||
Executable → Regular
+639
-730
File diff suppressed because it is too large.
Load diff
Executable → Regular
+231
-270
@@ -2,390 +2,351 @@
|
||||
|
||||
#include "ui_lts_text_editor.h"
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QTextCursor>
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QTextCharFormat>
|
||||
#include <QMimeData>
|
||||
#include <QTextList>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QDebug>
|
||||
#include <QLineEdit>
|
||||
#include <QMimeData>
|
||||
#include <QTextCharFormat>
|
||||
#include <QTextCursor>
|
||||
#include <QTextList>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
LtsTextEditor::LtsTextEditor(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::LtsTextEditor)
|
||||
LtsTextEditor::LtsTextEditor(QWidget* parent) : QWidget(parent), m_ui(new Ui::LtsTextEditor)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->textEdit, &QTextEdit::currentCharFormatChanged,
|
||||
this, &LtsTextEditor::slotCurrentCharFormatChanged);
|
||||
connect(m_ui->textEdit, &QTextEdit::cursorPositionChanged,
|
||||
this, &LtsTextEditor::slotAlignmentChanged);
|
||||
connect(m_ui->textEdit, &QTextEdit::currentCharFormatChanged, this, &LtsTextEditor::slotCurrentCharFormatChanged);
|
||||
connect(m_ui->textEdit, &QTextEdit::cursorPositionChanged, this, &LtsTextEditor::slotAlignmentChanged);
|
||||
|
||||
connect(m_ui->textEdit->document(), &QTextDocument::undoAvailable,
|
||||
m_ui->pbUndo, &QToolButton::setEnabled);
|
||||
connect(m_ui->textEdit->document(), &QTextDocument::redoAvailable,
|
||||
m_ui->pbRedo, &QToolButton::setEnabled);
|
||||
connect(m_ui->textEdit->document(), &QTextDocument::undoAvailable, m_ui->pbUndo, &QToolButton::setEnabled);
|
||||
connect(m_ui->textEdit->document(), &QTextDocument::redoAvailable, m_ui->pbRedo, &QToolButton::setEnabled);
|
||||
|
||||
m_ui->pbUndo->setEnabled(m_ui->textEdit->document()->isUndoAvailable());
|
||||
m_ui->pbRedo->setEnabled(m_ui->textEdit->document()->isRedoAvailable());
|
||||
m_ui->pbUndo->setEnabled(m_ui->textEdit->document()->isUndoAvailable());
|
||||
m_ui->pbRedo->setEnabled(m_ui->textEdit->document()->isRedoAvailable());
|
||||
|
||||
connect(QApplication::clipboard(), &QClipboard::dataChanged,
|
||||
this, &LtsTextEditor::slotClipboardDataChanged);
|
||||
connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &LtsTextEditor::slotClipboardDataChanged);
|
||||
|
||||
connect(m_ui->pbCut, &QToolButton::clicked, m_ui->textEdit, &QTextEdit::cut);
|
||||
connect(m_ui->pbCopy, &QToolButton::clicked, m_ui->textEdit, &QTextEdit::copy);
|
||||
connect(m_ui->pbPaste, &QToolButton::clicked, m_ui->textEdit, &QTextEdit::paste);
|
||||
|
||||
connect(m_ui->pbCut, &QToolButton::clicked,
|
||||
m_ui->textEdit, &QTextEdit::cut);
|
||||
connect(m_ui->pbCopy, &QToolButton::clicked,
|
||||
m_ui->textEdit, &QTextEdit::copy);
|
||||
connect(m_ui->pbPaste, &QToolButton::clicked,
|
||||
m_ui->textEdit, &QTextEdit::paste);
|
||||
connect(m_ui->pbUndo, &QToolButton::clicked, m_ui->textEdit, &QTextEdit::undo);
|
||||
connect(m_ui->pbRedo, &QToolButton::clicked, m_ui->textEdit, &QTextEdit::redo);
|
||||
|
||||
connect(m_ui->pbUndo, &QToolButton::clicked,
|
||||
m_ui->textEdit, &QTextEdit::undo);
|
||||
connect(m_ui->pbRedo, &QToolButton::clicked,
|
||||
m_ui->textEdit, &QTextEdit::redo);
|
||||
connect(m_ui->pbBold, &QToolButton::clicked, this, &LtsTextEditor::slotTextBold);
|
||||
connect(m_ui->pbItalic, &QToolButton::clicked, this, &LtsTextEditor::slotTextItalic);
|
||||
connect(m_ui->pbUnderline, &QToolButton::clicked, this, &LtsTextEditor::slotTextUnderline);
|
||||
|
||||
connect(m_ui->pbBold, &QToolButton::clicked,
|
||||
this, &LtsTextEditor::slotTextBold);
|
||||
connect(m_ui->pbItalic, &QToolButton::clicked,
|
||||
this, &LtsTextEditor::slotTextItalic);
|
||||
connect(m_ui->pbUnderline, &QToolButton::clicked,
|
||||
this, &LtsTextEditor::slotTextUnderline);
|
||||
connect(m_ui->pbTextColor, &QToolButton::clicked, this, &LtsTextEditor::slotTextColor);
|
||||
connect(m_ui->pbBackgroundColor, &QToolButton::clicked, this, &LtsTextEditor::slotBackgroundColor);
|
||||
|
||||
connect(m_ui->pbTextColor, &QToolButton::clicked,
|
||||
this, &LtsTextEditor::slotTextColor);
|
||||
connect(m_ui->pbBackgroundColor, &QToolButton::clicked,
|
||||
this, &LtsTextEditor::slotBackgroundColor);
|
||||
connect(m_ui->pbAlignLeft, &QToolButton::toggled, this, &LtsTextEditor::slotTextAlign);
|
||||
connect(m_ui->pbAlignCenter, &QToolButton::toggled, this, &LtsTextEditor::slotTextAlign);
|
||||
connect(m_ui->pbAlignRight, &QToolButton::toggled, this, &LtsTextEditor::slotTextAlign);
|
||||
connect(m_ui->pbAlignJustify, &QToolButton::toggled, this, &LtsTextEditor::slotTextAlign);
|
||||
|
||||
connect(m_ui->pbAlignLeft, &QToolButton::toggled,
|
||||
this, &LtsTextEditor::slotTextAlign);
|
||||
connect(m_ui->pbAlignCenter, &QToolButton::toggled,
|
||||
this, &LtsTextEditor::slotTextAlign);
|
||||
connect(m_ui->pbAlignRight, &QToolButton::toggled,
|
||||
this, &LtsTextEditor::slotTextAlign);
|
||||
connect(m_ui->pbAlignJustify, &QToolButton::toggled,
|
||||
this, &LtsTextEditor::slotTextAlign);
|
||||
QFont textFont(QStringLiteral("Sans Serif"));
|
||||
textFont.setStyleHint(QFont::SansSerif);
|
||||
m_ui->textEdit->setFont(textFont);
|
||||
slotFontChanged(m_ui->textEdit->font());
|
||||
slotTextColorChanged(m_ui->textEdit->textColor());
|
||||
slotAlignmentChanged();
|
||||
|
||||
slotBackgroundColorChanged(m_backgroundColor);
|
||||
|
||||
QFont textFont(QStringLiteral("Sans Serif"));
|
||||
textFont.setStyleHint(QFont::SansSerif);
|
||||
m_ui->textEdit->setFont(textFont);
|
||||
slotFontChanged(m_ui->textEdit->font());
|
||||
slotTextColorChanged(m_ui->textEdit->textColor());
|
||||
slotAlignmentChanged();
|
||||
connect(m_ui->cbFonts, &QComboBox::currentTextChanged, this, &LtsTextEditor::slotTextFamily);
|
||||
|
||||
slotBackgroundColorChanged(m_backgroundColor);
|
||||
const QList<int> standardSizes = QFontDatabase::standardSizes();
|
||||
for (int size : standardSizes)
|
||||
m_ui->cbFontSize->addItem(QString::number(size));
|
||||
m_ui->cbFontSize->setCurrentIndex(standardSizes.indexOf(QApplication::font().pointSize()));
|
||||
|
||||
connect(m_ui->cbFontSize, &QComboBox::currentTextChanged, this, &LtsTextEditor::slotTextSize);
|
||||
|
||||
connect(m_ui->cbFonts, QOverload<const QString &>::of(&QComboBox::activated),
|
||||
this, &LtsTextEditor::slotTextFamily);
|
||||
connect(m_ui->cbFontSize->lineEdit(), &QLineEdit::editingFinished, this,
|
||||
&LtsTextEditor::slotTextSizeEditingFinished);
|
||||
|
||||
const QList<int> standardSizes = QFontDatabase::standardSizes();
|
||||
for (int size : standardSizes)
|
||||
m_ui->cbFontSize->addItem(QString::number(size));
|
||||
m_ui->cbFontSize->setCurrentIndex(standardSizes.indexOf(QApplication::font().pointSize()));
|
||||
|
||||
connect(m_ui->cbFontSize, QOverload<const QString &>::of(&QComboBox::activated),
|
||||
this, &LtsTextEditor::slotTextSize);
|
||||
|
||||
connect(m_ui->cbFontSize->lineEdit(), &QLineEdit::editingFinished,
|
||||
this, &LtsTextEditor::slotTextSizeEditingFinished);
|
||||
|
||||
m_ui->textEdit->setFocus();
|
||||
m_ui->textEdit->setFocus();
|
||||
}
|
||||
|
||||
|
||||
LtsTextEditor::~LtsTextEditor()
|
||||
{
|
||||
delete m_ui;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
QTextEdit *LtsTextEditor::textEdit()
|
||||
QTextEdit* LtsTextEditor::textEdit()
|
||||
{
|
||||
return m_ui->textEdit;
|
||||
return m_ui->textEdit;
|
||||
}
|
||||
|
||||
QColor LtsTextEditor::backgroundColor() const
|
||||
{
|
||||
return m_backgroundColor;
|
||||
return m_backgroundColor;
|
||||
}
|
||||
|
||||
void LtsTextEditor::enableBackgroundColor(bool onOff)
|
||||
{
|
||||
m_ui->pbBackgroundColor->setVisible(onOff);
|
||||
m_ui->pbBackgroundColor->setVisible(onOff);
|
||||
}
|
||||
|
||||
void LtsTextEditor::setInitialBackgroundColor(const QColor &bgColor)
|
||||
void LtsTextEditor::setInitialBackgroundColor(const QColor& bgColor)
|
||||
{
|
||||
if (bgColor.isValid())
|
||||
m_backgroundColor = bgColor;
|
||||
slotBackgroundColorChanged(m_backgroundColor);
|
||||
if (bgColor.isValid())
|
||||
m_backgroundColor = bgColor;
|
||||
slotBackgroundColorChanged(m_backgroundColor);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotTextBold()
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString &f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
const qreal pointSize = (m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotTextUnderline()
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString &f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
const qreal pointSize = (m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotTextItalic()
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString &f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
const qreal pointSize = (m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotTextFamily(const QString &f)
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
|
||||
const qreal pointSize = (m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
}
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString& f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
const qreal pointSize =
|
||||
(m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotTextSize(const QString &p)
|
||||
void LtsTextEditor::slotTextUnderline()
|
||||
{
|
||||
qreal pointSize = p.toFloat();
|
||||
QTextCharFormat fmt;
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString& f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
const qreal pointSize =
|
||||
(m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
|
||||
if (p.toFloat() > 0)
|
||||
{
|
||||
QSignalBlocker signalBlocker(m_ui->cbFontSize->lineEdit());
|
||||
m_ui->cbFontSize->clearFocus();
|
||||
void LtsTextEditor::slotTextItalic()
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString& f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
const qreal pointSize =
|
||||
(m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
|
||||
void LtsTextEditor::slotTextFamily(const QString& f)
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString &f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
|
||||
const qreal pointSize =
|
||||
(m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
}
|
||||
fmt.setFontPointSize(pointSize);
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
}
|
||||
|
||||
void LtsTextEditor::slotTextSize(const QString& p)
|
||||
{
|
||||
qreal pointSize = p.toFloat();
|
||||
|
||||
if (p.toFloat() > 0)
|
||||
{
|
||||
QSignalBlocker signalBlocker(m_ui->cbFontSize->lineEdit());
|
||||
m_ui->cbFontSize->clearFocus();
|
||||
|
||||
QTextCharFormat fmt;
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
const QString& f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
fmt.setForeground(m_foregroundColor);
|
||||
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
}
|
||||
fmt.setFontPointSize(pointSize);
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
}
|
||||
}
|
||||
|
||||
void LtsTextEditor::slotTextSizeEditingFinished()
|
||||
{
|
||||
qreal pointSize = m_ui->cbFontSize->currentText().toFloat();
|
||||
qreal pointSize = m_ui->cbFontSize->currentText().toFloat();
|
||||
|
||||
if (pointSize > 0)
|
||||
{
|
||||
QTextCharFormat textCharFormat;
|
||||
if (pointSize > 0)
|
||||
{
|
||||
QTextCharFormat textCharFormat;
|
||||
|
||||
textCharFormat.setFontPointSize(pointSize);
|
||||
textCharFormat.setFontPointSize(pointSize);
|
||||
|
||||
QTextCursor cursor = m_ui->textEdit->textCursor();
|
||||
QTextCursor cursor = m_ui->textEdit->textCursor();
|
||||
|
||||
if (cursor.charFormat().font().pointSizeF() == pointSize)
|
||||
return;
|
||||
if (cursor.charFormat().font().pointSizeF() == pointSize)
|
||||
return;
|
||||
|
||||
if (!cursor.hasSelection())
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
if (!cursor.hasSelection())
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
|
||||
cursor.mergeCharFormat(textCharFormat);
|
||||
}
|
||||
cursor.mergeCharFormat(textCharFormat);
|
||||
}
|
||||
}
|
||||
|
||||
void LtsTextEditor::slotTextColor()
|
||||
{
|
||||
QColor col = QColorDialog::getColor(m_ui->textEdit->textColor(), this);
|
||||
if (!col.isValid())
|
||||
return;
|
||||
QColor col = QColorDialog::getColor(m_ui->textEdit->textColor(), this);
|
||||
if (!col.isValid())
|
||||
return;
|
||||
|
||||
QTextCharFormat fmt;
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
QTextCharFormat fmt;
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
{
|
||||
fmt.setFontItalic(m_ui->pbItalic->isChecked());
|
||||
fmt.setFontUnderline(m_ui->pbUnderline->isChecked());
|
||||
fmt.setFontWeight(m_ui->pbBold->isChecked() ? QFont::Bold : QFont::Normal);
|
||||
|
||||
const QString &f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
const qreal pointSize = (m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
fmt.setForeground(col);
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
slotTextColorChanged(col);
|
||||
const QString& f = m_ui->cbFonts->currentText();
|
||||
fmt.setFontFamily(f);
|
||||
fmt.setFontFamilies({f});
|
||||
const qreal pointSize =
|
||||
(m_ui->cbFontSize->currentText().toFloat() > 0 ? m_ui->cbFontSize->currentText().toFloat() : 11);
|
||||
fmt.setFontPointSize(pointSize);
|
||||
}
|
||||
fmt.setForeground(col);
|
||||
slotMergeFormatOnWordOrSelection(fmt);
|
||||
slotTextColorChanged(col);
|
||||
}
|
||||
|
||||
void LtsTextEditor::slotBackgroundColor()
|
||||
{
|
||||
QColor col = QColorDialog::getColor(m_backgroundColor.isValid() ? m_backgroundColor : Qt::white, this);
|
||||
if (!col.isValid())
|
||||
return;
|
||||
QColor col = QColorDialog::getColor(m_backgroundColor.isValid() ? m_backgroundColor : Qt::white, this);
|
||||
if (!col.isValid())
|
||||
return;
|
||||
|
||||
m_backgroundColor = col;
|
||||
slotBackgroundColorChanged(m_backgroundColor);
|
||||
emit backgroundColorChanged(m_backgroundColor);
|
||||
m_backgroundColor = col;
|
||||
slotBackgroundColorChanged(m_backgroundColor);
|
||||
emit backgroundColorChanged(m_backgroundColor);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotCurrentCharFormatChanged(const QTextCharFormat &format)
|
||||
void LtsTextEditor::slotCurrentCharFormatChanged(const QTextCharFormat& format)
|
||||
{
|
||||
slotFontChanged(format.font());
|
||||
slotTextColorChanged(format.foreground().color());
|
||||
slotFontChanged(format.font());
|
||||
slotTextColorChanged(format.foreground().color());
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotFontChanged(const QFont &f)
|
||||
void LtsTextEditor::slotFontChanged(const QFont& f)
|
||||
{
|
||||
m_ui->cbFonts->setCurrentIndex(m_ui->cbFonts->findText(f.family()));
|
||||
m_ui->cbFonts->setCurrentIndex(m_ui->cbFonts->findText(f.family()));
|
||||
|
||||
QSignalBlocker comboBoxsignalBlocker(m_ui->cbFontSize);
|
||||
QSignalBlocker lineEditSignalBlocker(m_ui->cbFontSize->lineEdit());
|
||||
QString fontSizeString = QString::number(f.pointSize());
|
||||
int32_t fontSizeIndex = m_ui->cbFontSize->findText(fontSizeString);
|
||||
QSignalBlocker comboBoxsignalBlocker(m_ui->cbFontSize);
|
||||
QSignalBlocker lineEditSignalBlocker(m_ui->cbFontSize->lineEdit());
|
||||
QString fontSizeString = QString::number(f.pointSize());
|
||||
int32_t fontSizeIndex = m_ui->cbFontSize->findText(fontSizeString);
|
||||
|
||||
if (fontSizeIndex >= 0)
|
||||
m_ui->cbFontSize->setCurrentIndex(fontSizeIndex);
|
||||
else if (m_ui->cbFontSize->currentText() != fontSizeString)
|
||||
m_ui->cbFontSize->setCurrentText(fontSizeString);
|
||||
if (fontSizeIndex >= 0)
|
||||
m_ui->cbFontSize->setCurrentIndex(fontSizeIndex);
|
||||
else if (m_ui->cbFontSize->currentText() != fontSizeString)
|
||||
m_ui->cbFontSize->setCurrentText(fontSizeString);
|
||||
|
||||
m_ui->pbBold->setChecked(f.bold());
|
||||
m_ui->pbItalic->setChecked(f.italic());
|
||||
m_ui->pbUnderline->setChecked(f.underline());
|
||||
m_ui->pbBold->setChecked(f.bold());
|
||||
m_ui->pbItalic->setChecked(f.italic());
|
||||
m_ui->pbUnderline->setChecked(f.underline());
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotMergeFormatOnWordOrSelection(const QTextCharFormat &format)
|
||||
void LtsTextEditor::slotMergeFormatOnWordOrSelection(const QTextCharFormat& format)
|
||||
{
|
||||
QTextCursor cursor = m_ui->textEdit->textCursor();
|
||||
if (!cursor.hasSelection())
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
QTextCursor cursor = m_ui->textEdit->textCursor();
|
||||
if (!cursor.hasSelection())
|
||||
cursor.select(QTextCursor::WordUnderCursor);
|
||||
|
||||
cursor.mergeCharFormat(format);
|
||||
|
||||
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
m_ui->textEdit->setTextCursor(cursor);
|
||||
cursor.mergeCharFormat(format);
|
||||
|
||||
if (m_ui->textEdit->document()->isEmpty())
|
||||
m_ui->textEdit->setTextCursor(cursor);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotTextColorChanged(const QColor &c)
|
||||
void LtsTextEditor::slotTextColorChanged(const QColor& c)
|
||||
{
|
||||
QPixmap pix(32, 32);
|
||||
pix.fill(c);
|
||||
m_ui->pbTextColor->setIcon(pix);
|
||||
m_foregroundColor = c;
|
||||
QPixmap pix(32, 32);
|
||||
pix.fill(c);
|
||||
m_ui->pbTextColor->setIcon(pix);
|
||||
m_foregroundColor = c;
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotBackgroundColorChanged(const QColor &bgColor)
|
||||
void LtsTextEditor::slotBackgroundColorChanged(const QColor& bgColor)
|
||||
{
|
||||
QPixmap pix(32, 32);
|
||||
pix.fill(bgColor);
|
||||
m_ui->pbBackgroundColor->setIcon(pix);
|
||||
QPixmap pix(32, 32);
|
||||
pix.fill(bgColor);
|
||||
m_ui->pbBackgroundColor->setIcon(pix);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotTextAlign()
|
||||
{
|
||||
QToolButton *b = qobject_cast<QToolButton *>(sender());
|
||||
QToolButton* b = qobject_cast<QToolButton*>(sender());
|
||||
|
||||
if (b == nullptr)
|
||||
return;
|
||||
if (b == nullptr)
|
||||
return;
|
||||
|
||||
if (b == m_ui->pbAlignLeft)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignLeft | Qt::AlignAbsolute);
|
||||
else if (b == m_ui->pbAlignCenter)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignHCenter);
|
||||
else if (b == m_ui->pbAlignRight)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignRight | Qt::AlignAbsolute);
|
||||
else if (b == m_ui->pbAlignJustify)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignJustify);
|
||||
if (b == m_ui->pbAlignLeft)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignLeft | Qt::AlignAbsolute);
|
||||
else if (b == m_ui->pbAlignCenter)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignHCenter);
|
||||
else if (b == m_ui->pbAlignRight)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignRight | Qt::AlignAbsolute);
|
||||
else if (b == m_ui->pbAlignJustify)
|
||||
m_ui->textEdit->setAlignment(Qt::AlignJustify);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotAlignmentChanged()
|
||||
{
|
||||
auto a = m_ui->textEdit->alignment();
|
||||
auto a = m_ui->textEdit->alignment();
|
||||
|
||||
if (a & Qt::AlignLeft)
|
||||
m_ui->pbAlignLeft->setChecked(true);
|
||||
if (a & Qt::AlignHCenter)
|
||||
m_ui->pbAlignCenter->setChecked(true);
|
||||
if (a & Qt::AlignRight)
|
||||
m_ui->pbAlignRight->setChecked(true);
|
||||
if (a & Qt::AlignJustify)
|
||||
m_ui->pbAlignJustify->setChecked(true);
|
||||
if (a & Qt::AlignLeft)
|
||||
m_ui->pbAlignLeft->setChecked(true);
|
||||
if (a & Qt::AlignHCenter)
|
||||
m_ui->pbAlignCenter->setChecked(true);
|
||||
if (a & Qt::AlignRight)
|
||||
m_ui->pbAlignRight->setChecked(true);
|
||||
if (a & Qt::AlignJustify)
|
||||
m_ui->pbAlignJustify->setChecked(true);
|
||||
}
|
||||
|
||||
|
||||
void LtsTextEditor::slotClipboardDataChanged()
|
||||
{
|
||||
if (const QMimeData *md = QApplication::clipboard()->mimeData())
|
||||
m_ui->pbPaste->setEnabled(md->hasText());
|
||||
if (const QMimeData* md = QApplication::clipboard()->mimeData())
|
||||
m_ui->pbPaste->setEnabled(md->hasText());
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+677
-657
File diff suppressed because it is too large.
Load diff
Executable → Regular
+13
-17
@@ -1,31 +1,27 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_tool_bar.h"
|
||||
|
||||
using namespace LtsWidgets;
|
||||
|
||||
LtsToolBar::LtsToolBar(QWidget *parent)
|
||||
: QToolBar(parent)
|
||||
LtsToolBar::LtsToolBar(QWidget* parent) : QToolBar(parent)
|
||||
{
|
||||
setMaximumHeight(1);
|
||||
setMinimumHeight(1);
|
||||
setMaximumHeight(1);
|
||||
setMinimumHeight(1);
|
||||
}
|
||||
|
||||
LtsToolBar::~LtsToolBar()
|
||||
LtsToolBar::~LtsToolBar() {}
|
||||
|
||||
void LtsToolBar::enterEvent(QEnterEvent* e)
|
||||
{
|
||||
setMaximumHeight(50);
|
||||
setMinimumHeight(50);
|
||||
QToolBar::enterEvent(e);
|
||||
}
|
||||
|
||||
void LtsToolBar::enterEvent(QEvent *e)
|
||||
void LtsToolBar::leaveEvent(QEvent* e)
|
||||
{
|
||||
setMaximumHeight(50);
|
||||
setMinimumHeight(50);
|
||||
QToolBar::enterEvent(e);
|
||||
}
|
||||
|
||||
void LtsToolBar::leaveEvent(QEvent *e)
|
||||
{
|
||||
setMaximumHeight(1);
|
||||
setMinimumHeight(1);
|
||||
QToolBar::leaveEvent(e);
|
||||
setMaximumHeight(1);
|
||||
setMinimumHeight(1);
|
||||
QToolBar::leaveEvent(e);
|
||||
}
|
||||
Executable → Regular
+11
-14
@@ -1,28 +1,25 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
|
||||
#include <QToolBar>
|
||||
#include "ltswidgets_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QToolBar>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
class LTSWIDGETS_EXPORT LtsToolBar : public QToolBar
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LtsToolBar(QWidget *parent = nullptr);
|
||||
~LtsToolBar();
|
||||
|
||||
protected:
|
||||
void enterEvent(QEvent *e) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LtsToolBar(QWidget* parent = nullptr);
|
||||
~LtsToolBar();
|
||||
|
||||
protected:
|
||||
void enterEvent(QEnterEvent* e) override;
|
||||
void leaveEvent(QEvent* e) override;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace LtsWidgets
|
||||
Executable → Regular
+246
-286
@@ -1,385 +1,345 @@
|
||||
|
||||
|
||||
|
||||
#include "lts_tool_bar_area.h"
|
||||
#include <utility>
|
||||
#include "ui_lts_tool_bar_area.h"
|
||||
|
||||
#include "lts_drag_icon.h"
|
||||
#include "ui_lts_tool_bar_area.h"
|
||||
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <QDebug>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QDropEvent>
|
||||
#include <QLabel>
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include <QShortcut>
|
||||
#include <QPointer>
|
||||
|
||||
#include <QShortcut>
|
||||
#include <QVariant>
|
||||
#include <utility>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
|
||||
|
||||
|
||||
void ShortCut::clear()
|
||||
{
|
||||
name.clear();
|
||||
identifier.clear();
|
||||
icon = nullptr;
|
||||
shortcut->disconnect(icon);
|
||||
name.clear();
|
||||
identifier.clear();
|
||||
icon = nullptr;
|
||||
shortcut->disconnect(icon);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
LtsToolBarArea::LtsToolBarArea(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_dummyLabel(nullptr)
|
||||
, m_ui(new Ui::LtsToolBarArea)
|
||||
LtsToolBarArea::LtsToolBarArea(QWidget* parent) : QWidget(parent), m_dummyLabel(nullptr), m_ui(new Ui::LtsToolBarArea)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->setupUi(this);
|
||||
|
||||
setAcceptDrops(true);
|
||||
clearToolBarArea();
|
||||
setAcceptDrops(true);
|
||||
clearToolBarArea();
|
||||
|
||||
|
||||
for(int i=Qt::Key_F5; i<=Qt::Key_F12; ++i)
|
||||
{
|
||||
ShortCut sc(this);
|
||||
sc.shortcut->setKey(QKeySequence(i));
|
||||
sc.key = i;
|
||||
m_functionKeys.insert(i, sc);
|
||||
}
|
||||
for (int i = Qt::Key_F5; i <= Qt::Key_F12; ++i)
|
||||
{
|
||||
ShortCut sc(this);
|
||||
sc.shortcut->setKey(QKeySequence(i));
|
||||
sc.key = i;
|
||||
m_functionKeys.insert(i, sc);
|
||||
}
|
||||
}
|
||||
|
||||
LtsToolBarArea::~LtsToolBarArea()
|
||||
{
|
||||
delete m_ui;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void LtsToolBarArea::addMenuEntry(LtsDragIcon *entry, LtsDragIcon *after)
|
||||
void LtsToolBarArea::addMenuEntry(LtsDragIcon* entry, LtsDragIcon* after)
|
||||
{
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
if (m_foreignButtonMap.contains(entry))
|
||||
return;
|
||||
|
||||
delete m_dummyLabel;
|
||||
m_dummyLabel = nullptr;
|
||||
|
||||
bool isInternalMove = false;
|
||||
LtsDragIcon *foreignDragIcon = entry;
|
||||
|
||||
for (int i = 0; i < m_buttonMap.size(); ++i)
|
||||
{
|
||||
if (m_buttonMap.at(i) == entry)
|
||||
{
|
||||
isInternalMove = true;
|
||||
|
||||
if (after == nullptr)
|
||||
if (!entry)
|
||||
return;
|
||||
m_buttonMap.removeAt(i);
|
||||
foreignDragIcon = m_foreignButtonMap.at(i);
|
||||
m_foreignButtonMap.removeAt(i);
|
||||
m_ui->layToolbar->removeWidget(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int index = m_buttonMap.size();
|
||||
for(int i = 0; i < m_buttonMap.size(); ++i)
|
||||
{
|
||||
if (m_buttonMap.at(i) == after ||
|
||||
m_foreignButtonMap.at(i) == after)
|
||||
if (m_foreignButtonMap.contains(entry))
|
||||
return;
|
||||
|
||||
delete m_dummyLabel;
|
||||
m_dummyLabel = nullptr;
|
||||
|
||||
bool isInternalMove = false;
|
||||
LtsDragIcon* foreignDragIcon = entry;
|
||||
|
||||
for (int i = 0; i < m_buttonMap.size(); ++i)
|
||||
{
|
||||
index = i + 1;
|
||||
break;
|
||||
if (m_buttonMap.at(i) == entry)
|
||||
{
|
||||
isInternalMove = true;
|
||||
|
||||
if (after == nullptr)
|
||||
return;
|
||||
m_buttonMap.removeAt(i);
|
||||
foreignDragIcon = m_foreignButtonMap.at(i);
|
||||
m_foreignButtonMap.removeAt(i);
|
||||
m_ui->layToolbar->removeWidget(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LtsDragIcon *newAction = entry;
|
||||
int index = m_buttonMap.size();
|
||||
for (int i = 0; i < m_buttonMap.size(); ++i)
|
||||
{
|
||||
if (m_buttonMap.at(i) == after || m_foreignButtonMap.at(i) == after)
|
||||
{
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isInternalMove)
|
||||
{
|
||||
newAction = new LtsDragIcon(this);
|
||||
newAction->setIcon(entry->icon());
|
||||
newAction->setText(entry->text());
|
||||
newAction->setContext(entry->context());
|
||||
if (!entry->toolTip().isEmpty())
|
||||
newAction->setToolTip(entry->toolTip());
|
||||
newAction->setIconSize(ButtonSize::eDefault);
|
||||
newAction->setButtonStyle(ButtonStyle::eIconOnly);
|
||||
newAction->setIdentifier(entry->identifier());
|
||||
LtsDragIcon* newAction = entry;
|
||||
|
||||
connect(newAction, &LtsDragIcon::clicked, entry, &LtsDragIcon::clicked);
|
||||
connect(entry, &LtsDragIcon::destroyed, newAction,
|
||||
[this, newAction]() { m_buttonMap.removeAll(newAction); newAction->deleteLater(); });
|
||||
newAction->setVisible(!entry->text().isEmpty());
|
||||
}
|
||||
newAction->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(newAction, &LtsDragIcon::customContextMenuRequested,
|
||||
this, &LtsToolBarArea::showContextMenu);
|
||||
if (!isInternalMove)
|
||||
{
|
||||
newAction = new LtsDragIcon(this);
|
||||
newAction->setIcon(entry->icon());
|
||||
newAction->setText(entry->text());
|
||||
newAction->setContext(entry->context());
|
||||
if (!entry->toolTip().isEmpty())
|
||||
newAction->setToolTip(entry->toolTip());
|
||||
newAction->setIconSize(ButtonSize::eDefault);
|
||||
newAction->setButtonStyle(ButtonStyle::eIconOnly);
|
||||
newAction->setIdentifier(entry->identifier());
|
||||
|
||||
m_foreignButtonMap.insert(index, foreignDragIcon);
|
||||
m_buttonMap.insert(index, newAction);
|
||||
connect(newAction, &LtsDragIcon::clicked, entry, &LtsDragIcon::clicked);
|
||||
connect(entry, &LtsDragIcon::destroyed, newAction, [this, newAction]() {
|
||||
m_buttonMap.removeAll(newAction);
|
||||
newAction->deleteLater();
|
||||
});
|
||||
newAction->setVisible(!entry->text().isEmpty());
|
||||
}
|
||||
newAction->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(newAction, &LtsDragIcon::customContextMenuRequested, this, &LtsToolBarArea::showContextMenu);
|
||||
|
||||
connect(foreignDragIcon, &LtsDragIcon::enabledChanged, newAction, &LtsDragIcon::setEnabled);
|
||||
m_foreignButtonMap.insert(index, foreignDragIcon);
|
||||
m_buttonMap.insert(index, newAction);
|
||||
|
||||
|
||||
m_ui->layToolbar->insertWidget(index + 1, newAction);
|
||||
saveSettings();
|
||||
connect(foreignDragIcon, &LtsDragIcon::enabledChanged, newAction, &LtsDragIcon::setEnabled);
|
||||
|
||||
m_ui->layToolbar->insertWidget(index + 1, newAction);
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
void LtsToolBarArea::clearToolBarArea()
|
||||
{
|
||||
qDeleteAll(m_buttonMap);
|
||||
m_buttonMap.clear();
|
||||
m_foreignButtonMap.clear();
|
||||
for(ShortCut &item : m_functionKeys)
|
||||
item.clear();
|
||||
qDeleteAll(m_buttonMap);
|
||||
m_buttonMap.clear();
|
||||
m_foreignButtonMap.clear();
|
||||
for (ShortCut& item : m_functionKeys)
|
||||
item.clear();
|
||||
|
||||
delete m_dummyLabel;
|
||||
|
||||
m_dummyLabel = new QLabel(tr("Drop menu entry here"), this);
|
||||
m_ui->layToolbar->addWidget(m_dummyLabel);
|
||||
delete m_dummyLabel;
|
||||
|
||||
m_dummyLabel = new QLabel(tr("Drop menu entry here"), this);
|
||||
m_ui->layToolbar->addWidget(m_dummyLabel);
|
||||
}
|
||||
|
||||
void LtsToolBarArea::setMenuEntries(const QVector<LtsDragIcon *> &actions)
|
||||
void LtsToolBarArea::setMenuEntries(const QVector<LtsDragIcon*>& actions)
|
||||
{
|
||||
clearToolBarArea();
|
||||
clearToolBarArea();
|
||||
|
||||
for (LtsDragIcon* ico : actions)
|
||||
addMenuEntry(ico);
|
||||
for (LtsDragIcon* ico : actions)
|
||||
addMenuEntry(ico);
|
||||
}
|
||||
|
||||
QStringList LtsToolBarArea::menuEntries() const
|
||||
{
|
||||
QStringList ret;
|
||||
ret.reserve(m_foreignButtonMap.size());
|
||||
for (LtsDragIcon *dragIcon : m_foreignButtonMap)
|
||||
ret << dragIcon->identifier();
|
||||
QStringList ret;
|
||||
ret.reserve(m_foreignButtonMap.size());
|
||||
for (LtsDragIcon* dragIcon : m_foreignButtonMap)
|
||||
ret << dragIcon->identifier();
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LtsToolBarArea::dragEnterEvent(QDragEnterEvent *event)
|
||||
void LtsToolBarArea::dragEnterEvent(QDragEnterEvent* event)
|
||||
{
|
||||
LtsDragIcon *source =
|
||||
qobject_cast<LtsDragIcon *>(event->source());
|
||||
if (source)
|
||||
{
|
||||
if (!m_foreignButtonMap.contains(source))
|
||||
LtsDragIcon* source = qobject_cast<LtsDragIcon*>(event->source());
|
||||
if (source)
|
||||
{
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
if (!m_foreignButtonMap.contains(source))
|
||||
{
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LtsToolBarArea::dropEvent(QDropEvent *event)
|
||||
void LtsToolBarArea::dropEvent(QDropEvent* event)
|
||||
{
|
||||
LtsDragIcon *source = qobject_cast<LtsDragIcon *>(event->source());
|
||||
|
||||
LtsDragIcon *after = nullptr;
|
||||
QWidget *w = childAt(event->pos());
|
||||
while (w)
|
||||
{
|
||||
after = qobject_cast<LtsDragIcon *>(w);
|
||||
if (after)
|
||||
break;
|
||||
w = w->parentWidget();
|
||||
}
|
||||
LtsDragIcon* source = qobject_cast<LtsDragIcon*>(event->source());
|
||||
|
||||
addMenuEntry(source, after);
|
||||
LtsDragIcon* after = nullptr;
|
||||
QWidget* w = childAt(event->pos());
|
||||
while (w)
|
||||
{
|
||||
after = qobject_cast<LtsDragIcon*>(w);
|
||||
if (after)
|
||||
break;
|
||||
w = w->parentWidget();
|
||||
}
|
||||
|
||||
addMenuEntry(source, after);
|
||||
}
|
||||
|
||||
QMenu *LtsToolBarArea::functionKeyMenu(QWidget *parent)
|
||||
QMenu* LtsToolBarArea::functionKeyMenu(QWidget* parent)
|
||||
{
|
||||
QMenu* menu = new QMenu(parent);
|
||||
menu->setTitle(tr("Function Key"));
|
||||
QAction *act;
|
||||
for(auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
ShortCut &shorty = val.value();
|
||||
act = menu->addAction(QStringLiteral("%1%2").arg(shorty.keyName(), !shorty.name.isEmpty() ? QStringLiteral(" - %1").arg(shorty.name) : QString()));
|
||||
act->setData(shorty.shortcut->key()[0]);
|
||||
QMenu* menu = new QMenu(parent);
|
||||
menu->setTitle(tr("Function Key"));
|
||||
QAction* act;
|
||||
for (auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
ShortCut& shorty = val.value();
|
||||
act = menu->addAction(QStringLiteral("%1%2").arg(
|
||||
shorty.keyName(), !shorty.name.isEmpty() ? QStringLiteral(" - %1").arg(shorty.name) : QString()));
|
||||
act->setData(QVariant::fromValue(shorty.shortcut->key()[0]));
|
||||
connect(act, &QAction::triggered, this, &LtsToolBarArea::functionKeyMenuTriggered);
|
||||
}
|
||||
menu->addSeparator();
|
||||
act = menu->addAction(tr("Remove Function Key"));
|
||||
act->setData(-1);
|
||||
connect(act, &QAction::triggered, this, &LtsToolBarArea::functionKeyMenuTriggered);
|
||||
}
|
||||
menu->addSeparator();
|
||||
act = menu->addAction(tr("Remove Function Key"));
|
||||
act->setData(-1);
|
||||
connect(act, &QAction::triggered, this, &LtsToolBarArea::functionKeyMenuTriggered);
|
||||
return menu;
|
||||
return menu;
|
||||
}
|
||||
|
||||
void LtsToolBarArea::functionKeyMenuTriggered()
|
||||
{
|
||||
QAction* act = qobject_cast<QAction*>(sender());
|
||||
if (!act)
|
||||
return;
|
||||
int fkey = act->data().toInt();
|
||||
QAction* act = qobject_cast<QAction*>(sender());
|
||||
if (!act)
|
||||
return;
|
||||
int fkey = act->data().toInt();
|
||||
|
||||
if (fkey == -1)
|
||||
removeFunctionKey(m_currentIdentifierForContextMenue);
|
||||
else if (fkey > 0)
|
||||
setFunctionKey(fkey, m_currentIdentifierForContextMenue);
|
||||
if (fkey == -1)
|
||||
removeFunctionKey(m_currentIdentifierForContextMenue);
|
||||
else if (fkey > 0)
|
||||
setFunctionKey(fkey, m_currentIdentifierForContextMenue);
|
||||
}
|
||||
|
||||
|
||||
bool LtsToolBarArea::removeFunctionKey(const QString &action)
|
||||
bool LtsToolBarArea::removeFunctionKey(const QString& action)
|
||||
{
|
||||
if (action.isEmpty())
|
||||
if (action.isEmpty())
|
||||
return true;
|
||||
|
||||
for (auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
ShortCut& itShortcut = val.value();
|
||||
if (itShortcut.identifier == action)
|
||||
{
|
||||
itShortcut.icon->removeModification();
|
||||
itShortcut.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
saveSettings();
|
||||
return true;
|
||||
|
||||
|
||||
for(auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
ShortCut &itShortcut = val.value();
|
||||
if (itShortcut.identifier == action)
|
||||
{
|
||||
itShortcut.icon->removeModification();
|
||||
itShortcut.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
saveSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LtsToolBarArea::setFunctionKey(int fkey, const QString &action)
|
||||
bool LtsToolBarArea::setFunctionKey(int fkey, const QString& action)
|
||||
{
|
||||
|
||||
if (fkey < Qt::Key_F5 || fkey > Qt::Key_F12)
|
||||
return false;
|
||||
|
||||
|
||||
LtsDragIcon *icon = nullptr;
|
||||
for (LtsDragIcon *ic : std::as_const(m_buttonMap))
|
||||
{
|
||||
if (ic->identifier() == action)
|
||||
if (fkey < Qt::Key_F5 || fkey > Qt::Key_F12)
|
||||
return false;
|
||||
|
||||
LtsDragIcon* icon = nullptr;
|
||||
for (LtsDragIcon* ic : std::as_const(m_buttonMap))
|
||||
{
|
||||
icon = ic;
|
||||
break;
|
||||
if (ic->identifier() == action)
|
||||
{
|
||||
icon = ic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!icon)
|
||||
return false;
|
||||
if (!icon)
|
||||
return false;
|
||||
|
||||
|
||||
ShortCut &shorty = m_functionKeys[fkey];
|
||||
ShortCut& shorty = m_functionKeys[fkey];
|
||||
|
||||
|
||||
for (LtsDragIcon *ic : std::as_const(m_buttonMap))
|
||||
if (ic->identifier() == shorty.identifier)
|
||||
ic->removeModification();
|
||||
for (LtsDragIcon* ic : std::as_const(m_buttonMap))
|
||||
if (ic->identifier() == shorty.identifier)
|
||||
ic->removeModification();
|
||||
|
||||
|
||||
for(auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
ShortCut &itShortcut = val.value();
|
||||
if (itShortcut.identifier == action)
|
||||
for (auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
itShortcut.clear();
|
||||
break;
|
||||
ShortCut& itShortcut = val.value();
|
||||
if (itShortcut.identifier == action)
|
||||
{
|
||||
itShortcut.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
shorty.clear();
|
||||
shorty.identifier = icon->identifier();
|
||||
shorty.name = icon->text();
|
||||
shorty.icon = icon;
|
||||
shorty.icon->setModification(shorty.keyName());
|
||||
connect(shorty.shortcut, &QShortcut::activated, icon, &LtsDragIcon::clicked);
|
||||
saveSettings();
|
||||
return true;
|
||||
shorty.clear();
|
||||
shorty.identifier = icon->identifier();
|
||||
shorty.name = icon->text();
|
||||
shorty.icon = icon;
|
||||
shorty.icon->setModification(shorty.keyName());
|
||||
connect(shorty.shortcut, &QShortcut::activated, icon, &LtsDragIcon::clicked);
|
||||
saveSettings();
|
||||
return true;
|
||||
}
|
||||
|
||||
QMap<int, QString> LtsToolBarArea::functionKeys() const
|
||||
{
|
||||
QMap<int, QString> retVal;
|
||||
for(auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
const ShortCut &itShortcut = val.value();
|
||||
if (!itShortcut.identifier.isEmpty())
|
||||
retVal[itShortcut.key] = itShortcut.identifier;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LtsToolBarArea::removeMenuAction(LtsDragIcon *icon)
|
||||
{
|
||||
|
||||
for(auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
ShortCut &itShortcut = val.value();
|
||||
if (itShortcut.identifier == icon->identifier())
|
||||
itShortcut.clear();
|
||||
}
|
||||
for (LtsDragIcon *ic : std::as_const(m_foreignButtonMap))
|
||||
{
|
||||
if(ic->identifier() == icon->identifier())
|
||||
QMap<int, QString> retVal;
|
||||
for (auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
m_foreignButtonMap.removeAll(ic);
|
||||
break;
|
||||
const ShortCut& itShortcut = val.value();
|
||||
if (!itShortcut.identifier.isEmpty())
|
||||
retVal[itShortcut.key] = itShortcut.identifier;
|
||||
}
|
||||
}
|
||||
m_buttonMap.removeAll(icon);
|
||||
m_ui->layToolbar->removeWidget(icon);
|
||||
delete icon;
|
||||
saveSettings();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LtsToolBarArea::showContextMenu(const QPoint &pos)
|
||||
{
|
||||
QPointer<LtsDragIcon> icon = qobject_cast<LtsDragIcon*>(sender());
|
||||
if (!icon)
|
||||
return;
|
||||
|
||||
const QPoint &globalPos = icon->mapToGlobal(pos);
|
||||
|
||||
QMenu *contextMenu = new QMenu(this);
|
||||
contextMenu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
|
||||
m_currentIdentifierForContextMenue = icon->identifier();
|
||||
connect(contextMenu, &QObject::destroyed, this, [this](){
|
||||
|
||||
m_currentIdentifierForContextMenue.clear();
|
||||
});
|
||||
|
||||
|
||||
QAction *delAction = contextMenu->addAction(tr("Remove"));
|
||||
connect(delAction, &QAction::triggered, this, [this, icon] () {
|
||||
if (icon)
|
||||
removeMenuAction(icon);
|
||||
});
|
||||
|
||||
|
||||
QMenu *fkeyMenu = functionKeyMenu(contextMenu);
|
||||
contextMenu->addMenu(fkeyMenu);
|
||||
|
||||
contextMenu->popup(globalPos);
|
||||
}
|
||||
|
||||
|
||||
void LtsToolBarArea::saveSettings()
|
||||
void LtsToolBarArea::removeMenuAction(LtsDragIcon* icon)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for (auto val = m_functionKeys.begin(); val != m_functionKeys.end(); ++val)
|
||||
{
|
||||
ShortCut& itShortcut = val.value();
|
||||
if (itShortcut.identifier == icon->identifier())
|
||||
itShortcut.clear();
|
||||
}
|
||||
for (LtsDragIcon* ic : std::as_const(m_foreignButtonMap))
|
||||
{
|
||||
if (ic->identifier() == icon->identifier())
|
||||
{
|
||||
m_foreignButtonMap.removeAll(ic);
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_buttonMap.removeAll(icon);
|
||||
m_ui->layToolbar->removeWidget(icon);
|
||||
delete icon;
|
||||
saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void LtsToolBarArea::showContextMenu(const QPoint& pos)
|
||||
{
|
||||
QPointer<LtsDragIcon> icon = qobject_cast<LtsDragIcon*>(sender());
|
||||
if (!icon)
|
||||
return;
|
||||
|
||||
const QPoint& globalPos = icon->mapToGlobal(pos);
|
||||
|
||||
QMenu* contextMenu = new QMenu(this);
|
||||
contextMenu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
m_currentIdentifierForContextMenue = icon->identifier();
|
||||
connect(contextMenu, &QObject::destroyed, this, [this]() { m_currentIdentifierForContextMenue.clear(); });
|
||||
|
||||
QAction* delAction = contextMenu->addAction(tr("Remove"));
|
||||
connect(delAction, &QAction::triggered, this, [this, icon]() {
|
||||
if (icon)
|
||||
removeMenuAction(icon);
|
||||
});
|
||||
|
||||
QMenu* fkeyMenu = functionKeyMenu(contextMenu);
|
||||
contextMenu->addMenu(fkeyMenu);
|
||||
|
||||
contextMenu->popup(globalPos);
|
||||
}
|
||||
|
||||
void LtsToolBarArea::saveSettings() {}
|
||||
} // namespace LtsWidgets
|
||||
@@ -13,8 +13,10 @@ ADD_SUBDIRECTORY(Battery)
|
||||
ADD_SUBDIRECTORY(Buildings)
|
||||
ADD_SUBDIRECTORY(BuildingViewer) # uses ZW connections (uses sql, ace, ..)
|
||||
ADD_SUBDIRECTORY(CentralEffectSimulation)
|
||||
ADD_SUBDIRECTORY(CodificationManagement)
|
||||
ADD_SUBDIRECTORY(CodificationManagement/Test)
|
||||
IF(BUILD_CODIFICATION)
|
||||
ADD_SUBDIRECTORY(CodificationManagement)
|
||||
ADD_SUBDIRECTORY(CodificationManagement/Test)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(CollateralDamageSimulation)
|
||||
ADD_SUBDIRECTORY(EffectManagement)
|
||||
ADD_SUBDIRECTORY(EffectShowClient)
|
||||
@@ -22,7 +24,9 @@ ADD_SUBDIRECTORY(EffectShowManagement)
|
||||
ADD_SUBDIRECTORY(Evaluations)
|
||||
ADD_SUBDIRECTORY(ExerciseManagement)
|
||||
ADD_SUBDIRECTORY(FileManagement)
|
||||
ADD_SUBDIRECTORY(FilterManagement)
|
||||
IF(BUILD_FILTERMANAGEMENT)
|
||||
ADD_SUBDIRECTORY(FilterManagement)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(FreeSpace)
|
||||
ADD_SUBDIRECTORY(GuezIedManagement)
|
||||
ADD_SUBDIRECTORY(GuezNasat)
|
||||
|
||||
+6
-1
@@ -5,7 +5,12 @@
|
||||
# Created by Hannes Fritsche, ESZS, 2024-08-05
|
||||
#
|
||||
|
||||
FIND_PACKAGE(KDReports REQUIRED)
|
||||
FIND_PACKAGE(KDReports)
|
||||
|
||||
IF(NOT KDReports_FOUND)
|
||||
MESSAGE(STATUS "KDReports not found; skipping CdsSimulationGuiPlugin")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
|
||||
SET(cds_gui_SRCS
|
||||
cds_building_model.cpp
|
||||
|
||||
@@ -37,11 +37,18 @@ ADD_INTERFACE_LIBRARY(
|
||||
#
|
||||
# need top be shared due to signals/slots
|
||||
NGL_ADD_LIBRARY2(WS IsmDataPluginInterface SHARED ism_data_plugin_interface.h)
|
||||
IF(BUILD_RTI)
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmDataPluginInterface
|
||||
Qt6::Core
|
||||
svcIsmCommon
|
||||
DataPluginInterface
|
||||
)
|
||||
ELSE()
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmDataPluginInterface
|
||||
Qt6::Core
|
||||
DataPluginInterface
|
||||
)
|
||||
ENDIF(BUILD_RTI)
|
||||
NGL_INSTALL_TARGET(IsmDataPluginInterface)
|
||||
|
||||
#
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@
|
||||
|
||||
FIND_PACKAGE(KDReports)
|
||||
FIND_PACKAGE(KDChart)
|
||||
IF (NOT KDReports_FOUND OR NOT KDChart_FOUND)
|
||||
MESSAGE(WARNING "KDReports or KDChart not found; skipping ReportViewer")
|
||||
IF ((NOT KDReports_FOUND OR NOT KDChart_FOUND) OR NOT BUILD_CODIFICATION)
|
||||
MESSAGE(WARNING "KDReports, KDChart not found or BUILD_CODIFICATION disabled; skipping ReportViewer")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
|
||||
|
||||
Executable → Regular
+210
-194
@@ -1,289 +1,305 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sv_export.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <WirelessLocationSystem/sfmconverter_export.h>
|
||||
|
||||
namespace WirelessLocationSystem
|
||||
{
|
||||
|
||||
|
||||
class SfmMessage
|
||||
{
|
||||
public:
|
||||
enum class MsgId
|
||||
{
|
||||
TacticalState = 37,
|
||||
SfmRestartNotification = 76,
|
||||
GpsControl = 79,
|
||||
RequestGpsControl = 79 | 0x8000,
|
||||
EquipmentId = 478,
|
||||
RequestEquipmentId = 478 | 0x8000,
|
||||
Acknowledge = 1098,
|
||||
LicenseState = 1099,
|
||||
TetraMessage = 1100
|
||||
};
|
||||
public:
|
||||
enum class MsgId {
|
||||
TacticalState = 37,
|
||||
SfmRestartNotification = 76,
|
||||
GpsControl = 79,
|
||||
RequestGpsControl = 79 | 0x8000,
|
||||
EquipmentId = 478,
|
||||
RequestEquipmentId = 478 | 0x8000,
|
||||
Acknowledge = 1098,
|
||||
LicenseState = 1099,
|
||||
TetraMessage = 1100
|
||||
};
|
||||
|
||||
protected:
|
||||
explicit SfmMessage(MsgId id)
|
||||
: m_id(id)
|
||||
{}
|
||||
protected:
|
||||
explicit SfmMessage(MsgId id) : m_id(id) {}
|
||||
|
||||
public:
|
||||
virtual ~SfmMessage() = default;
|
||||
public:
|
||||
virtual ~SfmMessage() = default;
|
||||
|
||||
MsgId getId() const { return m_id; }
|
||||
private:
|
||||
MsgId m_id;
|
||||
MsgId getId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
private:
|
||||
MsgId m_id;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMessage_tx : public SfmMessage
|
||||
{
|
||||
public:
|
||||
using SfmMessage::SfmMessage;
|
||||
public:
|
||||
using SfmMessage::SfmMessage;
|
||||
|
||||
|
||||
|
||||
virtual QByteArray getPayload() const = 0;
|
||||
virtual QByteArray getPayload() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMessage_rx : public SfmMessage
|
||||
{
|
||||
public:
|
||||
using SfmMessage::SfmMessage;
|
||||
public:
|
||||
using SfmMessage::SfmMessage;
|
||||
|
||||
|
||||
|
||||
virtual bool setPayload(const QByteArray &payload) = 0;
|
||||
virtual bool setPayload(const QByteArray& payload) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMsgGpsControl_tx final : public SfmMessage_tx
|
||||
{
|
||||
public:
|
||||
explicit SfmMsgGpsControl_tx(bool gpsOn = false)
|
||||
: SfmMessage_tx(SfmMessage::MsgId::GpsControl)
|
||||
, m_gpsOn(gpsOn)
|
||||
{}
|
||||
public:
|
||||
explicit SfmMsgGpsControl_tx(bool gpsOn = false) : SfmMessage_tx(SfmMessage::MsgId::GpsControl), m_gpsOn(gpsOn) {}
|
||||
|
||||
QByteArray getPayload() const override;
|
||||
QByteArray getPayload() const override;
|
||||
|
||||
void setGpsOn(bool bOn) { m_gpsOn = bOn; }
|
||||
bool isGpsOn() const { return m_gpsOn; }
|
||||
void setGpsOn(bool bOn)
|
||||
{
|
||||
m_gpsOn = bOn;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_gpsOn;
|
||||
bool isGpsOn() const
|
||||
{
|
||||
return m_gpsOn;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_gpsOn;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMsgRequestGpsControl_rx final : public SfmMessage_rx
|
||||
{
|
||||
public:
|
||||
SfmMsgRequestGpsControl_rx()
|
||||
: SfmMessage_rx(SfmMessage::MsgId::RequestGpsControl)
|
||||
{}
|
||||
public:
|
||||
SfmMsgRequestGpsControl_rx() : SfmMessage_rx(SfmMessage::MsgId::RequestGpsControl) {}
|
||||
|
||||
bool setPayload(const QByteArray &payload) override
|
||||
{
|
||||
return (payload.size() == 0);
|
||||
}
|
||||
bool setPayload(const QByteArray& payload) override
|
||||
{
|
||||
return (payload.size() == 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMsgRequestEquipmentId_tx final : public SfmMessage_tx
|
||||
{
|
||||
public:
|
||||
SfmMsgRequestEquipmentId_tx()
|
||||
: SfmMessage_tx(SfmMessage::MsgId::RequestEquipmentId)
|
||||
{}
|
||||
public:
|
||||
SfmMsgRequestEquipmentId_tx() : SfmMessage_tx(SfmMessage::MsgId::RequestEquipmentId) {}
|
||||
|
||||
QByteArray getPayload() const override
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
QByteArray getPayload() const override
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SFMCONVERTER_EXPORT SfmMsgEquipmentId final : public SfmMessage_rx, public SfmMessage_tx
|
||||
{
|
||||
public:
|
||||
SfmMsgEquipmentId()
|
||||
: SfmMessage_rx(SfmMessage::MsgId::EquipmentId)
|
||||
, SfmMessage_tx(SfmMessage::MsgId::EquipmentId)
|
||||
{}
|
||||
public:
|
||||
SfmMsgEquipmentId() : SfmMessage_rx(SfmMessage::MsgId::EquipmentId), SfmMessage_tx(SfmMessage::MsgId::EquipmentId)
|
||||
{
|
||||
}
|
||||
|
||||
bool setPayload(const QByteArray &) override;
|
||||
QByteArray getPayload() const override;
|
||||
bool setPayload(const QByteArray&) override;
|
||||
QByteArray getPayload() const override;
|
||||
|
||||
static constexpr int s_payloadSize = 3;
|
||||
static constexpr int s_payloadSize = 3;
|
||||
|
||||
unsigned short getEquipmentNumber() const
|
||||
{
|
||||
return m_equipmentNumber;
|
||||
}
|
||||
void setEquipmentNumber(quint16 equipmentNumber) { m_equipmentNumber = equipmentNumber; }
|
||||
unsigned short getEquipmentNumber() const
|
||||
{
|
||||
return m_equipmentNumber;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned short m_equipmentNumber = 0;
|
||||
void setEquipmentNumber(quint16 equipmentNumber)
|
||||
{
|
||||
m_equipmentNumber = equipmentNumber;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned short m_equipmentNumber = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMsgSfmRestart_rx final : public SfmMessage_rx
|
||||
{
|
||||
public:
|
||||
SfmMsgSfmRestart_rx()
|
||||
: SfmMessage_rx(SfmMessage::MsgId::SfmRestartNotification)
|
||||
{}
|
||||
bool setPayload(const QByteArray &payload) override
|
||||
{
|
||||
return (payload.size() == 0);
|
||||
}
|
||||
public:
|
||||
SfmMsgSfmRestart_rx() : SfmMessage_rx(SfmMessage::MsgId::SfmRestartNotification) {}
|
||||
|
||||
bool setPayload(const QByteArray& payload) override
|
||||
{
|
||||
return (payload.size() == 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMsgTacticalState_rx final : public SfmMessage_rx
|
||||
{
|
||||
public:
|
||||
SfmMsgTacticalState_rx()
|
||||
: SfmMessage_rx(SfmMessage::MsgId::TacticalState)
|
||||
{}
|
||||
public:
|
||||
SfmMsgTacticalState_rx() : SfmMessage_rx(SfmMessage::MsgId::TacticalState) {}
|
||||
|
||||
static constexpr int s_payloadSize = 1;
|
||||
static constexpr int s_payloadSize = 1;
|
||||
|
||||
bool setPayload(const QByteArray &) override;
|
||||
bool setPayload(const QByteArray&) override;
|
||||
|
||||
unsigned char getTacticalState() const { return m_tacticalState; }
|
||||
unsigned char getTacticalState() const
|
||||
{
|
||||
return m_tacticalState;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char m_tacticalState = 0;
|
||||
private:
|
||||
unsigned char m_tacticalState = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMsgTetra_rx final : public SfmMessage_rx
|
||||
{
|
||||
public:
|
||||
SfmMsgTetra_rx()
|
||||
: SfmMessage_rx(SfmMessage::MsgId::TetraMessage)
|
||||
{}
|
||||
public:
|
||||
SfmMsgTetra_rx() : SfmMessage_rx(SfmMessage::MsgId::TetraMessage) {}
|
||||
|
||||
bool setPayload(const QByteArray &p_data) override;
|
||||
bool setPayload(const QByteArray& p_data) override;
|
||||
|
||||
uint8_t sendCounter() const { return m_sendCounter; }
|
||||
bool isFragmented() const { return fragmentCount() > 1; }
|
||||
uint8_t fragmentNumber() const { return m_fragmentByte & 0x0f; }
|
||||
uint8_t fragmentCount() const { return (m_fragmentByte & 0xf0) >> 4;}
|
||||
uint8_t sendCounter() const
|
||||
{
|
||||
return m_sendCounter;
|
||||
}
|
||||
|
||||
const QByteArray &payload() const { return m_payload; }
|
||||
bool isFragmented() const
|
||||
{
|
||||
return fragmentCount() > 1;
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray m_payload;
|
||||
uint8_t m_sendCounter = 0;
|
||||
uint8_t m_fragmentByte = 0;
|
||||
uint8_t fragmentNumber() const
|
||||
{
|
||||
return m_fragmentByte & 0x0f;
|
||||
}
|
||||
|
||||
uint8_t fragmentCount() const
|
||||
{
|
||||
return (m_fragmentByte & 0xf0) >> 4;
|
||||
}
|
||||
|
||||
const QByteArray& payload() const
|
||||
{
|
||||
return m_payload;
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray m_payload;
|
||||
uint8_t m_sendCounter = 0;
|
||||
uint8_t m_fragmentByte = 0;
|
||||
};
|
||||
|
||||
class SfmMsgTetra_tx final : public SfmMessage_tx
|
||||
{
|
||||
public:
|
||||
explicit SfmMsgTetra_tx(uint8_t sendCounter, int fragmentCount, int fragmentNumber, const QByteArray &data)
|
||||
: SfmMessage_tx(SfmMessage::MsgId::TetraMessage)
|
||||
{
|
||||
m_data.reserve(data.size() + 2);
|
||||
m_data += sendCounter;
|
||||
m_data += fragmentByte(fragmentCount, fragmentNumber);
|
||||
m_data += data;
|
||||
}
|
||||
public:
|
||||
explicit SfmMsgTetra_tx(uint8_t sendCounter, int fragmentCount, int fragmentNumber, const QByteArray& data)
|
||||
: SfmMessage_tx(SfmMessage::MsgId::TetraMessage)
|
||||
{
|
||||
m_data.reserve(data.size() + 2);
|
||||
m_data += sendCounter;
|
||||
m_data += fragmentByte(fragmentCount, fragmentNumber);
|
||||
m_data += data;
|
||||
}
|
||||
|
||||
static char fragmentByte(int fragmentCount, int fragmentNumber)
|
||||
{
|
||||
Q_ASSERT(fragmentCount >= 0 && fragmentCount < 16);
|
||||
Q_ASSERT(fragmentNumber >= 0 && fragmentNumber <= fragmentCount);
|
||||
return ((fragmentCount & 0x0f) << 4 ) | (fragmentNumber & 0x0f);
|
||||
}
|
||||
QByteArray getPayload() const override { return m_data; }
|
||||
private:
|
||||
QByteArray m_data;
|
||||
static char fragmentByte(int fragmentCount, int fragmentNumber)
|
||||
{
|
||||
Q_ASSERT(fragmentCount >= 0 && fragmentCount < 16);
|
||||
Q_ASSERT(fragmentNumber >= 0 && fragmentNumber <= fragmentCount);
|
||||
return ((fragmentCount & 0x0f) << 4) | (fragmentNumber & 0x0f);
|
||||
}
|
||||
|
||||
QByteArray getPayload() const override
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray m_data;
|
||||
};
|
||||
|
||||
|
||||
class Acknowledge_rx final : public SfmMessage_rx
|
||||
{
|
||||
public:
|
||||
Acknowledge_rx()
|
||||
: SfmMessage_rx(SfmMessage::MsgId::Acknowledge)
|
||||
{}
|
||||
public:
|
||||
Acknowledge_rx() : SfmMessage_rx(SfmMessage::MsgId::Acknowledge) {}
|
||||
|
||||
static constexpr int s_payloadSize = 2;
|
||||
static constexpr int s_payloadSize = 2;
|
||||
|
||||
bool setPayload(const QByteArray &p_data) override;
|
||||
uint8_t recvCounter() const { return m_recvCounter; }
|
||||
bool isOk() const { return m_ackState == 0; }
|
||||
bool isCrcError() const { return (m_ackState & 0x20) == 0x20; }
|
||||
bool isFragmentError() const { return (m_ackState & 0x10) == 0x10; }
|
||||
uint8_t missingFragment() const { return (m_ackState & 0x0f)!= 0; }
|
||||
private:
|
||||
uint8_t m_recvCounter = 0;
|
||||
uint8_t m_ackState = 0;
|
||||
bool setPayload(const QByteArray& p_data) override;
|
||||
|
||||
uint8_t recvCounter() const
|
||||
{
|
||||
return m_recvCounter;
|
||||
}
|
||||
|
||||
bool isOk() const
|
||||
{
|
||||
return m_ackState == 0;
|
||||
}
|
||||
|
||||
bool isCrcError() const
|
||||
{
|
||||
return (m_ackState & 0x20) == 0x20;
|
||||
}
|
||||
|
||||
bool isFragmentError() const
|
||||
{
|
||||
return (m_ackState & 0x10) == 0x10;
|
||||
}
|
||||
|
||||
uint8_t missingFragment() const
|
||||
{
|
||||
return (m_ackState & 0x0f) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t m_recvCounter = 0;
|
||||
uint8_t m_ackState = 0;
|
||||
};
|
||||
|
||||
class Acknowledge_tx final : public SfmMessage_tx
|
||||
{
|
||||
public:
|
||||
explicit Acknowledge_tx()
|
||||
: SfmMessage_tx(SfmMessage::MsgId::Acknowledge)
|
||||
{}
|
||||
public:
|
||||
explicit Acknowledge_tx() : SfmMessage_tx(SfmMessage::MsgId::Acknowledge) {}
|
||||
|
||||
QByteArray getPayload() const override;
|
||||
QByteArray getPayload() const override;
|
||||
|
||||
void setRecvCounter(uint8_t recvCounter) { m_recvCounter = recvCounter; }
|
||||
void setCrcError() { m_ackState |= 0x20; }
|
||||
void setFragmentError(uint8_t missingFrag) { m_ackState |= (0x10 | (0x0f & missingFrag)); }
|
||||
private:
|
||||
uint8_t m_recvCounter = 0;
|
||||
uint8_t m_ackState = 0;
|
||||
void setRecvCounter(uint8_t recvCounter)
|
||||
{
|
||||
m_recvCounter = recvCounter;
|
||||
}
|
||||
|
||||
void setCrcError()
|
||||
{
|
||||
m_ackState |= 0x20;
|
||||
}
|
||||
|
||||
void setFragmentError(uint8_t missingFrag)
|
||||
{
|
||||
m_ackState |= (0x10 | (0x0f & missingFrag));
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t m_recvCounter = 0;
|
||||
uint8_t m_ackState = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class SfmMsgLicenseState_rx final : public SfmMessage_rx
|
||||
{
|
||||
public:
|
||||
SfmMsgLicenseState_rx()
|
||||
: SfmMessage_rx(SfmMessage::MsgId::LicenseState)
|
||||
{}
|
||||
public:
|
||||
SfmMsgLicenseState_rx() : SfmMessage_rx(SfmMessage::MsgId::LicenseState) {}
|
||||
|
||||
static constexpr int s_payloadSize = 1;
|
||||
static constexpr int s_payloadSize = 1;
|
||||
|
||||
bool setPayload(const QByteArray &p_data) override;
|
||||
bool isLicensed() const { return m_isLicensed; }
|
||||
bool setPayload(const QByteArray& p_data) override;
|
||||
|
||||
private:
|
||||
bool m_isLicensed = false;
|
||||
bool isLicensed() const
|
||||
{
|
||||
return m_isLicensed;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isLicensed = false;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace WirelessLocationSystem
|
||||
@@ -18,7 +18,9 @@ ADD_SUBDIRECTORY(Evaluations)
|
||||
ADD_SUBDIRECTORY(ExerciseManagement)
|
||||
ADD_SUBDIRECTORY(ExerciseEventManagement)
|
||||
ADD_SUBDIRECTORY(FileManagement)
|
||||
ADD_SUBDIRECTORY(FilterManagement)
|
||||
IF(BUILD_FILTERMANAGEMENT)
|
||||
ADD_SUBDIRECTORY(FilterManagement)
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(GuezIedManagement)
|
||||
ADD_SUBDIRECTORY(GuezMinelayerProcessing)
|
||||
IF(BUILD_RTI)
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -595,6 +595,10 @@ protected:
|
||||
static void setDestISSI_Internal(QByteArray &data, const uint32_t issi);
|
||||
|
||||
private:
|
||||
/**
|
||||
* The logger object
|
||||
*/
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+1687
-2004
File diff suppressed because it is too large.
Load diff
@@ -19,7 +19,7 @@ SET(NGLLogger_HDRS
|
||||
ADD_DEFINITIONS(-DBUILDING_NGLLOGGER)
|
||||
NGL_ADD_LIBRARY2(ALL NGLLogger SHARED ${NGLLogger_SRCS} ${NGLLogger_HDRS})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(NGLLogger
|
||||
INTERFACE
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
||||
Executable → Regular
+172
-187
@@ -1,59 +1,56 @@
|
||||
/**
|
||||
* Logger interface
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
* Logger interface
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QPointF>
|
||||
#include <QSize>
|
||||
#include <QRect>
|
||||
#include <QRectF>
|
||||
#include <QList>
|
||||
#include "ngllogger_export.h"
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <ngllogger_export.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
// keep in sync with log4qt/level.h
|
||||
enum class LogLevel
|
||||
{
|
||||
Undefined = 0,
|
||||
Trace = 64,
|
||||
Debug = 96,
|
||||
Info = 128,
|
||||
Warning = 150,
|
||||
Error = 182,
|
||||
Fatal = 214,
|
||||
enum class LogLevel {
|
||||
Undefined = 0,
|
||||
Trace = 64,
|
||||
Debug = 96,
|
||||
Info = 128,
|
||||
Warning = 150,
|
||||
Error = 182,
|
||||
Fatal = 214,
|
||||
};
|
||||
|
||||
class LogStreamHelper
|
||||
{
|
||||
public:
|
||||
inline LogStreamHelper(INGLLogger &logger, LogLevel level, const char *const file, int line, const char *const function)
|
||||
: m_logger(logger)
|
||||
, m_level(level)
|
||||
, m_line(line)
|
||||
, m_file(file)
|
||||
, m_func(function)
|
||||
{}
|
||||
inline ~LogStreamHelper(); // after INGLLogger class definition
|
||||
public:
|
||||
inline LogStreamHelper(INGLLogger& logger, LogLevel level, const char* const file, int line,
|
||||
const char* const function)
|
||||
: m_logger(logger), m_level(level), m_line(line), m_file(file), m_func(function)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline LogStreamHelper &operator<<(const T &val);
|
||||
inline ~LogStreamHelper(); // after INGLLogger class definition
|
||||
|
||||
private:
|
||||
std::ostringstream m_buffer;
|
||||
NGL::INGLLogger &m_logger;
|
||||
const LogLevel m_level;
|
||||
const int m_line;
|
||||
const char *const m_file;
|
||||
const char *const m_func;
|
||||
template <typename T> inline LogStreamHelper& operator<<(const T& val);
|
||||
|
||||
private:
|
||||
std::ostringstream m_buffer;
|
||||
NGL::INGLLogger& m_logger;
|
||||
const LogLevel m_level;
|
||||
const int m_line;
|
||||
const char* const m_file;
|
||||
const char* const m_func;
|
||||
};
|
||||
|
||||
// Interface class for source code logging.
|
||||
@@ -64,58 +61,64 @@ private:
|
||||
// information on logger-hierarchies, logging-levels, and configuration files.
|
||||
class INGLLogger
|
||||
{
|
||||
public:
|
||||
INGLLogger(const INGLLogger &) = delete;
|
||||
INGLLogger &operator=(const INGLLogger &) = delete;
|
||||
INGLLogger() = default;
|
||||
virtual ~INGLLogger() = default;
|
||||
public:
|
||||
INGLLogger(const INGLLogger&) = delete;
|
||||
INGLLogger& operator=(const INGLLogger&) = delete;
|
||||
INGLLogger() = default;
|
||||
virtual ~INGLLogger() = default;
|
||||
|
||||
using String = std::string;
|
||||
using String = std::string;
|
||||
|
||||
// Creates an instance of an INGLLogger interface. The fullqualifiedname is
|
||||
// a dottet sequence (i.e. "NGL.thisandthat.mylogger"). The same name will
|
||||
// always return the same interface-instance. It is not required to create
|
||||
// the parent nodes.
|
||||
virtual INGLLogger &getNGLLogger(const char *fullqualifiedname) = 0;
|
||||
virtual INGLLogger &getNGLLogger(const std::string &fullqualifiedname) = 0;
|
||||
// Creates an instance of an INGLLogger interface. The fullqualifiedname is
|
||||
// a dottet sequence (i.e. "NGL.thisandthat.mylogger"). The same name will
|
||||
// always return the same interface-instance. It is not required to create
|
||||
// the parent nodes.
|
||||
virtual INGLLogger& getNGLLogger(const char* fullqualifiedname) = 0;
|
||||
virtual INGLLogger& getNGLLogger(const std::string& fullqualifiedname) = 0;
|
||||
|
||||
// True if this level is enabled.
|
||||
virtual bool isTraceEnabled() const = 0;
|
||||
virtual bool isDebugEnabled() const = 0;
|
||||
virtual bool isInfoEnabled() const = 0;
|
||||
virtual bool isWarningEnabled() const = 0;
|
||||
virtual bool isErrorEnabled() const = 0;
|
||||
virtual bool isFatalEnabled() const = 0;
|
||||
virtual bool isLevelEnabled(LogLevel level) const = 0;
|
||||
|
||||
// True if this level is enabled.
|
||||
virtual bool isTraceEnabled() const = 0;
|
||||
virtual bool isDebugEnabled() const = 0;
|
||||
virtual bool isInfoEnabled() const = 0;
|
||||
virtual bool isWarningEnabled() const = 0;
|
||||
virtual bool isErrorEnabled() const = 0;
|
||||
virtual bool isFatalEnabled() const = 0;
|
||||
virtual bool isLevelEnabled(LogLevel level) const = 0;
|
||||
// Submit a LOG message.
|
||||
// Use __FILE__ and __NAME__ macros.
|
||||
virtual void log(LogLevel level, const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
|
||||
// Submit a LOG message.
|
||||
// Use __FILE__ and __NAME__ macros.
|
||||
virtual void log(LogLevel level, const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an TRACE message.
|
||||
virtual void logTrace(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit an DEBUG message.
|
||||
virtual void logDebug(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit an INFO message.
|
||||
virtual void logInfo(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit a WARNING message.
|
||||
virtual void logWarning(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit an ERROR message.
|
||||
virtual void logError(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit a FATAL message.
|
||||
virtual void logFatal(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
|
||||
// Submit an TRACE message.
|
||||
virtual void logTrace(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an DEBUG message.
|
||||
virtual void logDebug(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an INFO message.
|
||||
virtual void logInfo(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit a WARNING message.
|
||||
virtual void logWarning(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an ERROR message.
|
||||
virtual void logError(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit a FATAL message.
|
||||
virtual void logFatal(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Writes a startup message into the logfile
|
||||
virtual void logStartup(const char* file, int line, const char* function = nullptr) = 0;
|
||||
// Writes a shutdown message into the logfile
|
||||
virtual void logShutdown(const char* file, int line, const char* function = nullptr) = 0;
|
||||
|
||||
// Writes a startup message into the logfile
|
||||
virtual void logStartup(const char *file, int line, const char *function = nullptr) = 0;
|
||||
// Writes a shutdown message into the logfile
|
||||
virtual void logShutdown(const char *file, int line, const char *function = nullptr) = 0;
|
||||
// Get this loggers fullqualified name.
|
||||
virtual std::string getLoggerName() const = 0;
|
||||
|
||||
// Get this loggers fullqualified name.
|
||||
virtual std::string getLoggerName() const = 0;
|
||||
|
||||
virtual void setNoSpace(bool bNoSpace) = 0;
|
||||
virtual bool noSpace() const = 0;
|
||||
virtual void setNoSpace(bool bNoSpace) = 0;
|
||||
virtual bool noSpace() const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
@@ -123,112 +126,90 @@ public:
|
||||
//
|
||||
inline LogStreamHelper::~LogStreamHelper()
|
||||
{
|
||||
m_logger.log(m_level, m_buffer.str(), m_file, m_line, m_func);
|
||||
m_logger.log(m_level, m_buffer.str(), m_file, m_line, m_func);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline LogStreamHelper &LogStreamHelper::operator<<(const T &val)
|
||||
template <typename T> inline LogStreamHelper& LogStreamHelper::operator<<(const T& val)
|
||||
{
|
||||
m_buffer << val;
|
||||
if (!m_logger.noSpace())
|
||||
m_buffer << " ";
|
||||
return *this;
|
||||
m_buffer << val;
|
||||
if (!m_logger.noSpace())
|
||||
m_buffer << " ";
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace NGL
|
||||
|
||||
} //namespace NGL
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const QByteArray &str)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QByteArray& str)
|
||||
{
|
||||
stream << std::string(str.data(), str.size());
|
||||
return stream;
|
||||
stream << std::string(str.data(), str.size());
|
||||
return stream;
|
||||
}
|
||||
|
||||
//
|
||||
// operator to ease logging (at least via NglLogging)
|
||||
//
|
||||
inline std::ostream &operator<<(std::ostream &stream,
|
||||
const QPointF &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QPointF& value)
|
||||
{
|
||||
stream << "QPointF(" << QString::number(value.x(), 'f', 6).toStdString() << "#" << QString::number(value.y(), 'f', 6).toStdString() << ")";
|
||||
return stream;
|
||||
stream << "QPointF(" << QString::number(value.x(), 'f', 6).toStdString() << "#"
|
||||
<< QString::number(value.y(), 'f', 6).toStdString() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QPoint &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QPoint& value)
|
||||
{
|
||||
stream << "QPoint(" << value.x() << "#" << value.y() << ")";
|
||||
return stream;
|
||||
stream << "QPoint(" << value.x() << "#" << value.y() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QSize &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QSize& value)
|
||||
{
|
||||
stream << "QSize(w=" << value.width() << ";h=" << value.height() << ")";
|
||||
return stream;
|
||||
}
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QSizeF &value)
|
||||
{
|
||||
stream << "QSize(w="
|
||||
<< QString::number(value.width(), 'f', 6).toStdString() << ";h="
|
||||
<< QString::number(value.height(), 'f', 6).toStdString()
|
||||
<< ")";
|
||||
return stream;
|
||||
stream << "QSize(w=" << value.width() << ";h=" << value.height() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QRect &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QSizeF& value)
|
||||
{
|
||||
stream << "QRect(center=" << value.center()
|
||||
<< " w=" << value.width()
|
||||
<< ";h=" << value.height()
|
||||
<< " bottomLeft=" << value.bottomLeft()
|
||||
<< " topRight=" << value.topRight()
|
||||
<< ")";
|
||||
return stream;
|
||||
stream << "QSize(w=" << QString::number(value.width(), 'f', 6).toStdString()
|
||||
<< ";h=" << QString::number(value.height(), 'f', 6).toStdString() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QRectF &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QRect& value)
|
||||
{
|
||||
stream << "QRectF(center=" << value.center()
|
||||
<< " w=" << QString::number(value.width(), 'f', 3).toStdString()
|
||||
<< ";h=" << QString::number(value.height(), 'f', 3).toStdString()
|
||||
<< " bottomLeft=" << value.bottomLeft()
|
||||
<< " topRight=" << value.topRight()
|
||||
<< ")";
|
||||
return stream;
|
||||
stream << "QRect(center=" << value.center() << " w=" << value.width() << ";h=" << value.height()
|
||||
<< " bottomLeft=" << value.bottomLeft() << " topRight=" << value.topRight() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QList<int> &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QRectF& value)
|
||||
{
|
||||
stream << "QList<int>(" << value.size() << "): ";
|
||||
for (int i : value)
|
||||
stream << i << ";";
|
||||
return stream;
|
||||
stream << "QRectF(center=" << value.center() << " w=" << QString::number(value.width(), 'f', 3).toStdString()
|
||||
<< ";h=" << QString::number(value.height(), 'f', 3).toStdString() << " bottomLeft=" << value.bottomLeft()
|
||||
<< " topRight=" << value.topRight() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QList<QPointF> &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QList<int>& value)
|
||||
{
|
||||
stream << "QList<QPointF>(" << value.size() << "): ";
|
||||
for (const QPointF &item : value)
|
||||
stream << item << ";";
|
||||
return stream;
|
||||
stream << "QList<int>(" << value.size() << "): ";
|
||||
for (int i : value)
|
||||
stream << i << ";";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const QString &str)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QList<QPointF>& value)
|
||||
{
|
||||
return stream << str.toUtf8();
|
||||
stream << "QList<QPointF>(" << value.size() << "): ";
|
||||
for (const QPointF& item : value)
|
||||
stream << item << ";";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QString& str)
|
||||
{
|
||||
return stream << str.toUtf8();
|
||||
}
|
||||
|
||||
namespace NGL
|
||||
@@ -236,15 +217,12 @@ namespace NGL
|
||||
|
||||
namespace NGLLoggerHelper
|
||||
{
|
||||
NGLLOGGER_EXPORT void hexDumpHelper(NGL::INGLLogger &logger,
|
||||
NGL::LogLevel level,
|
||||
const void *a_data,
|
||||
NGLLOGGER_EXPORT void hexDumpHelper(NGL::INGLLogger& logger, NGL::LogLevel level, const void* a_data,
|
||||
const unsigned int a_size);
|
||||
inline void hexDumpHelper(NGL::INGLLogger &logger,
|
||||
NGL::LogLevel level,
|
||||
const QByteArray &data)
|
||||
|
||||
inline void hexDumpHelper(NGL::INGLLogger& logger, NGL::LogLevel level, const QByteArray& data)
|
||||
{
|
||||
return hexDumpHelper(logger, level, data.data(), data.size());
|
||||
return hexDumpHelper(logger, level, data.data(), data.size());
|
||||
}
|
||||
} // namespace NGLLoggerHelper
|
||||
|
||||
@@ -260,41 +238,46 @@ NGLLOGGER_EXPORT std::string getMemoryData();
|
||||
#define LOGFUNCTION Q_FUNC_INFO
|
||||
|
||||
// log this output every time, no matter what log level is enabled
|
||||
#define NOTICE_LOG(logger) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define NOTICE_LOG(logger) NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
#define TRACE_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isTraceEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define TRACE_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isTraceEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
#else
|
||||
#define TRACE_LOG(logger) \
|
||||
for ( ; false; ) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define TRACE_LOG(logger) \
|
||||
for (; false;) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
#endif
|
||||
|
||||
#define DEBUG_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isDebugEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Debug, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define DEBUG_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isDebugEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Debug, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define INFO_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define INFO_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define WARNING_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isWarningEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Warning, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define WARNING_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isWarningEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Warning, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define ERROR_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isErrorEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Error, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define ERROR_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isErrorEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Error, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define FATAL_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isFatalEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Fatal, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define FATAL_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isFatalEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Fatal, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define STARTUP_LOG(logger) { (logger).logStartup(__FILE__, __LINE__, Q_FUNC_INFO); }
|
||||
#define SHUTDOWN_LOG(logger) { (logger).logShutdown(__FILE__, __LINE__, Q_FUNC_INFO); }
|
||||
#define STARTUP_LOG(logger) \
|
||||
{ \
|
||||
(logger).logStartup(__FILE__, __LINE__, Q_FUNC_INFO); \
|
||||
}
|
||||
#define SHUTDOWN_LOG(logger) \
|
||||
{ \
|
||||
(logger).logShutdown(__FILE__, __LINE__, Q_FUNC_INFO); \
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
@@ -303,8 +286,10 @@ NGLLOGGER_EXPORT std::string getMemoryData();
|
||||
// do something nasty
|
||||
// MEMORY_LOG() << " after something nasty";
|
||||
|
||||
#define MEMORY_LOG() \
|
||||
for (bool log_level_enabled = (NGL::getMemoryLogger()).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(NGL::getMemoryLogger(), NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO) << NGL::getMemoryData()
|
||||
#define MEMORY_LOG() \
|
||||
for (bool log_level_enabled = (NGL::getMemoryLogger()).isInfoEnabled(); log_level_enabled; \
|
||||
log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(NGL::getMemoryLogger(), NGL::LogLevel::Info, __FILE__, __LINE__, Q_FUNC_INFO) \
|
||||
<< NGL::getMemoryData()
|
||||
|
||||
//==============================================================================
|
||||
Executable → Regular
+18
-32
@@ -1,11 +1,10 @@
|
||||
|
||||
|
||||
|
||||
#ifndef NGLLOGGERBOOTSTRAP_H
|
||||
#define NGLLOGGERBOOTSTRAP_H
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include "ngllogger_export.h"
|
||||
#include <ngllogger_export.h>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
@@ -14,46 +13,33 @@ namespace NGLLoggerBootstrap
|
||||
{
|
||||
class AlreadyCreatedError final : public std::exception
|
||||
{
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "NGLLogger rootlogger already created!";
|
||||
}
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "NGLLogger rootlogger already created!";
|
||||
}
|
||||
};
|
||||
|
||||
class NotCreatedError final : public std::exception
|
||||
{
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "NGLLogger rootlogger not yet created!";
|
||||
}
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "NGLLogger rootlogger not yet created!";
|
||||
}
|
||||
};
|
||||
|
||||
NGLLOGGER_EXPORT INGLLogger& getNGLRootLogger();
|
||||
|
||||
NGLLOGGER_EXPORT INGLLogger& createNGLRootLogger(const QString& configfilename, bool ignorealreadycreated,
|
||||
const QString& logOutputName = QString(), bool quiet = false);
|
||||
|
||||
|
||||
NGLLOGGER_EXPORT INGLLogger &getNGLRootLogger();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
NGLLOGGER_EXPORT INGLLogger &createNGLRootLogger(const QString &configfilename,
|
||||
bool ignorealreadycreated,
|
||||
const QString &logOutputName = QString(),
|
||||
bool quiet = false);
|
||||
inline INGLLogger &createNGLRootLogger(const char *configfilename,
|
||||
bool ignorealreadycreated,
|
||||
const QString &logOutputName = QString())
|
||||
inline INGLLogger& createNGLRootLogger(const char* configfilename, bool ignorealreadycreated,
|
||||
const QString& logOutputName = QString())
|
||||
{
|
||||
return createNGLRootLogger(QString::fromUtf8(configfilename), ignorealreadycreated, logOutputName);
|
||||
return createNGLRootLogger(QString::fromUtf8(configfilename), ignorealreadycreated, logOutputName);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace NGLLoggerBootstrap
|
||||
|
||||
}
|
||||
} // namespace NGL
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
Executable → Regular
+242
-261
@@ -1,360 +1,341 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "nglcomp_bzip2iodevice.h"
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QString>
|
||||
|
||||
#include <bzlib.h>
|
||||
|
||||
|
||||
|
||||
|
||||
class BZip2IODevice::Private
|
||||
{
|
||||
public:
|
||||
Private(BZip2IODevice *parent_, QIODevice *dev, int bs)
|
||||
: parent(parent_)
|
||||
, device(dev)
|
||||
, iCurPos(0)
|
||||
, iMaxBufSize(1024 * 1024)
|
||||
, blocksize(bs)
|
||||
, initialized(false)
|
||||
, decomressStreamEnd(false)
|
||||
{
|
||||
buffer.resize(iMaxBufSize);
|
||||
}
|
||||
public:
|
||||
Private(BZip2IODevice* parent_, QIODevice* dev, int bs)
|
||||
: parent(parent_), device(dev), iCurPos(0), iMaxBufSize(1024 * 1024), blocksize(bs), initialized(false),
|
||||
decomressStreamEnd(false)
|
||||
{
|
||||
buffer.resize(iMaxBufSize);
|
||||
}
|
||||
|
||||
bool initializeCompress();
|
||||
qint64 doCompress(const char *in, qint64 iMaxLen);
|
||||
bool finishCompress();
|
||||
bool initializeDecompress();
|
||||
qint64 doDecompress(char *out, qint64 iMaxLen);
|
||||
bool finishDecompress();
|
||||
static QString bzipError2String(int errCode);
|
||||
bool initializeCompress();
|
||||
qint64 doCompress(const char* in, qint64 iMaxLen);
|
||||
bool finishCompress();
|
||||
bool initializeDecompress();
|
||||
qint64 doDecompress(char* out, qint64 iMaxLen);
|
||||
bool finishDecompress();
|
||||
static QString bzipError2String(int errCode);
|
||||
|
||||
QAtomicInt aborted { 0 };
|
||||
BZip2IODevice *parent;
|
||||
QIODevice *device;
|
||||
unsigned int iCurPos;
|
||||
unsigned int iMaxBufSize;
|
||||
unsigned int blocksize;
|
||||
bool initialized;
|
||||
bool decomressStreamEnd;
|
||||
QByteArray buffer;
|
||||
bz_stream stream;
|
||||
QAtomicInt aborted{0};
|
||||
BZip2IODevice* parent;
|
||||
QIODevice* device;
|
||||
unsigned int iCurPos;
|
||||
unsigned int iMaxBufSize;
|
||||
unsigned int blocksize;
|
||||
bool initialized;
|
||||
bool decomressStreamEnd;
|
||||
QByteArray buffer;
|
||||
bz_stream stream;
|
||||
};
|
||||
|
||||
bool BZip2IODevice::Private::initializeCompress()
|
||||
{
|
||||
if (initialized)
|
||||
return true;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
int blockSize = (blocksize > 0 && blocksize < 10) ? blocksize : 10;
|
||||
int ret = BZ2_bzCompressInit(&stream, blockSize, 0, 0);
|
||||
if (ret != BZ_OK)
|
||||
{
|
||||
parent->setErrorString(QStringLiteral("Error initializing bzip2 %1").arg(bzipError2String(ret)));
|
||||
initialized = false;
|
||||
}
|
||||
else
|
||||
initialized = true;
|
||||
if (initialized)
|
||||
return true;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
int blockSize = (blocksize > 0 && blocksize < 10) ? blocksize : 10;
|
||||
int ret = BZ2_bzCompressInit(&stream, blockSize, 0, 0);
|
||||
if (ret != BZ_OK)
|
||||
{
|
||||
parent->setErrorString(QStringLiteral("Error initializing bzip2 %1").arg(bzipError2String(ret)));
|
||||
initialized = false;
|
||||
}
|
||||
else
|
||||
initialized = true;
|
||||
|
||||
return initialized;
|
||||
return initialized;
|
||||
}
|
||||
|
||||
qint64 BZip2IODevice::Private::doCompress(const char *in, qint64 iMaxLen)
|
||||
qint64 BZip2IODevice::Private::doCompress(const char* in, qint64 iMaxLen)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
if (parent->errorString().isEmpty())
|
||||
parent->setErrorString(QLatin1String("Internal Error - bzip not initialized"));
|
||||
finishCompress();
|
||||
return -1;
|
||||
}
|
||||
if (iMaxLen > 2 * 1024 * 1024 * 1024LL)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Currently can't handle more than 2GB!"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream.next_in = const_cast<char *>(in);
|
||||
stream.avail_in = iMaxLen;
|
||||
|
||||
do
|
||||
{
|
||||
if (aborted) return 0;
|
||||
|
||||
stream.next_out = buffer.data();
|
||||
stream.avail_out = buffer.size();
|
||||
|
||||
const int ret = BZ2_bzCompress(&stream, BZ_RUN);
|
||||
if (ret != BZ_RUN_OK)
|
||||
if (!initialized)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
|
||||
return -1;
|
||||
}
|
||||
int iBytesToWrite = buffer.size() - stream.avail_out;
|
||||
if (iBytesToWrite)
|
||||
{
|
||||
if (device->write(buffer.constData(), iBytesToWrite) != iBytesToWrite)
|
||||
{
|
||||
if (parent->errorString().isEmpty())
|
||||
parent->setErrorString(QLatin1String("Internal Error - bzip not initialized"));
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Error writing to QIODevice"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (stream.avail_in != 0);
|
||||
if (iMaxLen > 2 * 1024 * 1024 * 1024LL)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Currently can't handle more than 2GB!"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return stream.next_in - in;
|
||||
stream.next_in = const_cast<char*>(in);
|
||||
stream.avail_in = iMaxLen;
|
||||
|
||||
do
|
||||
{
|
||||
if (aborted)
|
||||
return 0;
|
||||
|
||||
stream.next_out = buffer.data();
|
||||
stream.avail_out = buffer.size();
|
||||
|
||||
const int ret = BZ2_bzCompress(&stream, BZ_RUN);
|
||||
if (ret != BZ_RUN_OK)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
|
||||
return -1;
|
||||
}
|
||||
int iBytesToWrite = buffer.size() - stream.avail_out;
|
||||
if (iBytesToWrite)
|
||||
{
|
||||
if (device->write(buffer.constData(), iBytesToWrite) != iBytesToWrite)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Error writing to QIODevice"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} while (stream.avail_in != 0);
|
||||
|
||||
return stream.next_in - in;
|
||||
}
|
||||
|
||||
bool BZip2IODevice::Private::finishCompress()
|
||||
{
|
||||
if (!initialized || aborted)
|
||||
if (!initialized || aborted)
|
||||
return true;
|
||||
|
||||
int ret = -1;
|
||||
|
||||
do
|
||||
{
|
||||
stream.next_out = buffer.data();
|
||||
stream.avail_out = buffer.size();
|
||||
ret = BZ2_bzCompress(&stream, BZ_FINISH);
|
||||
if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
|
||||
return false;
|
||||
}
|
||||
int iBytesToWrite = buffer.size() - stream.avail_out;
|
||||
if (device->write(buffer.constData(), iBytesToWrite) != iBytesToWrite)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Error writing to QIODevice"));
|
||||
return false;
|
||||
}
|
||||
} while (ret != BZ_STREAM_END);
|
||||
BZ2_bzCompressEnd(&stream);
|
||||
|
||||
initialized = false;
|
||||
return true;
|
||||
|
||||
int ret = -1;
|
||||
|
||||
do
|
||||
{
|
||||
stream.next_out = buffer.data();
|
||||
stream.avail_out = buffer.size();
|
||||
ret = BZ2_bzCompress(&stream, BZ_FINISH);
|
||||
if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
|
||||
return false;
|
||||
}
|
||||
int iBytesToWrite = buffer.size() - stream.avail_out;
|
||||
if (device->write(buffer.constData(), iBytesToWrite) != iBytesToWrite)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Error writing to QIODevice"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
while (ret != BZ_STREAM_END);
|
||||
BZ2_bzCompressEnd(&stream);
|
||||
|
||||
initialized = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BZip2IODevice::Private::initializeDecompress()
|
||||
{
|
||||
if (initialized)
|
||||
return true;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
int ret = BZ2_bzDecompressInit(&stream, 0, 0);
|
||||
if (ret != BZ_OK)
|
||||
{
|
||||
parent->setErrorString(QStringLiteral("Error initializing bzip2: %1").arg(bzipError2String(ret)));
|
||||
initialized = false;
|
||||
}
|
||||
else
|
||||
initialized = true;
|
||||
decomressStreamEnd = false;
|
||||
return initialized;
|
||||
if (initialized)
|
||||
return true;
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
int ret = BZ2_bzDecompressInit(&stream, 0, 0);
|
||||
if (ret != BZ_OK)
|
||||
{
|
||||
parent->setErrorString(QStringLiteral("Error initializing bzip2: %1").arg(bzipError2String(ret)));
|
||||
initialized = false;
|
||||
}
|
||||
else
|
||||
initialized = true;
|
||||
decomressStreamEnd = false;
|
||||
return initialized;
|
||||
}
|
||||
|
||||
qint64 BZip2IODevice::Private::doDecompress(char *out, qint64 iMaxLen)
|
||||
qint64 BZip2IODevice::Private::doDecompress(char* out, qint64 iMaxLen)
|
||||
{
|
||||
int ret = -1;
|
||||
if (!initialized)
|
||||
{
|
||||
if (parent->errorString().isEmpty())
|
||||
parent->setErrorString(QLatin1String("Internal Error - bzip not initialized"));
|
||||
finishDecompress();
|
||||
return -1;
|
||||
}
|
||||
if (decomressStreamEnd)
|
||||
return 0;
|
||||
|
||||
if (iMaxLen > 2 * 1024 * 1024 * 1024LL)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Currently can't handle more than 2GB!"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream.next_out = out;
|
||||
stream.avail_out = iMaxLen;
|
||||
|
||||
do
|
||||
{
|
||||
if (ret != BZ_STREAM_END && stream.avail_in == 0)
|
||||
int ret = -1;
|
||||
if (!initialized)
|
||||
{
|
||||
qint64 iReadCnt = device->read(buffer.data(), buffer.size());
|
||||
if (iReadCnt <= 0)
|
||||
if (parent->errorString().isEmpty())
|
||||
parent->setErrorString(QLatin1String("Internal Error - bzip not initialized"));
|
||||
finishDecompress();
|
||||
return -1;
|
||||
}
|
||||
if (decomressStreamEnd)
|
||||
return 0;
|
||||
|
||||
if (iMaxLen > 2 * 1024 * 1024 * 1024LL)
|
||||
{
|
||||
finishCompress();
|
||||
parent->setErrorString(QLatin1String("Currently can't handle more than 2GB!"));
|
||||
return -1;
|
||||
stream.next_in = buffer.data();
|
||||
stream.avail_in = iReadCnt;
|
||||
}
|
||||
|
||||
ret = BZ2_bzDecompress(&stream);
|
||||
if (ret != BZ_OK && ret != BZ_STREAM_END)
|
||||
stream.next_out = out;
|
||||
stream.avail_out = iMaxLen;
|
||||
|
||||
do
|
||||
{
|
||||
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
|
||||
finishDecompress();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while (stream.avail_out != 0 && ret != BZ_STREAM_END);
|
||||
decomressStreamEnd = (ret == BZ_STREAM_END);
|
||||
return stream.next_out - out;
|
||||
if (ret != BZ_STREAM_END && stream.avail_in == 0)
|
||||
{
|
||||
qint64 iReadCnt = device->read(buffer.data(), buffer.size());
|
||||
if (iReadCnt <= 0)
|
||||
return -1;
|
||||
stream.next_in = buffer.data();
|
||||
stream.avail_in = iReadCnt;
|
||||
}
|
||||
|
||||
ret = BZ2_bzDecompress(&stream);
|
||||
if (ret != BZ_OK && ret != BZ_STREAM_END)
|
||||
{
|
||||
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
|
||||
finishDecompress();
|
||||
return -1;
|
||||
}
|
||||
} while (stream.avail_out != 0 && ret != BZ_STREAM_END);
|
||||
decomressStreamEnd = (ret == BZ_STREAM_END);
|
||||
return stream.next_out - out;
|
||||
}
|
||||
|
||||
bool BZip2IODevice::Private::finishDecompress()
|
||||
{
|
||||
if (!initialized)
|
||||
return true;
|
||||
BZ2_bzDecompressEnd(&stream);
|
||||
if (!initialized)
|
||||
return true;
|
||||
BZ2_bzDecompressEnd(&stream);
|
||||
|
||||
initialized = false;
|
||||
return true;
|
||||
initialized = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString BZip2IODevice::Private::bzipError2String(int errCode)
|
||||
{
|
||||
switch (errCode)
|
||||
{
|
||||
case BZ_SEQUENCE_ERROR:
|
||||
return QLatin1String("Sequence error");
|
||||
case BZ_PARAM_ERROR:
|
||||
return QLatin1String("Parameter not correct");
|
||||
case BZ_MEM_ERROR:
|
||||
return QLatin1String("Memory allocation error");
|
||||
case BZ_DATA_ERROR:
|
||||
return QLatin1String("Invalid input data");
|
||||
case BZ_DATA_ERROR_MAGIC:
|
||||
return QLatin1String("Not a bzip2 file");
|
||||
case BZ_IO_ERROR:
|
||||
return QLatin1String("I/O error");
|
||||
case BZ_UNEXPECTED_EOF:
|
||||
return QLatin1String("Unexpected end of file");
|
||||
case BZ_OUTBUFF_FULL:
|
||||
return QLatin1String("Output buffer full");
|
||||
case BZ_CONFIG_ERROR:
|
||||
return QLatin1String("Wrong config parameter");
|
||||
};
|
||||
return QString::number(errCode);
|
||||
switch (errCode)
|
||||
{
|
||||
case BZ_SEQUENCE_ERROR:
|
||||
return QLatin1String("Sequence error");
|
||||
case BZ_PARAM_ERROR:
|
||||
return QLatin1String("Parameter not correct");
|
||||
case BZ_MEM_ERROR:
|
||||
return QLatin1String("Memory allocation error");
|
||||
case BZ_DATA_ERROR:
|
||||
return QLatin1String("Invalid input data");
|
||||
case BZ_DATA_ERROR_MAGIC:
|
||||
return QLatin1String("Not a bzip2 file");
|
||||
case BZ_IO_ERROR:
|
||||
return QLatin1String("I/O error");
|
||||
case BZ_UNEXPECTED_EOF:
|
||||
return QLatin1String("Unexpected end of file");
|
||||
case BZ_OUTBUFF_FULL:
|
||||
return QLatin1String("Output buffer full");
|
||||
case BZ_CONFIG_ERROR:
|
||||
return QLatin1String("Wrong config parameter");
|
||||
};
|
||||
return QString::number(errCode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
BZip2IODevice::BZip2IODevice(QIODevice *dev, int blocksize)
|
||||
: d(new Private(this, dev, blocksize))
|
||||
{}
|
||||
BZip2IODevice::BZip2IODevice(QIODevice* dev, int blocksize) : d(new Private(this, dev, blocksize)) {}
|
||||
|
||||
BZip2IODevice::~BZip2IODevice()
|
||||
{
|
||||
close();
|
||||
delete d;
|
||||
close();
|
||||
delete d;
|
||||
}
|
||||
|
||||
void BZip2IODevice::setBufferSize(unsigned int size)
|
||||
{
|
||||
d->iMaxBufSize = size > 1024 ? size : 1024;
|
||||
d->buffer.resize(d->iMaxBufSize);
|
||||
d->iMaxBufSize = size > 1024 ? size : 1024;
|
||||
d->buffer.resize(d->iMaxBufSize);
|
||||
}
|
||||
|
||||
void BZip2IODevice::setBlockSize(unsigned int size)
|
||||
{
|
||||
if (isOpen())
|
||||
return;
|
||||
d->blocksize = size;
|
||||
if (isOpen())
|
||||
return;
|
||||
d->blocksize = size;
|
||||
}
|
||||
|
||||
bool BZip2IODevice::isSequential() const
|
||||
{
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BZip2IODevice::open(OpenMode mode)
|
||||
{
|
||||
if ((mode & QIODevice::ReadWrite) == 0)
|
||||
{
|
||||
setErrorString(QStringLiteral("Unsupported OpenMode %1").arg(mode));
|
||||
return false;
|
||||
}
|
||||
if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite)
|
||||
{
|
||||
setErrorString(QLatin1String("Can't read and write simultaniously"));
|
||||
return false;
|
||||
}
|
||||
if ((mode & QIODevice::ReadOnly) == QIODevice::ReadOnly)
|
||||
{
|
||||
if (!d->device)
|
||||
if ((mode & QIODevice::ReadWrite) == 0)
|
||||
{
|
||||
setErrorString(QLatin1String("No QIODevice for reading available"));
|
||||
return false;
|
||||
setErrorString(QStringLiteral("Unsupported OpenMode %1").arg(static_cast<int>(mode)));
|
||||
return false;
|
||||
}
|
||||
if ((d->device->openMode() & QIODevice::ReadOnly) == 0)
|
||||
if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite)
|
||||
{
|
||||
setErrorString(QLatin1String("QIODevice not opened for reading"));
|
||||
return false;
|
||||
setErrorString(QLatin1String("Can't read and write simultaniously"));
|
||||
return false;
|
||||
}
|
||||
if (!d->initializeDecompress())
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!d->device)
|
||||
if ((mode & QIODevice::ReadOnly) == QIODevice::ReadOnly)
|
||||
{
|
||||
setErrorString(QLatin1String("No QIODevice for writing available"));
|
||||
return false;
|
||||
if (!d->device)
|
||||
{
|
||||
setErrorString(QLatin1String("No QIODevice for reading available"));
|
||||
return false;
|
||||
}
|
||||
if ((d->device->openMode() & QIODevice::ReadOnly) == 0)
|
||||
{
|
||||
setErrorString(QLatin1String("QIODevice not opened for reading"));
|
||||
return false;
|
||||
}
|
||||
if (!d->initializeDecompress())
|
||||
return false;
|
||||
}
|
||||
if ((d->device->openMode() & QIODevice::WriteOnly) == 0)
|
||||
else
|
||||
{
|
||||
setErrorString(QLatin1String("QIODevice not opened for writing"));
|
||||
return false;
|
||||
if (!d->device)
|
||||
{
|
||||
setErrorString(QLatin1String("No QIODevice for writing available"));
|
||||
return false;
|
||||
}
|
||||
if ((d->device->openMode() & QIODevice::WriteOnly) == 0)
|
||||
{
|
||||
setErrorString(QLatin1String("QIODevice not opened for writing"));
|
||||
return false;
|
||||
}
|
||||
if (!d->initializeCompress())
|
||||
return false;
|
||||
}
|
||||
if (!d->initializeCompress())
|
||||
return false;
|
||||
}
|
||||
setErrorString(QString());
|
||||
setOpenMode(mode);
|
||||
return QIODevice::open(mode);
|
||||
setErrorString(QString());
|
||||
setOpenMode(mode);
|
||||
return QIODevice::open(mode);
|
||||
}
|
||||
|
||||
void BZip2IODevice::abort()
|
||||
{
|
||||
d->aborted = 1;
|
||||
d->aborted = 1;
|
||||
}
|
||||
|
||||
void BZip2IODevice::close()
|
||||
{
|
||||
if (!isOpen())
|
||||
return;
|
||||
if ((openMode() & QIODevice::ReadOnly) == QIODevice::ReadOnly)
|
||||
d->finishDecompress();
|
||||
else
|
||||
d->finishCompress();
|
||||
QIODevice::close();
|
||||
if (!isOpen())
|
||||
return;
|
||||
if ((openMode() & QIODevice::ReadOnly) == QIODevice::ReadOnly)
|
||||
d->finishDecompress();
|
||||
else
|
||||
d->finishCompress();
|
||||
QIODevice::close();
|
||||
}
|
||||
|
||||
bool BZip2IODevice::atEnd() const
|
||||
{
|
||||
if (!d->device)
|
||||
return true;
|
||||
return d->device->atEnd() && d->decomressStreamEnd && QIODevice::atEnd();
|
||||
if (!d->device)
|
||||
return true;
|
||||
return d->device->atEnd() && d->decomressStreamEnd && QIODevice::atEnd();
|
||||
}
|
||||
|
||||
qint64 BZip2IODevice::readData(char *data, qint64 maxSize)
|
||||
qint64 BZip2IODevice::readData(char* data, qint64 maxSize)
|
||||
{
|
||||
return d->doDecompress(data, maxSize);
|
||||
return d->doDecompress(data, maxSize);
|
||||
}
|
||||
|
||||
qint64 BZip2IODevice::writeData(const char *data, qint64 maxSize)
|
||||
qint64 BZip2IODevice::writeData(const char* data, qint64 maxSize)
|
||||
{
|
||||
return d->doCompress(data, maxSize);
|
||||
return d->doCompress(data, maxSize);
|
||||
}
|
||||
Executable → Regular
+405
-445
@@ -1,569 +1,529 @@
|
||||
|
||||
|
||||
#include "nglcomp_compress.h"
|
||||
|
||||
#include "nglcomp_bzip2iodevice.h"
|
||||
#include "nglcomp_tarfilter.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QtConcurrent>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QFutureWatcher>
|
||||
#include <QIODevice>
|
||||
#include <QStringList>
|
||||
#include <QtConcurrent>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
|
||||
Compress::Compress(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_u2_memFiles()
|
||||
, m_aborted(0)
|
||||
Compress::Compress(QObject* parent)
|
||||
: QObject(parent), m_u2_memFiles(), m_aborted(0),
|
||||
m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("nglcompress"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "c_tor";
|
||||
DEBUG_LOG(m_logger) << "c_tor";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QTimer *t = new QTimer(this);
|
||||
t->setInterval(1000);
|
||||
connect(t, &QTimer::timeout, this, [](){qWarning() << "still alive ...";});
|
||||
t->start();
|
||||
QTimer* t = new QTimer(this);
|
||||
t->setInterval(1000);
|
||||
connect(t, &QTimer::timeout, this, []() { qWarning() << "still alive ..."; });
|
||||
t->start();
|
||||
}
|
||||
|
||||
Compress::~Compress()
|
||||
{
|
||||
qWarning() << "## COMPRESS DTOR!!!!";
|
||||
qWarning() << "## COMPRESS DTOR!!!!";
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "~";
|
||||
DEBUG_LOG(m_logger) << "~";
|
||||
|
||||
abort();
|
||||
m_future.waitForFinished();
|
||||
DEBUG_LOG(m_logger) << "~ finished";
|
||||
abort();
|
||||
m_future.waitForFinished();
|
||||
DEBUG_LOG(m_logger) << "~ finished";
|
||||
}
|
||||
|
||||
void Compress::abort()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "ABORT";
|
||||
DEBUG_LOG(m_logger) << "ABORT";
|
||||
|
||||
m_aborted = 1;
|
||||
m_lastError = tr("Aborted");
|
||||
m_aborted = 1;
|
||||
m_lastError = tr("Aborted");
|
||||
|
||||
if (m_currentTarFilter != nullptr)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "aborting tar";
|
||||
m_currentTarFilter->abort();
|
||||
}
|
||||
if (m_currentTarFilter != nullptr)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "aborting tar";
|
||||
m_currentTarFilter->abort();
|
||||
}
|
||||
|
||||
if (m_currentBzipDevice != nullptr)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "aborting bzip";
|
||||
m_currentBzipDevice->abort();
|
||||
}
|
||||
if (m_currentBzipDevice != nullptr)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "aborting bzip";
|
||||
m_currentBzipDevice->abort();
|
||||
}
|
||||
}
|
||||
|
||||
void Compress::compress(QIODevice *out,
|
||||
const QString &filesRootDir,
|
||||
const QVector<FileInformations> &files,
|
||||
const QVector<FileInformations> &memFiles,
|
||||
const QString &destRootDir)
|
||||
void Compress::compress(QIODevice* out, const QString& filesRootDir, const QVector<FileInformations>& files,
|
||||
const QVector<FileInformations>& memFiles, const QString& destRootDir)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "compress #2";
|
||||
reset();
|
||||
setupFutureWatcher(QtConcurrent::run([this, out, filesRootDir, files, memFiles, destRootDir]() {
|
||||
return this->_compress(out, filesRootDir, files, memFiles, destRootDir);
|
||||
}));
|
||||
DEBUG_LOG(m_logger) << "compress #2";
|
||||
reset();
|
||||
setupFutureWatcher(QtConcurrent::run([this, out, filesRootDir, files, memFiles, destRootDir]() {
|
||||
return this->_compress(out, filesRootDir, files, memFiles, destRootDir);
|
||||
}));
|
||||
}
|
||||
|
||||
void Compress::compress(QIODevice *out, const QString &sourceDir, const QString &destRootDir)
|
||||
void Compress::compress(QIODevice* out, const QString& sourceDir, const QString& destRootDir)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "compress #1 source dir: " << sourceDir << ", destRootDir: " << destRootDir;
|
||||
reset();
|
||||
DEBUG_LOG(m_logger) << "compress #1 source dir: " << sourceDir << ", destRootDir: " << destRootDir;
|
||||
reset();
|
||||
|
||||
QVector<Compress::FileInformations> inFiles = directoryFileList(sourceDir, true);
|
||||
QVector<Compress::FileInformations> inFiles = directoryFileList(sourceDir, true);
|
||||
|
||||
|
||||
int len = sourceDir.length();
|
||||
if (!sourceDir.endsWith(QLatin1Char('/')))
|
||||
len += 1;
|
||||
for (auto &fi : inFiles)
|
||||
{
|
||||
fi.inputFileName = fi.inputFileName.mid(len);
|
||||
fi.bAbsInputPath = false;
|
||||
DEBUG_LOG(m_logger) << "fi: ifm = " << fi.inputFileName << ", abs = " << fi.bAbsInputPath;
|
||||
}
|
||||
int len = sourceDir.length();
|
||||
if (!sourceDir.endsWith(QLatin1Char('/')))
|
||||
len += 1;
|
||||
for (auto& fi : inFiles)
|
||||
{
|
||||
fi.inputFileName = fi.inputFileName.mid(len);
|
||||
fi.bAbsInputPath = false;
|
||||
DEBUG_LOG(m_logger) << "fi: ifm = " << fi.inputFileName << ", abs = " << fi.bAbsInputPath;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "FI list size: " << inFiles.count();
|
||||
DEBUG_LOG(m_logger) << "FI list size: " << inFiles.count();
|
||||
|
||||
compress(out, sourceDir, inFiles, {}, destRootDir);
|
||||
compress(out, sourceDir, inFiles, {}, destRootDir);
|
||||
}
|
||||
|
||||
bool Compress::_compress(QIODevice *output,
|
||||
const QString &filesRootDir,
|
||||
const QVector<FileInformations> &files,
|
||||
const QVector<FileInformations> &memFiles,
|
||||
const QString &_destRootDir)
|
||||
bool Compress::_compress(QIODevice* output, const QString& filesRootDir, const QVector<FileInformations>& files,
|
||||
const QVector<FileInformations>& memFiles, const QString& _destRootDir)
|
||||
{
|
||||
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int *)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #1";
|
||||
m_currentTarFilter = nullptr;
|
||||
m_currentBzipDevice = nullptr;
|
||||
});
|
||||
(void)invalidatePointersOnScopeLeave;
|
||||
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int*) {
|
||||
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #1";
|
||||
m_currentTarFilter = nullptr;
|
||||
m_currentBzipDevice = nullptr;
|
||||
});
|
||||
(void)invalidatePointersOnScopeLeave;
|
||||
|
||||
|
||||
if (!output || !output->isWritable())
|
||||
{
|
||||
m_lastError = tr("Device is not writeable");
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString destRootDir = _destRootDir.endsWith(QLatin1Char('/')) ?
|
||||
_destRootDir : _destRootDir + QLatin1Char('/');
|
||||
|
||||
const qint64 maxCount = files.count() + memFiles.count();
|
||||
qint64 count = 0;
|
||||
|
||||
DEBUG_LOG(m_logger) << "destRootDir = " << destRootDir << ", maxCount = " << maxCount << ", count = " << count;
|
||||
|
||||
BZip2IODevice bzip2(output, 9);
|
||||
m_currentBzipDevice = &bzip2;
|
||||
|
||||
if (!bzip2.open(QIODevice::WriteOnly))
|
||||
{
|
||||
m_lastError = bzip2.errorString();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
qint64 bytesTotal = 0;
|
||||
for (const FileInformations &file : std::as_const(files))
|
||||
{
|
||||
if (m_aborted) return false;
|
||||
|
||||
const QString in = file.bAbsInputPath ? file.inputFileName : filesRootDir + QLatin1Char('/') + file.inputFileName;
|
||||
const QFileInfo fi(in);
|
||||
|
||||
bytesTotal += fi.size();
|
||||
}
|
||||
|
||||
|
||||
qint64 currentFileSize = 0;
|
||||
QString currentFileName;
|
||||
auto readCallback = [this, &maxCount, &count, ¤tFileSize, ¤tFileName, &bytesTotal](const qint64 iSize)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "readCallback: maxCount = " << maxCount << ", count = " << count
|
||||
<< ", currentFileSize = " << currentFileSize << ", currentFileName = " << currentFileName << ", iSize = " << iSize;
|
||||
emit compressInfoEx(maxCount, count, currentFileSize, (currentFileSize - iSize), currentFileName, bytesTotal);
|
||||
};
|
||||
|
||||
|
||||
TarFilter tf(&bzip2, readCallback);
|
||||
m_currentTarFilter = &tf;
|
||||
const QStringList paths = destRootDir.split(QLatin1Char('/'), Qt::SkipEmptyParts);
|
||||
QString curPath;
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "prepairing tar filter";
|
||||
for (const QString &path : paths)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "path = " << path;
|
||||
if (m_aborted) return false;
|
||||
|
||||
if (curPath.isEmpty())
|
||||
curPath = path + QLatin1Char('/');
|
||||
else
|
||||
curPath += path + QLatin1Char('/');
|
||||
|
||||
DEBUG_LOG(m_logger) << "curPath = " << curPath << ", filesRootDir.isEmpty() = " << filesRootDir.isEmpty();
|
||||
|
||||
if (filesRootDir.isEmpty())
|
||||
if (!output || !output->isWritable())
|
||||
{
|
||||
if (!tf.addData(curPath, QByteArray(), true))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
m_lastError = tr("Device is not writeable");
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
const QString destRootDir =
|
||||
_destRootDir.endsWith(QLatin1Char('/')) ? _destRootDir : _destRootDir + QLatin1Char('/');
|
||||
|
||||
const qint64 maxCount = files.count() + memFiles.count();
|
||||
qint64 count = 0;
|
||||
|
||||
DEBUG_LOG(m_logger) << "destRootDir = " << destRootDir << ", maxCount = " << maxCount << ", count = " << count;
|
||||
|
||||
BZip2IODevice bzip2(output, 9);
|
||||
m_currentBzipDevice = &bzip2;
|
||||
|
||||
if (!bzip2.open(QIODevice::WriteOnly))
|
||||
{
|
||||
if (!tf.addFile(filesRootDir, curPath))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
m_lastError = bzip2.errorString();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_c_sizeInfo.realSize = 0;
|
||||
for (const FileInformations &file : std::as_const(files))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "file = " << file.inputFileName;
|
||||
emit compressInfo(maxCount, ++count, file.inputFileName);
|
||||
|
||||
if (m_aborted) return false;
|
||||
|
||||
QString in = file.bAbsInputPath ? file.inputFileName : filesRootDir + QLatin1Char('/') + file.inputFileName;
|
||||
QString out = destRootDir + (file.outputFileName.isEmpty() ? file.inputFileName : file.outputFileName);
|
||||
|
||||
DEBUG_LOG(m_logger) << "in = " << in << ", out = " << out;
|
||||
|
||||
QFileInfo fi(in);
|
||||
|
||||
currentFileName = fi.fileName();
|
||||
currentFileSize = fi.size();
|
||||
m_c_sizeInfo.realSize += currentFileSize;
|
||||
|
||||
DEBUG_LOG(m_logger) << "currentFileName = " << currentFileName << ", currentFileSize = " << currentFileSize << "m_c_sizeInfo.realSize" << m_c_sizeInfo.realSize;
|
||||
|
||||
if (!tf.addFile(in, out))
|
||||
qint64 bytesTotal = 0;
|
||||
for (const FileInformations& file : std::as_const(files))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
if (m_aborted)
|
||||
return false;
|
||||
|
||||
const QString in =
|
||||
file.bAbsInputPath ? file.inputFileName : filesRootDir + QLatin1Char('/') + file.inputFileName;
|
||||
const QFileInfo fi(in);
|
||||
|
||||
bytesTotal += fi.size();
|
||||
}
|
||||
}
|
||||
|
||||
for (const FileInformations &file : std::as_const(memFiles))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "(mem) file = " << file.inputFileName;
|
||||
emit compressInfo(maxCount, ++count, file.inputFileName);
|
||||
|
||||
if (m_aborted) return false;
|
||||
qint64 currentFileSize = 0;
|
||||
QString currentFileName;
|
||||
auto readCallback = [this, &maxCount, &count, ¤tFileSize, ¤tFileName, &bytesTotal](const qint64 iSize) {
|
||||
DEBUG_LOG(m_logger) << "readCallback: maxCount = " << maxCount << ", count = " << count
|
||||
<< ", currentFileSize = " << currentFileSize << ", currentFileName = " << currentFileName
|
||||
<< ", iSize = " << iSize;
|
||||
emit compressInfoEx(maxCount, count, currentFileSize, (currentFileSize - iSize), currentFileName, bytesTotal);
|
||||
};
|
||||
|
||||
currentFileName = file.inputFileName;
|
||||
currentFileSize = file.fileData.size();
|
||||
m_c_sizeInfo.compressedSize += currentFileSize;
|
||||
TarFilter tf(&bzip2, readCallback);
|
||||
m_currentTarFilter = &tf;
|
||||
const QStringList paths = destRootDir.split(QLatin1Char('/'), Qt::SkipEmptyParts);
|
||||
QString curPath;
|
||||
|
||||
DEBUG_LOG(m_logger) << "(mem) currentFileName = " << currentFileName << ", currentFileSize = " << currentFileSize << "m_c_sizeInfo.realSize" << m_c_sizeInfo.realSize;
|
||||
|
||||
if (!tf.addData(file.inputFileName, file.fileData))
|
||||
DEBUG_LOG(m_logger) << "prepairing tar filter";
|
||||
for (const QString& path : paths)
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
DEBUG_LOG(m_logger) << "path = " << path;
|
||||
if (m_aborted)
|
||||
return false;
|
||||
|
||||
if (curPath.isEmpty())
|
||||
curPath = path + QLatin1Char('/');
|
||||
else
|
||||
curPath += path + QLatin1Char('/');
|
||||
|
||||
DEBUG_LOG(m_logger) << "curPath = " << curPath << ", filesRootDir.isEmpty() = " << filesRootDir.isEmpty();
|
||||
|
||||
if (filesRootDir.isEmpty())
|
||||
{
|
||||
if (!tf.addData(curPath, QByteArray(), true))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tf.addFile(filesRootDir, curPath))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_c_sizeInfo.realSize = 0;
|
||||
for (const FileInformations& file : std::as_const(files))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "file = " << file.inputFileName;
|
||||
emit compressInfo(maxCount, ++count, file.inputFileName);
|
||||
|
||||
DEBUG_LOG(m_logger) << "writing eos";
|
||||
tf.writeEOS();
|
||||
if (m_aborted)
|
||||
return false;
|
||||
|
||||
DEBUG_LOG(m_logger) << "closing bzip";
|
||||
bzip2.close();
|
||||
QString in = file.bAbsInputPath ? file.inputFileName : filesRootDir + QLatin1Char('/') + file.inputFileName;
|
||||
QString out = destRootDir + (file.outputFileName.isEmpty() ? file.inputFileName : file.outputFileName);
|
||||
|
||||
m_c_sizeInfo.compressedSize = output->size();
|
||||
DEBUG_LOG(m_logger) << "m_c_sizeInfo.compressedSize = " << m_c_sizeInfo.compressedSize;
|
||||
DEBUG_LOG(m_logger) << "in = " << in << ", out = " << out;
|
||||
|
||||
m_success = true;
|
||||
QFileInfo fi(in);
|
||||
|
||||
DEBUG_LOG(m_logger) << "DONE!";
|
||||
currentFileName = fi.fileName();
|
||||
currentFileSize = fi.size();
|
||||
m_c_sizeInfo.realSize += currentFileSize;
|
||||
|
||||
return true;
|
||||
DEBUG_LOG(m_logger) << "currentFileName = " << currentFileName << ", currentFileSize = " << currentFileSize
|
||||
<< "m_c_sizeInfo.realSize" << m_c_sizeInfo.realSize;
|
||||
|
||||
if (!tf.addFile(in, out))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const FileInformations& file : std::as_const(memFiles))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "(mem) file = " << file.inputFileName;
|
||||
emit compressInfo(maxCount, ++count, file.inputFileName);
|
||||
|
||||
if (m_aborted)
|
||||
return false;
|
||||
|
||||
currentFileName = file.inputFileName;
|
||||
currentFileSize = file.fileData.size();
|
||||
m_c_sizeInfo.compressedSize += currentFileSize;
|
||||
|
||||
DEBUG_LOG(m_logger) << "(mem) currentFileName = " << currentFileName
|
||||
<< ", currentFileSize = " << currentFileSize << "m_c_sizeInfo.realSize"
|
||||
<< m_c_sizeInfo.realSize;
|
||||
|
||||
if (!tf.addData(file.inputFileName, file.fileData))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "writing eos";
|
||||
tf.writeEOS();
|
||||
|
||||
DEBUG_LOG(m_logger) << "closing bzip";
|
||||
bzip2.close();
|
||||
|
||||
m_c_sizeInfo.compressedSize = output->size();
|
||||
DEBUG_LOG(m_logger) << "m_c_sizeInfo.compressedSize = " << m_c_sizeInfo.compressedSize;
|
||||
|
||||
m_success = true;
|
||||
|
||||
DEBUG_LOG(m_logger) << "DONE!";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Compress::uncompress(QIODevice *in, const QString &outDir)
|
||||
void Compress::uncompress(QIODevice* in, const QString& outDir)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "uncompress #1";
|
||||
reset();
|
||||
setupFutureWatcher(QtConcurrent::run([this, in, outDir](){ return this->_uncompressDirectory(in, outDir); }));
|
||||
DEBUG_LOG(m_logger) << "uncompress #1";
|
||||
reset();
|
||||
setupFutureWatcher(QtConcurrent::run([this, in, outDir]() { return this->_uncompressDirectory(in, outDir); }));
|
||||
}
|
||||
|
||||
bool Compress::_uncompressDirectory(QIODevice *input, const QString &outDir)
|
||||
bool Compress::_uncompressDirectory(QIODevice* input, const QString& outDir)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "_uncompressDirectory";
|
||||
DEBUG_LOG(m_logger) << "_uncompressDirectory";
|
||||
|
||||
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int *)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #2";
|
||||
m_currentTarFilter = nullptr;
|
||||
m_currentBzipDevice = nullptr;
|
||||
});
|
||||
(void)invalidatePointersOnScopeLeave;
|
||||
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int*) {
|
||||
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #2";
|
||||
m_currentTarFilter = nullptr;
|
||||
m_currentBzipDevice = nullptr;
|
||||
});
|
||||
(void)invalidatePointersOnScopeLeave;
|
||||
|
||||
|
||||
if (!input || !input->isReadable())
|
||||
{
|
||||
m_lastError = tr("Device is not readable");
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BZip2IODevice bzip2(input, 9);
|
||||
m_currentBzipDevice = &bzip2;
|
||||
if (!bzip2.open(QIODevice::ReadOnly))
|
||||
{
|
||||
m_lastError = bzip2.errorString();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TarFilter tf(&bzip2);
|
||||
m_currentTarFilter = &tf;
|
||||
TarFilter::FileInformations tfi;
|
||||
QDir dir(outDir);
|
||||
|
||||
DEBUG_LOG(m_logger) << "dir = " << dir.path();
|
||||
|
||||
while (tf.getData(tfi))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "tfi.fileName = " << tfi.fileName;
|
||||
emit uncompressInfo(input->size(), input->pos(), tfi.fileName);
|
||||
if (m_aborted) return false;
|
||||
|
||||
QString path = outDir + QLatin1Char('/') + tfi.fileName;
|
||||
DEBUG_LOG(m_logger) << "path = " << path;
|
||||
if (tfi.fileType == TarFilter::directory)
|
||||
if (!input || !input->isReadable())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "tfi.fileType == TarFilter::directory";
|
||||
if (!dir.exists(path) && !dir.mkpath(path))
|
||||
{
|
||||
m_lastError = tr("Error creating directory %1").arg(outDir);
|
||||
m_lastError = tr("Device is not readable");
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
QString pathName = QFileInfo(path).absolutePath();
|
||||
if (!dir.exists(pathName) && !dir.mkpath(pathName))
|
||||
{
|
||||
m_lastError = tr("Error creating directory %1").arg(pathName);
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
QFile f(path);
|
||||
if (!f.open(QIODevice::WriteOnly))
|
||||
{
|
||||
m_lastError = tr("Error opening %1 for writing (%2)").arg(path, f.errorString());
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!tf.getData(&f))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "uncompress done!";
|
||||
m_success = true;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
BZip2IODevice bzip2(input, 9);
|
||||
m_currentBzipDevice = &bzip2;
|
||||
if (!bzip2.open(QIODevice::ReadOnly))
|
||||
{
|
||||
m_lastError = bzip2.errorString();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TarFilter tf(&bzip2);
|
||||
m_currentTarFilter = &tf;
|
||||
TarFilter::FileInformations tfi;
|
||||
QDir dir(outDir);
|
||||
|
||||
DEBUG_LOG(m_logger) << "dir = " << dir.path();
|
||||
|
||||
while (tf.getData(tfi))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "tfi.fileName = " << tfi.fileName;
|
||||
emit uncompressInfo(input->size(), input->pos(), tfi.fileName);
|
||||
if (m_aborted)
|
||||
return false;
|
||||
|
||||
QString path = outDir + QLatin1Char('/') + tfi.fileName;
|
||||
DEBUG_LOG(m_logger) << "path = " << path;
|
||||
if (tfi.fileType == TarFilter::directory)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "tfi.fileType == TarFilter::directory";
|
||||
if (!dir.exists(path) && !dir.mkpath(path))
|
||||
{
|
||||
m_lastError = tr("Error creating directory %1").arg(outDir);
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
QString pathName = QFileInfo(path).absolutePath();
|
||||
if (!dir.exists(pathName) && !dir.mkpath(pathName))
|
||||
{
|
||||
m_lastError = tr("Error creating directory %1").arg(pathName);
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
QFile f(path);
|
||||
if (!f.open(QIODevice::WriteOnly))
|
||||
{
|
||||
m_lastError = tr("Error opening %1 for writing (%2)").arg(path, f.errorString());
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!tf.getData(&f))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "uncompress done!";
|
||||
m_success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Compress::uncompress(QIODevice *in)
|
||||
void Compress::uncompress(QIODevice* in)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "uncompress #2!";
|
||||
reset();
|
||||
setupFutureWatcher(QtConcurrent::run([this, in](){ return this->_uncompressBuffer(in); }));
|
||||
DEBUG_LOG(m_logger) << "uncompress #2!";
|
||||
reset();
|
||||
setupFutureWatcher(QtConcurrent::run([this, in]() { return this->_uncompressBuffer(in); }));
|
||||
}
|
||||
|
||||
bool Compress::_uncompressBuffer(QIODevice *input)
|
||||
bool Compress::_uncompressBuffer(QIODevice* input)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "uncompressBuffer";
|
||||
DEBUG_LOG(m_logger) << "uncompressBuffer";
|
||||
|
||||
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int *)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #2";
|
||||
m_currentTarFilter = nullptr;
|
||||
m_currentBzipDevice = nullptr;
|
||||
});
|
||||
(void)invalidatePointersOnScopeLeave;
|
||||
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int*) {
|
||||
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #2";
|
||||
m_currentTarFilter = nullptr;
|
||||
m_currentBzipDevice = nullptr;
|
||||
});
|
||||
(void)invalidatePointersOnScopeLeave;
|
||||
|
||||
|
||||
if (!input->isReadable())
|
||||
{
|
||||
m_lastError = tr("Device is not readable");
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BZip2IODevice bzip2(input, 9);
|
||||
m_currentBzipDevice = &bzip2;
|
||||
if (!bzip2.open(QIODevice::ReadOnly))
|
||||
{
|
||||
m_lastError = bzip2.errorString();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TarFilter tf(&bzip2);
|
||||
m_currentTarFilter = &tf;
|
||||
TarFilter::FileInformations tfi;
|
||||
while (tf.getData(tfi))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "tfi.fileName = " << tfi.fileName;
|
||||
emit uncompressInfo(input->size(), input->pos(), tfi.fileName);
|
||||
if (m_aborted) return false;
|
||||
|
||||
FileInformations fi;
|
||||
fi.outputFileName = tfi.fileName;
|
||||
|
||||
DEBUG_LOG(m_logger) << "fi.outputFileName = " << fi.outputFileName;
|
||||
|
||||
if (tfi.fileType == TarFilter::directory)
|
||||
if (!input->isReadable())
|
||||
{
|
||||
fi.outputFileName += QLatin1Char('/');
|
||||
DEBUG_LOG(m_logger) << "> fi.outputFileName = " << fi.outputFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "stuff";
|
||||
m_lastError = tr("Device is not readable");
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
QBuffer buf(&fi.fileData);
|
||||
if (!buf.open(QIODevice::WriteOnly))
|
||||
{
|
||||
m_lastError = tr("Error opening buffer for writing (%1)").arg(buf.errorString());
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!tf.getData(&buf))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fi.bAbsInputPath = fi.outputFileName.startsWith(QLatin1Char('/'));
|
||||
DEBUG_LOG(m_logger) << "added fi.bAbsInputPath = " << fi.bAbsInputPath;
|
||||
m_u2_memFiles += fi;
|
||||
}
|
||||
BZip2IODevice bzip2(input, 9);
|
||||
m_currentBzipDevice = &bzip2;
|
||||
if (!bzip2.open(QIODevice::ReadOnly))
|
||||
{
|
||||
m_lastError = bzip2.errorString();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
m_success = true;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
TarFilter tf(&bzip2);
|
||||
m_currentTarFilter = &tf;
|
||||
TarFilter::FileInformations tfi;
|
||||
while (tf.getData(tfi))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "tfi.fileName = " << tfi.fileName;
|
||||
emit uncompressInfo(input->size(), input->pos(), tfi.fileName);
|
||||
if (m_aborted)
|
||||
return false;
|
||||
|
||||
FileInformations fi;
|
||||
fi.outputFileName = tfi.fileName;
|
||||
|
||||
DEBUG_LOG(m_logger) << "fi.outputFileName = " << fi.outputFileName;
|
||||
|
||||
if (tfi.fileType == TarFilter::directory)
|
||||
{
|
||||
fi.outputFileName += QLatin1Char('/');
|
||||
DEBUG_LOG(m_logger) << "> fi.outputFileName = " << fi.outputFileName;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "stuff";
|
||||
|
||||
QBuffer buf(&fi.fileData);
|
||||
if (!buf.open(QIODevice::WriteOnly))
|
||||
{
|
||||
m_lastError = tr("Error opening buffer for writing (%1)").arg(buf.errorString());
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!tf.getData(&buf))
|
||||
{
|
||||
m_lastError = tf.lastError();
|
||||
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fi.bAbsInputPath = fi.outputFileName.startsWith(QLatin1Char('/'));
|
||||
DEBUG_LOG(m_logger) << "added fi.bAbsInputPath = " << fi.bAbsInputPath;
|
||||
m_u2_memFiles += fi;
|
||||
}
|
||||
|
||||
m_success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Compress::success() const
|
||||
{
|
||||
|
||||
ERROR_LOG(m_logger) << "success? " << (m_future.isFinished() && !m_future.isCanceled() && m_success);
|
||||
ERROR_LOG(m_logger) << "success details: "
|
||||
<< "success m_future.isFinished() = " << (m_future.isFinished())
|
||||
<< " !m_future.isCanceled() = " << !m_future.isCanceled()
|
||||
<< " m_success = " << m_success;
|
||||
return (m_future.isFinished() && !m_future.isCanceled() && m_success);
|
||||
|
||||
ERROR_LOG(m_logger) << "success? " << (m_future.isFinished() && !m_future.isCanceled() && m_success);
|
||||
ERROR_LOG(m_logger) << "success details: "
|
||||
<< "success m_future.isFinished() = " << (m_future.isFinished())
|
||||
<< " !m_future.isCanceled() = " << !m_future.isCanceled() << " m_success = " << m_success;
|
||||
return (m_future.isFinished() && !m_future.isCanceled() && m_success);
|
||||
}
|
||||
|
||||
bool Compress::waitForFinished()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "waitForFinished...";
|
||||
m_future.waitForFinished();
|
||||
DEBUG_LOG(m_logger) << "waitForFinished... done!";
|
||||
return success();
|
||||
DEBUG_LOG(m_logger) << "waitForFinished...";
|
||||
m_future.waitForFinished();
|
||||
DEBUG_LOG(m_logger) << "waitForFinished... done!";
|
||||
return success();
|
||||
}
|
||||
|
||||
QVector<Compress::FileInformations> Compress::directoryFileList(const QString &dir, bool recursive)
|
||||
QVector<Compress::FileInformations> Compress::directoryFileList(const QString& dir, bool recursive)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "directoryFileList";
|
||||
DEBUG_LOG(m_logger) << "directoryFileList";
|
||||
|
||||
QVector<FileInformations> sl_absolute;
|
||||
QDir d(dir);
|
||||
QVector<FileInformations> sl_absolute;
|
||||
QDir d(dir);
|
||||
|
||||
if (d.exists())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "exists";
|
||||
const auto entries = d.entryList(QDir::Files);
|
||||
sl_absolute.reserve(sl_absolute.size() + entries.size());
|
||||
for (const QString &entry : entries)
|
||||
sl_absolute << FileInformations(QFileInfo(d, entry).absoluteFilePath(), true);
|
||||
}
|
||||
if (d.exists())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "exists";
|
||||
const auto entries = d.entryList(QDir::Files);
|
||||
sl_absolute.reserve(sl_absolute.size() + entries.size());
|
||||
for (const QString& entry : entries)
|
||||
sl_absolute << FileInformations(QFileInfo(d, entry).absoluteFilePath(), true);
|
||||
}
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "recursive";
|
||||
const auto entries = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
sl_absolute.reserve(sl_absolute.size() + entries.size());
|
||||
for (const QString &s : entries)
|
||||
sl_absolute << directoryFileList(dir + QLatin1Char('/') + s, true);
|
||||
}
|
||||
if (recursive)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "recursive";
|
||||
const auto entries = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
sl_absolute.reserve(sl_absolute.size() + entries.size());
|
||||
for (const QString& s : entries)
|
||||
sl_absolute << directoryFileList(dir + QLatin1Char('/') + s, true);
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "done";
|
||||
return sl_absolute;
|
||||
DEBUG_LOG(m_logger) << "done";
|
||||
return sl_absolute;
|
||||
}
|
||||
|
||||
void Compress::reset()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "reset";
|
||||
m_u2_memFiles.clear();
|
||||
DEBUG_LOG(m_logger) << "reset";
|
||||
m_u2_memFiles.clear();
|
||||
|
||||
m_lastError.clear();
|
||||
m_lastError.clear();
|
||||
|
||||
m_c_sizeInfo.realSize = 0;
|
||||
m_c_sizeInfo.compressedSize = 0;
|
||||
m_c_sizeInfo.realSize = 0;
|
||||
m_c_sizeInfo.compressedSize = 0;
|
||||
|
||||
m_success = false;
|
||||
m_success = false;
|
||||
}
|
||||
|
||||
void Compress::setupFutureWatcher(const QFuture<bool> &future)
|
||||
void Compress::setupFutureWatcher(const QFuture<bool>& future)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "setupFutureWatcher";
|
||||
m_future = future;
|
||||
QFutureWatcher<bool> *fw = new QFutureWatcher<bool>(this);
|
||||
QObject::connect(fw, &QObject::destroyed, this, [this]() { DEBUG_LOG(m_logger) << "Future Watcher destroyed"; });
|
||||
QObject::connect(fw, &QFutureWatcher<bool>::finished, this, &Compress::finished);
|
||||
QObject::connect(fw, &QFutureWatcher<bool>::finished, fw, &QObject::deleteLater);
|
||||
QObject::connect(fw, &QFutureWatcher<bool>::finished, fw, [this]() { DEBUG_LOG(m_logger) << "Future Watcher about to be deleted"; });
|
||||
fw->setFuture(m_future);
|
||||
DEBUG_LOG(m_logger) << "setupFutureWatcher";
|
||||
m_future = future;
|
||||
QFutureWatcher<bool>* fw = new QFutureWatcher<bool>(this);
|
||||
QObject::connect(fw, &QObject::destroyed, this, [this]() { DEBUG_LOG(m_logger) << "Future Watcher destroyed"; });
|
||||
QObject::connect(fw, &QFutureWatcher<bool>::finished, this, &Compress::finished);
|
||||
QObject::connect(fw, &QFutureWatcher<bool>::finished, fw, &QObject::deleteLater);
|
||||
QObject::connect(fw, &QFutureWatcher<bool>::finished, fw,
|
||||
[this]() { DEBUG_LOG(m_logger) << "Future Watcher about to be deleted"; });
|
||||
fw->setFuture(m_future);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace NGL
|
||||
Executable → Regular
+6
-9
@@ -1,19 +1,16 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "commandinterface.h"
|
||||
#include "sv_export.h"
|
||||
|
||||
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
class TCPSERVER_EXPORT CBI_Help : public CommandInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Help(unsigned short port);
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Help(unsigned short port);
|
||||
|
||||
void handleCommandInternal(const QVector<QByteArray> &args) override;
|
||||
QString help() const override;
|
||||
void handleCommandInternal(const QVector<QByteArray>& args) override;
|
||||
QString help() const override;
|
||||
};
|
||||
Executable → Regular
+6
-9
@@ -1,19 +1,16 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "commandinterface.h"
|
||||
#include "sv_export.h"
|
||||
|
||||
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
class CBI_PingPong : public CommandInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_PingPong(unsigned short port);
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_PingPong(unsigned short port);
|
||||
|
||||
void handleCommandInternal(const QVector<QByteArray> &args) override;
|
||||
QString help() const override;
|
||||
void handleCommandInternal(const QVector<QByteArray>& args) override;
|
||||
QString help() const override;
|
||||
};
|
||||
Executable → Regular
+6
-9
@@ -1,19 +1,16 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "commandinterface.h"
|
||||
#include "sv_export.h"
|
||||
|
||||
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
class TCPSERVER_EXPORT CBI_Quit : public CommandInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Quit(unsigned short port);
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Quit(unsigned short port);
|
||||
|
||||
void handleCommandInternal(const QVector<QByteArray> &args) override;
|
||||
QString help() const override;
|
||||
void handleCommandInternal(const QVector<QByteArray>& args) override;
|
||||
QString help() const override;
|
||||
};
|
||||
Executable → Regular
+12
-10
@@ -1,23 +1,25 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "commandinterface.h"
|
||||
#include "sv_export.h"
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
|
||||
class QIODevice;
|
||||
|
||||
class CBI_Recvfile : public CommandInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Recvfile(unsigned short port);
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Recvfile(unsigned short port);
|
||||
|
||||
void handleCommandInternal(const QVector<QByteArray> &args) override;
|
||||
QString help() const override;
|
||||
void newPlainData() override;
|
||||
protected:
|
||||
QMap<WorkerBase*, QPair<QIODevice*, int> > m_wbMap;
|
||||
void handleCommandInternal(const QVector<QByteArray>& args) override;
|
||||
QString help() const override;
|
||||
void newPlainData() override;
|
||||
|
||||
protected:
|
||||
QMap<WorkerBase*, QPair<QIODevice*, int>> m_wbMap;
|
||||
};
|
||||
Executable → Regular
+6
-7
@@ -1,17 +1,16 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "commandinterface.h"
|
||||
#include "sv_export.h"
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
class CBI_Sendfile : public CommandInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Sendfile(unsigned short port);
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Sendfile(unsigned short port);
|
||||
|
||||
void handleCommandInternal(const QVector<QByteArray> &args) override;
|
||||
QString help() const override;
|
||||
void handleCommandInternal(const QVector<QByteArray>& args) override;
|
||||
QString help() const override;
|
||||
};
|
||||
Executable → Regular
+10
-13
@@ -1,25 +1,22 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "commandinterface.h"
|
||||
#include "sv_export.h"
|
||||
|
||||
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
class TCPSERVER_EXPORT CBI_Shutdown : public CommandInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Shutdown(unsigned short port);
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CBI_Shutdown(unsigned short port);
|
||||
|
||||
void handleCommandInternal(const QVector<QByteArray> &args) override;
|
||||
QString help() const override;
|
||||
void handleCommandInternal(const QVector<QByteArray>& args) override;
|
||||
QString help() const override;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void shutdownRequest();
|
||||
private:
|
||||
void shutdownRequest();
|
||||
|
||||
private:
|
||||
};
|
||||
Executable → Regular
+51
-102
@@ -1,158 +1,107 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
#include "sv_export.h"
|
||||
|
||||
class QAbstractSocket;
|
||||
class QByteArray;
|
||||
class WorkerBase;
|
||||
|
||||
|
||||
class TCPSERVER_EXPORT CommandInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CommandInterface(unsigned short port, const QByteArray& command = QByteArray());
|
||||
|
||||
explicit CommandInterface(unsigned short port, const QByteArray &command = QByteArray());
|
||||
virtual ~CommandInterface();
|
||||
|
||||
|
||||
void handleCommand(const QVector<QByteArray>& args);
|
||||
|
||||
virtual ~CommandInterface();
|
||||
|
||||
virtual void newPlainData();
|
||||
|
||||
void handleCommand(const QVector<QByteArray> &args);
|
||||
|
||||
virtual QString help() const = 0;
|
||||
|
||||
virtual void newPlainData();
|
||||
|
||||
QByteArray command() const;
|
||||
|
||||
virtual QString help() const = 0;
|
||||
|
||||
void setAutoWriteEOL(bool newAutoWriteEOL);
|
||||
|
||||
QByteArray command() const;
|
||||
bool autoWriteEOL() const;
|
||||
|
||||
|
||||
bool errorOccured() const;
|
||||
|
||||
void setAutoWriteEOL(bool newAutoWriteEOL);
|
||||
static void setDefaultSuccessMessage(const QString& msg);
|
||||
|
||||
|
||||
static void setDefaultErrorMessage(const QString& msg);
|
||||
|
||||
bool autoWriteEOL() const;
|
||||
template <class T> static CommandInterface* factory(unsigned short port)
|
||||
{
|
||||
return new T(port);
|
||||
}
|
||||
|
||||
|
||||
virtual void aboutToDestroy() {}
|
||||
|
||||
bool errorOccured() const;
|
||||
protected:
|
||||
virtual void handleCommandInternal(const QVector<QByteArray>& args) = 0;
|
||||
|
||||
|
||||
void setWriteTimeout(int iMS);
|
||||
|
||||
static void setDefaultSuccessMessage(const QString &msg);
|
||||
void writeData(const QByteArray& payload);
|
||||
|
||||
|
||||
void writeData(const char* payload);
|
||||
|
||||
static void setDefaultErrorMessage(const QString &msg);
|
||||
void writeData(const QString& payload);
|
||||
|
||||
template<class T>
|
||||
static CommandInterface *factory(unsigned short port) { return new T(port); }
|
||||
void writeData(const QStringList& payload);
|
||||
|
||||
|
||||
void writeData(const QList<QByteArray>& payload);
|
||||
|
||||
virtual void aboutToDestroy() {}
|
||||
protected:
|
||||
|
||||
void writeOk(const QString& additionalMsg = QString());
|
||||
|
||||
virtual void handleCommandInternal(const QVector<QByteArray> &args) = 0;
|
||||
|
||||
void writeError(const QString& additionalMsg = QString());
|
||||
|
||||
void setWriteTimeout(int iMS);
|
||||
|
||||
void writeEOL();
|
||||
|
||||
void writeData(const QByteArray &payload);
|
||||
|
||||
QByteArray quote(const QByteArray& payload);
|
||||
|
||||
void writeData(const char *payload);
|
||||
|
||||
QAbstractSocket* socket();
|
||||
|
||||
void writeData(const QString &payload);
|
||||
|
||||
void setSocket(QAbstractSocket* socket);
|
||||
|
||||
void writeData(const QStringList &payload);
|
||||
|
||||
WorkerBase* workerBase();
|
||||
|
||||
void writeData(const QList<QByteArray> &payload);
|
||||
|
||||
void setWorkerBase(WorkerBase* wb);
|
||||
|
||||
void writeOk(const QString &additionalMsg = QString());
|
||||
|
||||
void conversionError(const QByteArray& arg, const QByteArray& type);
|
||||
|
||||
void writeError(const QString &additionalMsg = QString());
|
||||
|
||||
bool getValue(const QByteArray& arg, bool& value);
|
||||
|
||||
void writeEOL();
|
||||
|
||||
bool getValue(const QByteArray& arg, long& value);
|
||||
|
||||
QByteArray quote(const QByteArray &payload);
|
||||
|
||||
bool getValue(const QByteArray& arg, unsigned long& value);
|
||||
|
||||
QAbstractSocket *socket();
|
||||
|
||||
bool getValue(const QByteArray& arg, int& value);
|
||||
|
||||
void setSocket(QAbstractSocket *socket);
|
||||
|
||||
bool getValue(const QByteArray& arg, unsigned int& value);
|
||||
|
||||
WorkerBase *workerBase();
|
||||
|
||||
bool getValue(const QByteArray& arg, float& value);
|
||||
|
||||
void setWorkerBase(WorkerBase *wb);
|
||||
|
||||
bool getValue(const QByteArray& arg, double& value);
|
||||
|
||||
void conversionError(const QByteArray &arg, const QByteArray &type);
|
||||
|
||||
unsigned short port() const;
|
||||
|
||||
bool getValue(const QByteArray &arg, bool &value);
|
||||
|
||||
void closeConnection();
|
||||
|
||||
bool getValue(const QByteArray &arg, long &value);
|
||||
|
||||
bool socketIsOpen() const;
|
||||
|
||||
bool getValue(const QByteArray &arg, unsigned long &value);
|
||||
|
||||
private:
|
||||
friend class WorkerBase;
|
||||
|
||||
bool getValue(const QByteArray &arg, int &value);
|
||||
|
||||
class Private;
|
||||
|
||||
bool getValue(const QByteArray &arg, unsigned int &value);
|
||||
|
||||
|
||||
bool getValue(const QByteArray &arg, float &value);
|
||||
|
||||
|
||||
bool getValue(const QByteArray &arg, double &value);
|
||||
|
||||
|
||||
|
||||
unsigned short port() const;
|
||||
|
||||
|
||||
|
||||
void closeConnection();
|
||||
|
||||
|
||||
|
||||
bool socketIsOpen() const;
|
||||
|
||||
private:
|
||||
friend class WorkerBase;
|
||||
|
||||
class Private;
|
||||
|
||||
|
||||
Private *const d;
|
||||
Private* const d;
|
||||
};
|
||||
Executable → Regular
+30
-62
@@ -1,96 +1,64 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QTcpServer>
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
#include "sv_export.h"
|
||||
#include <QTcpServer>
|
||||
|
||||
class WorkerInstance;
|
||||
class CommandInterface;
|
||||
|
||||
|
||||
|
||||
class TCPSERVER_EXPORT TcpServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QVector<CommandInterface*(*)(unsigned short) > CommandInterfaceList;
|
||||
public:
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QVector<CommandInterface* (*)(unsigned short)> CommandInterfaceList;
|
||||
|
||||
virtual ~TcpServer();
|
||||
|
||||
public:
|
||||
virtual ~TcpServer();
|
||||
|
||||
static TcpServer *instance(unsigned short port);
|
||||
static TcpServer* instance(unsigned short port);
|
||||
|
||||
|
||||
bool listen(const QHostAddress& address = QHostAddress::Any);
|
||||
|
||||
bool listen(const QHostAddress &address = QHostAddress::Any);
|
||||
void setUseWorkerThreads(bool bEnable);
|
||||
|
||||
|
||||
bool useWorkerThreads() const;
|
||||
|
||||
void setUseWorkerThreads(bool bEnable);
|
||||
QVector<WorkerInstance*> workers() const;
|
||||
|
||||
|
||||
unsigned short getListenPort() const;
|
||||
|
||||
bool useWorkerThreads() const;
|
||||
static bool registerCommand(unsigned short port, CommandInterface* (*factory)(unsigned short));
|
||||
|
||||
|
||||
static bool unregisterCommand(unsigned short port, CommandInterface* (*factory)(unsigned short));
|
||||
|
||||
QVector<WorkerInstance *> workers() const;
|
||||
static CommandInterfaceList registeredCommands(unsigned short port);
|
||||
|
||||
|
||||
void setUserData(void* userData);
|
||||
|
||||
unsigned short getListenPort() const;
|
||||
void* userData() const;
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
static bool registerCommand(unsigned short port, CommandInterface * (*factory)(unsigned short));
|
||||
void aboutToQuit(unsigned short port);
|
||||
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
static bool unregisterCommand(unsigned short port, CommandInterface * (*factory)(unsigned short));
|
||||
void shutdownRequest();
|
||||
|
||||
|
||||
void workerFinished();
|
||||
|
||||
static CommandInterfaceList registeredCommands(unsigned short port);
|
||||
protected:
|
||||
void incomingConnection(qintptr socketDescriptor);
|
||||
|
||||
|
||||
private:
|
||||
class Private;
|
||||
|
||||
void setUserData(void *userData);
|
||||
Private* const d;
|
||||
|
||||
|
||||
explicit TcpServer(unsigned short port);
|
||||
|
||||
void *userData() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
|
||||
void aboutToQuit(unsigned short port);
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
|
||||
void shutdownRequest();
|
||||
|
||||
|
||||
void workerFinished();
|
||||
|
||||
protected:
|
||||
void incomingConnection(qintptr socketDescriptor);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
|
||||
|
||||
Private *const d;
|
||||
|
||||
explicit TcpServer(unsigned short port);
|
||||
|
||||
|
||||
|
||||
bool listen(const QHostAddress &address, quint16 port);
|
||||
bool listen(const QHostAddress& address, quint16 port);
|
||||
};
|
||||
Executable → Regular
+41
-82
@@ -1,128 +1,87 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tcpserver_export.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QMap>
|
||||
#include <QPointer>
|
||||
#include <QObject>
|
||||
|
||||
#include "sv_export.h"
|
||||
#include <QPointer>
|
||||
|
||||
class QAbstractSocket;
|
||||
class CommandInterface;
|
||||
|
||||
|
||||
|
||||
class TCPSERVER_EXPORT WorkerBase
|
||||
{
|
||||
public:
|
||||
typedef QMap< QByteArray, CommandInterface *> CommandMap;
|
||||
public:
|
||||
|
||||
public:
|
||||
typedef QMap<QByteArray, CommandInterface*> CommandMap;
|
||||
|
||||
WorkerBase(qintptr sd, unsigned short port);
|
||||
|
||||
public:
|
||||
WorkerBase(qintptr sd, unsigned short port);
|
||||
|
||||
virtual ~WorkerBase() = default;
|
||||
|
||||
virtual ~WorkerBase() = default;
|
||||
|
||||
QAbstractSocket *connection();
|
||||
QAbstractSocket* connection();
|
||||
|
||||
|
||||
const QAbstractSocket* connection() const;
|
||||
|
||||
const QAbstractSocket *connection() const;
|
||||
void redirectDataHandling(bool bDoRedirect, CommandInterface* newDataHandler = nullptr);
|
||||
|
||||
|
||||
static QByteArray formatForDebug(const QByteArray& data);
|
||||
|
||||
void redirectDataHandling(bool bDoRedirect, CommandInterface *newDataHandler = nullptr);
|
||||
static QByteArray formatForDebug(const QAbstractSocket* dev);
|
||||
|
||||
|
||||
CommandMap getCommands() const;
|
||||
|
||||
static QByteArray formatForDebug(const QByteArray &data);
|
||||
protected:
|
||||
void newDataInternal();
|
||||
|
||||
|
||||
int initCommands(unsigned short port);
|
||||
|
||||
static QByteArray formatForDebug(const QAbstractSocket *dev);
|
||||
void cleanupCommands();
|
||||
|
||||
|
||||
qintptr m_socketDescriptor;
|
||||
|
||||
CommandMap getCommands() const;
|
||||
QPointer<QAbstractSocket> m_connection;
|
||||
|
||||
protected:
|
||||
|
||||
unsigned short m_port;
|
||||
|
||||
void newDataInternal();
|
||||
|
||||
QByteArray m_connString;
|
||||
|
||||
int initCommands(unsigned short port);
|
||||
bool m_bRedirectIncomingData;
|
||||
|
||||
|
||||
CommandInterface* m_bRedirectDataHandler;
|
||||
|
||||
void cleanupCommands();
|
||||
|
||||
|
||||
|
||||
qintptr m_socketDescriptor;
|
||||
|
||||
|
||||
QPointer<QAbstractSocket> m_connection;
|
||||
|
||||
|
||||
unsigned short m_port;
|
||||
|
||||
|
||||
QByteArray m_connString;
|
||||
|
||||
|
||||
bool m_bRedirectIncomingData;
|
||||
|
||||
|
||||
CommandInterface *m_bRedirectDataHandler;
|
||||
|
||||
|
||||
|
||||
CommandMap m_registeredCommands;
|
||||
CommandMap m_registeredCommands;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class WorkerInstance final : public QObject, public WorkerBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WorkerInstance(qintptr sd, unsigned short port, QObject *parent = nullptr);
|
||||
virtual ~WorkerInstance();
|
||||
Q_OBJECT
|
||||
public:
|
||||
WorkerInstance(qintptr sd, unsigned short port, QObject* parent = nullptr);
|
||||
virtual ~WorkerInstance();
|
||||
|
||||
|
||||
bool isRunning() const;
|
||||
|
||||
bool isRunning() const;
|
||||
|
||||
bool isFinished() const;
|
||||
|
||||
bool isFinished() const;
|
||||
public Q_SLOTS:
|
||||
|
||||
public Q_SLOTS:
|
||||
|
||||
void quit();
|
||||
|
||||
void quit();
|
||||
void doWork();
|
||||
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
void doWork();
|
||||
void newData();
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
void connectionDisconnected();
|
||||
|
||||
void newData();
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished();
|
||||
|
||||
void connectionDisconnected();
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished();
|
||||
|
||||
private:
|
||||
bool m_bFinished;
|
||||
private:
|
||||
bool m_bFinished;
|
||||
};
|
||||
|
||||
@@ -163,25 +163,31 @@ MACRO(INSTALL_SHARED_FILES srcList)
|
||||
ENDMACRO()
|
||||
|
||||
MACRO(CODEGEN_SQL srcList xmlFile_in)
|
||||
_GET_SERVICENAME( "${xmlFile_in}" svcNameOut )
|
||||
SET(out_dir_sql "${CMAKE_BINARY_DIR}/share/Lts/sql/")
|
||||
SET(out_file_sql "${out_dir_sql}/${svcNameOut}.sql")
|
||||
SET(action "SQL")
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${out_file_sql}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E make_directory ${out_dir_sql}
|
||||
COMMAND ngl_codegen
|
||||
ARGS -s ${xmlFile_in}
|
||||
-a ${action}
|
||||
-o ${out_dir_sql}
|
||||
-i ${CMAKE_BINARY_DIR}/service_idl_files.txt
|
||||
DEPENDS ngl_codegen ${xmlFile_in}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
LIST(APPEND ${srcList} ${out_file_sql})
|
||||
IF(BUILD_GRANTLEE)
|
||||
_GET_SERVICENAME( "${xmlFile_in}" svcNameOut )
|
||||
SET(out_dir_sql "${CMAKE_BINARY_DIR}/share/Lts/sql/")
|
||||
SET(out_file_sql "${out_dir_sql}/${svcNameOut}.sql")
|
||||
SET(action "SQL")
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${out_file_sql}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E make_directory ${out_dir_sql}
|
||||
COMMAND ngl_codegen
|
||||
ARGS -s ${xmlFile_in}
|
||||
-a ${action}
|
||||
-o ${out_dir_sql}
|
||||
-i ${CMAKE_BINARY_DIR}/service_idl_files.txt
|
||||
DEPENDS ngl_codegen ${xmlFile_in}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
LIST(APPEND ${srcList} ${out_file_sql})
|
||||
|
||||
|
||||
NGL_INSTALL(SV AAR FILES ${out_file_sql} DESTINATION share/Lts/sql)
|
||||
|
||||
NGL_INSTALL(SV AAR FILES ${out_file_sql} DESTINATION share/Lts/sql)
|
||||
ELSE()
|
||||
# BUILD_GRANTLEE disabled: skip SQL generation
|
||||
# SQL files will not be generated; modules may need pre-generated SQL files
|
||||
MESSAGE(STATUS "BUILD_GRANTLEE disabled: skipping SQL generation for ${xmlFile_in}")
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
|
||||
MACRO(CODEGEN_HANDLE_SVC_XML srcList xmlFile_in)
|
||||
|
||||
Executable → Regular
+172
-187
@@ -1,59 +1,56 @@
|
||||
/**
|
||||
* Logger interface
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
* Logger interface
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QPointF>
|
||||
#include <QSize>
|
||||
#include <QRect>
|
||||
#include <QRectF>
|
||||
#include <QList>
|
||||
#include "ngllogger_export.h"
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <ngllogger_export.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
// keep in sync with log4qt/level.h
|
||||
enum class LogLevel
|
||||
{
|
||||
Undefined = 0,
|
||||
Trace = 64,
|
||||
Debug = 96,
|
||||
Info = 128,
|
||||
Warning = 150,
|
||||
Error = 182,
|
||||
Fatal = 214,
|
||||
enum class LogLevel {
|
||||
Undefined = 0,
|
||||
Trace = 64,
|
||||
Debug = 96,
|
||||
Info = 128,
|
||||
Warning = 150,
|
||||
Error = 182,
|
||||
Fatal = 214,
|
||||
};
|
||||
|
||||
class LogStreamHelper
|
||||
{
|
||||
public:
|
||||
inline LogStreamHelper(INGLLogger &logger, LogLevel level, const char *const file, int line, const char *const function)
|
||||
: m_logger(logger)
|
||||
, m_level(level)
|
||||
, m_line(line)
|
||||
, m_file(file)
|
||||
, m_func(function)
|
||||
{}
|
||||
inline ~LogStreamHelper(); // after INGLLogger class definition
|
||||
public:
|
||||
inline LogStreamHelper(INGLLogger& logger, LogLevel level, const char* const file, int line,
|
||||
const char* const function)
|
||||
: m_logger(logger), m_level(level), m_line(line), m_file(file), m_func(function)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline LogStreamHelper &operator<<(const T &val);
|
||||
inline ~LogStreamHelper(); // after INGLLogger class definition
|
||||
|
||||
private:
|
||||
std::ostringstream m_buffer;
|
||||
NGL::INGLLogger &m_logger;
|
||||
const LogLevel m_level;
|
||||
const int m_line;
|
||||
const char *const m_file;
|
||||
const char *const m_func;
|
||||
template <typename T> inline LogStreamHelper& operator<<(const T& val);
|
||||
|
||||
private:
|
||||
std::ostringstream m_buffer;
|
||||
NGL::INGLLogger& m_logger;
|
||||
const LogLevel m_level;
|
||||
const int m_line;
|
||||
const char* const m_file;
|
||||
const char* const m_func;
|
||||
};
|
||||
|
||||
// Interface class for source code logging.
|
||||
@@ -64,58 +61,64 @@ private:
|
||||
// information on logger-hierarchies, logging-levels, and configuration files.
|
||||
class INGLLogger
|
||||
{
|
||||
public:
|
||||
INGLLogger(const INGLLogger &) = delete;
|
||||
INGLLogger &operator=(const INGLLogger &) = delete;
|
||||
INGLLogger() = default;
|
||||
virtual ~INGLLogger() = default;
|
||||
public:
|
||||
INGLLogger(const INGLLogger&) = delete;
|
||||
INGLLogger& operator=(const INGLLogger&) = delete;
|
||||
INGLLogger() = default;
|
||||
virtual ~INGLLogger() = default;
|
||||
|
||||
using String = std::string;
|
||||
using String = std::string;
|
||||
|
||||
// Creates an instance of an INGLLogger interface. The fullqualifiedname is
|
||||
// a dottet sequence (i.e. "NGL.thisandthat.mylogger"). The same name will
|
||||
// always return the same interface-instance. It is not required to create
|
||||
// the parent nodes.
|
||||
virtual INGLLogger &getNGLLogger(const char *fullqualifiedname) = 0;
|
||||
virtual INGLLogger &getNGLLogger(const std::string &fullqualifiedname) = 0;
|
||||
// Creates an instance of an INGLLogger interface. The fullqualifiedname is
|
||||
// a dottet sequence (i.e. "NGL.thisandthat.mylogger"). The same name will
|
||||
// always return the same interface-instance. It is not required to create
|
||||
// the parent nodes.
|
||||
virtual INGLLogger& getNGLLogger(const char* fullqualifiedname) = 0;
|
||||
virtual INGLLogger& getNGLLogger(const std::string& fullqualifiedname) = 0;
|
||||
|
||||
// True if this level is enabled.
|
||||
virtual bool isTraceEnabled() const = 0;
|
||||
virtual bool isDebugEnabled() const = 0;
|
||||
virtual bool isInfoEnabled() const = 0;
|
||||
virtual bool isWarningEnabled() const = 0;
|
||||
virtual bool isErrorEnabled() const = 0;
|
||||
virtual bool isFatalEnabled() const = 0;
|
||||
virtual bool isLevelEnabled(LogLevel level) const = 0;
|
||||
|
||||
// True if this level is enabled.
|
||||
virtual bool isTraceEnabled() const = 0;
|
||||
virtual bool isDebugEnabled() const = 0;
|
||||
virtual bool isInfoEnabled() const = 0;
|
||||
virtual bool isWarningEnabled() const = 0;
|
||||
virtual bool isErrorEnabled() const = 0;
|
||||
virtual bool isFatalEnabled() const = 0;
|
||||
virtual bool isLevelEnabled(LogLevel level) const = 0;
|
||||
// Submit a LOG message.
|
||||
// Use __FILE__ and __NAME__ macros.
|
||||
virtual void log(LogLevel level, const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
|
||||
// Submit a LOG message.
|
||||
// Use __FILE__ and __NAME__ macros.
|
||||
virtual void log(LogLevel level, const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an TRACE message.
|
||||
virtual void logTrace(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit an DEBUG message.
|
||||
virtual void logDebug(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit an INFO message.
|
||||
virtual void logInfo(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit a WARNING message.
|
||||
virtual void logWarning(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit an ERROR message.
|
||||
virtual void logError(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
// Submit a FATAL message.
|
||||
virtual void logFatal(const INGLLogger::String& message, const char* file = nullptr, int line = -1,
|
||||
const char* function = nullptr) = 0;
|
||||
|
||||
// Submit an TRACE message.
|
||||
virtual void logTrace(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an DEBUG message.
|
||||
virtual void logDebug(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an INFO message.
|
||||
virtual void logInfo(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit a WARNING message.
|
||||
virtual void logWarning(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit an ERROR message.
|
||||
virtual void logError(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Submit a FATAL message.
|
||||
virtual void logFatal(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
|
||||
// Writes a startup message into the logfile
|
||||
virtual void logStartup(const char* file, int line, const char* function = nullptr) = 0;
|
||||
// Writes a shutdown message into the logfile
|
||||
virtual void logShutdown(const char* file, int line, const char* function = nullptr) = 0;
|
||||
|
||||
// Writes a startup message into the logfile
|
||||
virtual void logStartup(const char *file, int line, const char *function = nullptr) = 0;
|
||||
// Writes a shutdown message into the logfile
|
||||
virtual void logShutdown(const char *file, int line, const char *function = nullptr) = 0;
|
||||
// Get this loggers fullqualified name.
|
||||
virtual std::string getLoggerName() const = 0;
|
||||
|
||||
// Get this loggers fullqualified name.
|
||||
virtual std::string getLoggerName() const = 0;
|
||||
|
||||
virtual void setNoSpace(bool bNoSpace) = 0;
|
||||
virtual bool noSpace() const = 0;
|
||||
virtual void setNoSpace(bool bNoSpace) = 0;
|
||||
virtual bool noSpace() const = 0;
|
||||
};
|
||||
|
||||
//
|
||||
@@ -123,112 +126,90 @@ public:
|
||||
//
|
||||
inline LogStreamHelper::~LogStreamHelper()
|
||||
{
|
||||
m_logger.log(m_level, m_buffer.str(), m_file, m_line, m_func);
|
||||
m_logger.log(m_level, m_buffer.str(), m_file, m_line, m_func);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline LogStreamHelper &LogStreamHelper::operator<<(const T &val)
|
||||
template <typename T> inline LogStreamHelper& LogStreamHelper::operator<<(const T& val)
|
||||
{
|
||||
m_buffer << val;
|
||||
if (!m_logger.noSpace())
|
||||
m_buffer << " ";
|
||||
return *this;
|
||||
m_buffer << val;
|
||||
if (!m_logger.noSpace())
|
||||
m_buffer << " ";
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace NGL
|
||||
|
||||
} //namespace NGL
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const QByteArray &str)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QByteArray& str)
|
||||
{
|
||||
stream << std::string(str.data(), str.size());
|
||||
return stream;
|
||||
stream << std::string(str.data(), str.size());
|
||||
return stream;
|
||||
}
|
||||
|
||||
//
|
||||
// operator to ease logging (at least via NglLogging)
|
||||
//
|
||||
inline std::ostream &operator<<(std::ostream &stream,
|
||||
const QPointF &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QPointF& value)
|
||||
{
|
||||
stream << "QPointF(" << QString::number(value.x(), 'f', 6).toStdString() << "#" << QString::number(value.y(), 'f', 6).toStdString() << ")";
|
||||
return stream;
|
||||
stream << "QPointF(" << QString::number(value.x(), 'f', 6).toStdString() << "#"
|
||||
<< QString::number(value.y(), 'f', 6).toStdString() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QPoint &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QPoint& value)
|
||||
{
|
||||
stream << "QPoint(" << value.x() << "#" << value.y() << ")";
|
||||
return stream;
|
||||
stream << "QPoint(" << value.x() << "#" << value.y() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QSize &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QSize& value)
|
||||
{
|
||||
stream << "QSize(w=" << value.width() << ";h=" << value.height() << ")";
|
||||
return stream;
|
||||
}
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QSizeF &value)
|
||||
{
|
||||
stream << "QSize(w="
|
||||
<< QString::number(value.width(), 'f', 6).toStdString() << ";h="
|
||||
<< QString::number(value.height(), 'f', 6).toStdString()
|
||||
<< ")";
|
||||
return stream;
|
||||
stream << "QSize(w=" << value.width() << ";h=" << value.height() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QRect &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QSizeF& value)
|
||||
{
|
||||
stream << "QRect(center=" << value.center()
|
||||
<< " w=" << value.width()
|
||||
<< ";h=" << value.height()
|
||||
<< " bottomLeft=" << value.bottomLeft()
|
||||
<< " topRight=" << value.topRight()
|
||||
<< ")";
|
||||
return stream;
|
||||
stream << "QSize(w=" << QString::number(value.width(), 'f', 6).toStdString()
|
||||
<< ";h=" << QString::number(value.height(), 'f', 6).toStdString() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QRectF &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QRect& value)
|
||||
{
|
||||
stream << "QRectF(center=" << value.center()
|
||||
<< " w=" << QString::number(value.width(), 'f', 3).toStdString()
|
||||
<< ";h=" << QString::number(value.height(), 'f', 3).toStdString()
|
||||
<< " bottomLeft=" << value.bottomLeft()
|
||||
<< " topRight=" << value.topRight()
|
||||
<< ")";
|
||||
return stream;
|
||||
stream << "QRect(center=" << value.center() << " w=" << value.width() << ";h=" << value.height()
|
||||
<< " bottomLeft=" << value.bottomLeft() << " topRight=" << value.topRight() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QList<int> &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QRectF& value)
|
||||
{
|
||||
stream << "QList<int>(" << value.size() << "): ";
|
||||
for (int i : value)
|
||||
stream << i << ";";
|
||||
return stream;
|
||||
stream << "QRectF(center=" << value.center() << " w=" << QString::number(value.width(), 'f', 3).toStdString()
|
||||
<< ";h=" << QString::number(value.height(), 'f', 3).toStdString() << " bottomLeft=" << value.bottomLeft()
|
||||
<< " topRight=" << value.topRight() << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &stream,
|
||||
const QList<QPointF> &value)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QList<int>& value)
|
||||
{
|
||||
stream << "QList<QPointF>(" << value.size() << "): ";
|
||||
for (const QPointF &item : value)
|
||||
stream << item << ";";
|
||||
return stream;
|
||||
stream << "QList<int>(" << value.size() << "): ";
|
||||
for (int i : value)
|
||||
stream << i << ";";
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &stream, const QString &str)
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QList<QPointF>& value)
|
||||
{
|
||||
return stream << str.toUtf8();
|
||||
stream << "QList<QPointF>(" << value.size() << "): ";
|
||||
for (const QPointF& item : value)
|
||||
stream << item << ";";
|
||||
return stream;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream, const QString& str)
|
||||
{
|
||||
return stream << str.toUtf8();
|
||||
}
|
||||
|
||||
namespace NGL
|
||||
@@ -236,15 +217,12 @@ namespace NGL
|
||||
|
||||
namespace NGLLoggerHelper
|
||||
{
|
||||
NGLLOGGER_EXPORT void hexDumpHelper(NGL::INGLLogger &logger,
|
||||
NGL::LogLevel level,
|
||||
const void *a_data,
|
||||
NGLLOGGER_EXPORT void hexDumpHelper(NGL::INGLLogger& logger, NGL::LogLevel level, const void* a_data,
|
||||
const unsigned int a_size);
|
||||
inline void hexDumpHelper(NGL::INGLLogger &logger,
|
||||
NGL::LogLevel level,
|
||||
const QByteArray &data)
|
||||
|
||||
inline void hexDumpHelper(NGL::INGLLogger& logger, NGL::LogLevel level, const QByteArray& data)
|
||||
{
|
||||
return hexDumpHelper(logger, level, data.data(), data.size());
|
||||
return hexDumpHelper(logger, level, data.data(), data.size());
|
||||
}
|
||||
} // namespace NGLLoggerHelper
|
||||
|
||||
@@ -260,41 +238,46 @@ NGLLOGGER_EXPORT std::string getMemoryData();
|
||||
#define LOGFUNCTION Q_FUNC_INFO
|
||||
|
||||
// log this output every time, no matter what log level is enabled
|
||||
#define NOTICE_LOG(logger) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define NOTICE_LOG(logger) NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
#define TRACE_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isTraceEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define TRACE_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isTraceEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
#else
|
||||
#define TRACE_LOG(logger) \
|
||||
for ( ; false; ) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define TRACE_LOG(logger) \
|
||||
for (; false;) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
#endif
|
||||
|
||||
#define DEBUG_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isDebugEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Debug, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define DEBUG_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isDebugEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Debug, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define INFO_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define INFO_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define WARNING_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isWarningEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Warning, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define WARNING_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isWarningEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Warning, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define ERROR_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isErrorEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Error, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define ERROR_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isErrorEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Error, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define FATAL_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isFatalEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Fatal, __FILE__,__LINE__, Q_FUNC_INFO)
|
||||
#define FATAL_LOG(logger) \
|
||||
for (bool log_level_enabled = (logger).isFatalEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(logger, NGL::LogLevel::Fatal, __FILE__, __LINE__, Q_FUNC_INFO)
|
||||
|
||||
#define STARTUP_LOG(logger) { (logger).logStartup(__FILE__, __LINE__, Q_FUNC_INFO); }
|
||||
#define SHUTDOWN_LOG(logger) { (logger).logShutdown(__FILE__, __LINE__, Q_FUNC_INFO); }
|
||||
#define STARTUP_LOG(logger) \
|
||||
{ \
|
||||
(logger).logStartup(__FILE__, __LINE__, Q_FUNC_INFO); \
|
||||
}
|
||||
#define SHUTDOWN_LOG(logger) \
|
||||
{ \
|
||||
(logger).logShutdown(__FILE__, __LINE__, Q_FUNC_INFO); \
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
||||
@@ -303,8 +286,10 @@ NGLLOGGER_EXPORT std::string getMemoryData();
|
||||
// do something nasty
|
||||
// MEMORY_LOG() << " after something nasty";
|
||||
|
||||
#define MEMORY_LOG() \
|
||||
for (bool log_level_enabled = (NGL::getMemoryLogger()).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(NGL::getMemoryLogger(), NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO) << NGL::getMemoryData()
|
||||
#define MEMORY_LOG() \
|
||||
for (bool log_level_enabled = (NGL::getMemoryLogger()).isInfoEnabled(); log_level_enabled; \
|
||||
log_level_enabled = false) \
|
||||
NGL::LogStreamHelper(NGL::getMemoryLogger(), NGL::LogLevel::Info, __FILE__, __LINE__, Q_FUNC_INFO) \
|
||||
<< NGL::getMemoryData()
|
||||
|
||||
//==============================================================================
|
||||
@@ -13,7 +13,7 @@ if(NOT TARGET GTest::gtest_main)
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
||||
GIT_TAG release-1.13.0
|
||||
GIT_TAG v1.13.0
|
||||
)
|
||||
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||
@@ -31,6 +31,7 @@ if(BUILD_TESTING)
|
||||
test_symbology_xml.cpp
|
||||
test_saa_telegrams.cpp
|
||||
test_rti_integration.cpp
|
||||
test_ltswidgets_qt6.cpp
|
||||
)
|
||||
|
||||
# Check which files actually exist
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @file test_ltswidgets_qt6.cpp
|
||||
* @brief Tests für LtsWidgets Qt6-Migration
|
||||
*
|
||||
* Tests verify Qt6 API compatibility changes:
|
||||
* 1. QRandomGenerator usage (replacing qrand())
|
||||
* 2. Signal/slot connections with Qt6 signatures
|
||||
* 3. QWheelEvent angleDelta() usage
|
||||
* 4. QStyleOption::initFrom() usage
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <QRandomGenerator>
|
||||
#include <QComboBox>
|
||||
#include <QWheelEvent>
|
||||
#include <QStyleOption>
|
||||
#include <QPushButton>
|
||||
#include <QApplication>
|
||||
|
||||
// Ensure QApplication is initialized for widget tests
|
||||
static bool appInitialized = false;
|
||||
static void ensureAppInitialized() {
|
||||
if (!appInitialized) {
|
||||
static int argc = 1;
|
||||
static char* argv[] = { (char*)"test_ltswidgets_qt6", nullptr };
|
||||
static QApplication app(argc, argv);
|
||||
appInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Test 1: QRandomGenerator bounded generation (used in lts_tab_widget.cpp)
|
||||
TEST(LtsWidgetsQt6, QRandomGeneratorBounded) {
|
||||
auto* generator = QRandomGenerator::global();
|
||||
ASSERT_NE(generator, nullptr);
|
||||
|
||||
// Test multiple bounded calls to ensure stability
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
int value = generator->bounded(10);
|
||||
EXPECT_GE(value, 0);
|
||||
EXPECT_LT(value, 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Test 2: QRandomGenerator produces different values
|
||||
TEST(LtsWidgetsQt6, QRandomGeneratorVariation) {
|
||||
auto* generator = QRandomGenerator::global();
|
||||
|
||||
QVector<int> values;
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
values.append(generator->bounded(1000));
|
||||
}
|
||||
|
||||
// Check that we get some variation (not all same value)
|
||||
bool hasDifferent = false;
|
||||
for (int i = 1; i < values.size(); ++i) {
|
||||
if (values[i] != values[0]) {
|
||||
hasDifferent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(hasDifferent);
|
||||
}
|
||||
|
||||
// Test 3: QRandomGenerator seeded reproducibility
|
||||
TEST(LtsWidgetsQt6, QRandomGeneratorSeeded) {
|
||||
QRandomGenerator gen1(12345);
|
||||
QRandomGenerator gen2(12345);
|
||||
|
||||
// Same seed should produce same sequence
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
EXPECT_EQ(gen1.bounded(1000), gen2.bounded(1000));
|
||||
}
|
||||
}
|
||||
|
||||
// Test 4: QComboBox currentTextChanged signal (Qt6 compatible)
|
||||
// This tests the signal used in lts_text_editor.cpp
|
||||
TEST(LtsWidgetsQt6, QComboBoxCurrentTextChangedSignal) {
|
||||
ensureAppInitialized();
|
||||
|
||||
QComboBox comboBox;
|
||||
comboBox.addItem("Option1");
|
||||
comboBox.addItem("Option2");
|
||||
comboBox.addItem("Option3");
|
||||
|
||||
bool signalReceived = false;
|
||||
QString receivedText;
|
||||
|
||||
QObject::connect(&comboBox, &QComboBox::currentTextChanged,
|
||||
[&signalReceived, &receivedText](const QString& text) {
|
||||
signalReceived = true;
|
||||
receivedText = text;
|
||||
});
|
||||
|
||||
comboBox.setCurrentIndex(1);
|
||||
|
||||
EXPECT_TRUE(signalReceived);
|
||||
EXPECT_EQ(receivedText, "Option2");
|
||||
}
|
||||
|
||||
// Test 5: QComboBox activated signal with int parameter (Qt6)
|
||||
// Note: activated signal is only emitted on user interaction, not on setCurrentIndex
|
||||
TEST(LtsWidgetsQt6, QComboBoxActivatedIntSignal) {
|
||||
ensureAppInitialized();
|
||||
|
||||
QComboBox comboBox;
|
||||
comboBox.addItem("First");
|
||||
comboBox.addItem("Second");
|
||||
comboBox.addItem("Third");
|
||||
|
||||
bool signalReceived = false;
|
||||
int receivedIndex = -1;
|
||||
|
||||
// Connect using Qt6 syntax - activated emits int index
|
||||
QObject::connect(&comboBox, QOverload<int>::of(&QComboBox::activated),
|
||||
[&signalReceived, &receivedIndex](int index) {
|
||||
signalReceived = true;
|
||||
receivedIndex = index;
|
||||
});
|
||||
|
||||
// Simulate user interaction by emitting the signal manually
|
||||
// (setCurrentIndex does not trigger activated signal)
|
||||
QMetaObject::invokeMethod(&comboBox, "activated", Qt::QueuedConnection, Q_ARG(int, 2));
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
// Verify the connection works with int parameter
|
||||
EXPECT_TRUE(signalReceived);
|
||||
EXPECT_EQ(receivedIndex, 2);
|
||||
}
|
||||
|
||||
// Test 6: QStyleOption::initFrom() (Qt6 replacement for init())
|
||||
// This tests the API used in lts_notification_box.cpp
|
||||
TEST(LtsWidgetsQt6, QStyleOptionInitFrom) {
|
||||
ensureAppInitialized();
|
||||
|
||||
QPushButton button("Test");
|
||||
button.resize(100, 30);
|
||||
button.setEnabled(true);
|
||||
|
||||
QStyleOption opt;
|
||||
opt.initFrom(&button);
|
||||
|
||||
// Verify initFrom sets up the option correctly
|
||||
// State_Enabled should be set (among other states)
|
||||
EXPECT_TRUE(opt.state & QStyle::State_Enabled);
|
||||
EXPECT_FALSE(opt.rect.isNull());
|
||||
}
|
||||
|
||||
// Test 7: QStyleOption multiple widgets
|
||||
TEST(LtsWidgetsQt6, QStyleOptionInitFromMultipleWidgets) {
|
||||
ensureAppInitialized();
|
||||
|
||||
QPushButton button1("Btn1");
|
||||
QPushButton button2("Btn2");
|
||||
button1.setEnabled(true);
|
||||
button2.setEnabled(false);
|
||||
|
||||
QStyleOption opt1;
|
||||
opt1.initFrom(&button1);
|
||||
|
||||
QStyleOption opt2;
|
||||
opt2.initFrom(&button2);
|
||||
|
||||
// Verify different widget states are captured
|
||||
EXPECT_TRUE(opt1.state & QStyle::State_Enabled);
|
||||
EXPECT_FALSE(opt2.state & QStyle::State_Enabled);
|
||||
}
|
||||
|
||||
// Test 8: QWheelEvent angleDelta() availability
|
||||
// This verifies the API used in lts_date_time_edit_p.cpp
|
||||
TEST(LtsWidgetsQt6, QWheelEventAngleDelta) {
|
||||
ensureAppInitialized();
|
||||
|
||||
QPoint pos(100, 100);
|
||||
QPoint globalPos(200, 200);
|
||||
QPoint pixelDelta(0, 0);
|
||||
QPoint angleDelta(0, 120); // Standard wheel step
|
||||
|
||||
QWheelEvent wheelEvent(pos, globalPos, pixelDelta, angleDelta,
|
||||
Qt::NoButton, Qt::NoModifier,
|
||||
Qt::NoScrollPhase, false);
|
||||
|
||||
// Verify angleDelta() is accessible and returns correct value
|
||||
QPoint delta = wheelEvent.angleDelta();
|
||||
EXPECT_EQ(delta.y(), 120);
|
||||
EXPECT_EQ(delta.x(), 0);
|
||||
}
|
||||
|
||||
// Test 9: QWheelEvent negative angleDelta
|
||||
TEST(LtsWidgetsQt6, QWheelEventNegativeAngleDelta) {
|
||||
ensureAppInitialized();
|
||||
|
||||
QPoint pos(100, 100);
|
||||
QPoint globalPos(200, 200);
|
||||
QPoint pixelDelta(0, 0);
|
||||
QPoint angleDelta(0, -120); // Scroll down
|
||||
|
||||
QWheelEvent wheelEvent(pos, globalPos, pixelDelta, angleDelta,
|
||||
Qt::NoButton, Qt::NoModifier,
|
||||
Qt::NoScrollPhase, false);
|
||||
|
||||
QPoint delta = wheelEvent.angleDelta();
|
||||
EXPECT_EQ(delta.y(), -120);
|
||||
|
||||
// Test the logic used in lts_date_time_edit_p.cpp
|
||||
bool isUp = delta.y() > 0;
|
||||
EXPECT_FALSE(isUp);
|
||||
}
|
||||
|
||||
// Test 10: QWheelEvent angleDelta direction detection
|
||||
TEST(LtsWidgetsQt6, QWheelEventDirectionDetection) {
|
||||
ensureAppInitialized();
|
||||
|
||||
// Simulate wheel up (positive delta)
|
||||
QPoint angleDeltaUp(0, 120);
|
||||
QWheelEvent wheelUp(QPoint(0, 0), QPoint(0, 0), QPoint(0, 0), angleDeltaUp,
|
||||
Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
|
||||
EXPECT_TRUE(wheelUp.angleDelta().y() > 0);
|
||||
|
||||
// Simulate wheel down (negative delta)
|
||||
QPoint angleDeltaDown(0, -120);
|
||||
QWheelEvent wheelDown(QPoint(0, 0), QPoint(0, 0), QPoint(0, 0), angleDeltaDown,
|
||||
Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false);
|
||||
EXPECT_FALSE(wheelDown.angleDelta().y() > 0);
|
||||
}
|
||||
Reference in new issue
Block a user