first commit

This commit is contained in:
amneiht 2025-03-15 10:17:05 +07:00
commit 0b2333ee14
58 changed files with 3436 additions and 0 deletions

5
.gitinorge Normal file
View file

@ -0,0 +1,5 @@
*.user.*
.*
build/
*.o

66
CMakeLists.txt Normal file
View file

@ -0,0 +1,66 @@
cmake_minimum_required(VERSION 3.20)
project(chat LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(QPACKAGE Core Gui Qml Quick QuickControls2)
find_package(QT NAMES Qt5 Qt6 REQUIRED COMPONENTS ${QPACKAGE} )
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS ${QPACKAGE})
# lazy add file
#file(GLOB_RECURSE BASE_DIR "src/base/*.cpp" "src/base/*.h")
#file(GLOB_RECURSE INCLUDE_DIR "include/*.h" )
# file(GLOB_RECURSE CHAT_SRC "src/*.cpp")
# file(GLOB_RECURSE CHAT_HDR "include/*.h")
set(QML_IMPORT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/qml" CACHE STRING "Path used to locate CMake modules by Qt Creator" FORCE)
set(QML2_IMPORT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/qml" CACHE STRING "Path used to locate CMake modules by Qt Creator" FORCE)
set(QT_PLUGIN_PATH "${CMAKE_CURRENT_SOURCE_DIR}/qml" )
set(QML_SOURCE_PATH "qml/")
set(QML_MODULES_PATH "qml/")
add_executable(chat
src/deltachat/account.h src/deltachat/account.cpp
src/deltachat/context.h src/deltachat/context.cpp
src/deltachat/message.h src/deltachat/message.cpp
src/deltachat/event.h src/deltachat/event.cpp
src/deltachat/contact.h src/deltachat/contact.cpp
src/deltachat/chat.h src/deltachat/chat.cpp
src/deltachat/chatlist.h src/deltachat/chatlist.cpp
src/deltachat/lot.h src/deltachat/lot.cpp
src/deltachat/eventemitter.h src/deltachat/eventemitter.cpp
src/main.cpp
src/app/msgshow.h src/app/msgshow.cpp
src/deltachat/deltacpp.h
src/app/task.h src/app/task.cpp
src/app/acc.h src/app/acc.cpp
src/app/app.h
src/app/send.h src/app/send.cpp
src/app/contactui.h src/app/contactui.cpp
src/app/chatui.h src/app/chatui.cpp
resource.qrc
src/model/chat/chatproxymodel.h src/model/chat/chatproxymodel.cpp
src/model/chat/chatlistmodel.h src/model/chat/chatlistmodel.cpp
src/model/chat/chatcore.h src/model/chat/chatcore.cpp
src/model/chat/chatroommodel.h src/model/chat/chatroommodel.cpp
src/model/chat/messagemodel.h src/model/chat/messagemodel.cpp
)
target_include_directories(chat PRIVATE "./include" "./src")
foreach( PACK IN LISTS QPACKAGE )
target_link_libraries(chat Qt${QT_VERSION_MAJOR}::${PACK} )
endforeach()
include(GNUInstallDirs)
install(TARGETS chat
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
find_package(Deltachat REQUIRED)
target_link_libraries(chat Deltachat)

467
CMakeLists.txt.user Normal file
View file

@ -0,0 +1,467 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 15.0.1, 2025-03-14T17:17:45. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{de1076e9-327b-449c-9243-94dce3154b24}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="qlonglong">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap">
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
<value type="bool" key="AutoTest.Framework.Boost">true</value>
<value type="bool" key="AutoTest.Framework.CTest">false</value>
<value type="bool" key="AutoTest.Framework.Catch">true</value>
<value type="bool" key="AutoTest.Framework.GTest">true</value>
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
</valuemap>
<value type="bool" key="AutoTest.ApplyFilter">false</value>
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
<value type="int" key="AutoTest.RunAfterBuild">0</value>
<value type="bool" key="AutoTest.UseGlobal">true</value>
<valuemap type="QVariantMap" key="ClangTools">
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
<value type="int" key="ClangTools.ParallelJobs">6</value>
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
</valuemap>
<valuemap type="QVariantMap" key="CppEditor.QuickFix">
<value type="bool" key="UseGlobalSettings">true</value>
</valuemap>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.2 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.2 GCC 64bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5152.gcc_64_kit</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="CMake.Build.Type">Debug</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Debug
-DCMAKE_GENERATOR:STRING=Ninja
-DLINPHONE_SDK:STRING=/home/amneiht/app/workspace/lib/linphone/release/x64
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX};/home/amneiht/app/workspace/lib/delta_chat/build/output
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/mnt/ramdisk/build/deltachat/Desktop_Qt_5_15_2_GCC_64bit-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="CMake.Build.Type">Release</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=Release
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/mnt/ramdisk/build/deltachat/Desktop_Qt_5_15_2_GCC_64bit-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/mnt/ramdisk/build/deltachat/Desktop_Qt_5_15_2_GCC_64bit-RelWithDebInfo</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value>
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/mnt/ramdisk/build/deltachat/Desktop_Qt_5_15_2_GCC_64bit-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
<value type="QString" key="CMake.Build.Type">MinSizeRel</value>
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_BUILD_TYPE:STRING=MinSizeRel
-DCMAKE_GENERATOR:STRING=Ninja
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
-DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG}
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/mnt/ramdisk/build/deltachat/Desktop_Qt_5_15_2_GCC_64bit-MinSizeRel</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">all</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString">clean</value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">5</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
<value type="QString"></value>
</valuelist>
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.CMakePackageStep</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="QString" key="ApplicationManagerPlugin.Deploy.InstallPackageStep.Arguments">install-package --acknowledge</value>
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Install Application Manager package</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.InstallPackageStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.Configuration</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">chat</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">chat</value>
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">true</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseTerminal">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/mnt/ramdisk/build/deltachat/Desktop_Qt_5_15_2_GCC_64bit-Debug</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">22</value>
</data>
<data>
<variable>Version</variable>
<value type="int">22</value>
</data>
</qtcreator>

20
cmake/FindDeltachat.cmake Normal file
View file

@ -0,0 +1,20 @@
#custom find deltachat
set(DeltaDIR "/home/amneiht/app/workspace/lib/delta_chat/arm64")
# cmake_policy(SET CMP0074 OLD)
# find_path(Deltachat_INCLUDE_DIR NAMES deltachat.h PATHS ${DeltaDIR} PATH_SUFFIXES include NO_DEFAULT_PATH )
# find_library(Deltachat_LIBS NAMES deltachat PATHS ${DeltaDIR} PATH_SUFFIXES lib )
set(Deltachat_INCLUDE_DIR ${DeltaDIR}/include )
set(Deltachat_LIBS ${DeltaDIR}/lib/libdeltachat.so )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Deltachat DEFAULT_MSG Deltachat_INCLUDE_DIR Deltachat_LIBS)
if ( Deltachat_FOUND )
add_library(Deltachat INTERFACE IMPORTED)
target_include_directories(Deltachat INTERFACE ${Deltachat_INCLUDE_DIR})
target_link_libraries(Deltachat INTERFACE ${Deltachat_LIBS} dl pthread m)
message("Set config")
else()
message("No deltachat found")
endif()

14
qml/DCStyle/ChatStyle.qml Normal file
View file

@ -0,0 +1,14 @@
pragma Singleton
import QtQml 2.2
// import QtQuick 2.0
QtObject {
property QtObject list: QtObject {
property int viewWidth: 50
property color scolor: "lightgreen"
property color ucolor: "white"
property color pcolor: "black"
property int psize : 3
}
}

21
qml/DCStyle/MessStyle.qml Normal file
View file

@ -0,0 +1,21 @@
pragma Singleton
import QtQml 2.2
QtObject {
property QtObject mess: QtObject {
property color background: "lightgray"
property QtObject incoming: QtObject {
property color color: "lightgreen"
}
property QtObject outgoing: QtObject {
property color color: "white"
}
}
property QtObject margin: QtObject {
property int maxsize : 50
property int border : 10
property int padding : border * 2
}
}

6
qml/DCStyle/qmldir Normal file
View file

@ -0,0 +1,6 @@
# See: https://wiki.qt.io/Qml_Styling
module DCStyle
# qml style
singleton ChatStyle 1.0 ChatStyle.qml
singleton MessStyle 1.0 MessStyle.qml

48
qml/chat/ChatList.qml Normal file
View file

@ -0,0 +1,48 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.2
import Dcchat 1.0
import DCStyle 1.0
Item {
id: chatlist
anchors.fill: parent
property int cindex : 0
RowLayout {
// view panel
anchors.fill: parent
spacing: 0
ChatListView {
// list view
id: chatlistview
Layout.fillHeight: true
width: 240
}
Rectangle {
color: ChatStyle.list.pcolor
width: ChatStyle.list.psize
Layout.fillHeight: true
}
Loader {
id : chatContend
z:2
asynchronous : true
Layout.fillHeight: true
Layout.fillWidth: true
}
}
function setSource(id){
chatContend.setSource("MessageArea.qml", {"chat_id": id ,})
}
Connections {
target: chatlistview
function onIdChange(id)
{
// set chat id to show
chatContend.source = ""
Qt.callLater(setSource , id)
}
}
}

39
qml/chat/ChatListItem.qml Normal file
View file

@ -0,0 +1,39 @@
import QtQuick 2.15
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.3
import DCStyle 1.0
Rectangle {
required property string $name
required property int $chatid
Layout.fillWidth: true
height: ChatStyle.list.viewWidth
color: ChatStyle.list.ucolor
Text {
id :stext
Layout.fillWidth: true
Layout.fillHeight: true
verticalAlignment : Text.AlignVCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
list.idChange($chatid)
color = ChatStyle.list.scolor
}
}
Component.onCompleted:{
stext.text = $name
}
Connections {
target: list
function onIdChange(pid){
if(pid !== $chatid)
color = ChatStyle.list.ucolor
}
}
}

50
qml/chat/ChatListView.qml Normal file
View file

@ -0,0 +1,50 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.2
import Dcchat 1.0
Rectangle {
// detachat
id: list
signal idChange(int id)
ChatListModel {
id : lmodel
}
Item {
id: bar
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: search.height
z:1
TextField {
id: search
anchors.top: parent.top
anchors.left: parent.left
anchors.right: btn.right
}
Button {
id :btn
anchors.top: parent.top
anchors.right: parent.right
width: 30
text: "tk"
}
}
ListView {
id: view
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.top: bar.bottom
spacing: 1
model: lmodel
delegate: ChatListItem {
width: parent.width
}
}
}

12
qml/chat/MessageArea.js Normal file
View file

@ -0,0 +1,12 @@
function viewChange() {
view.positionViewAtEnd()
}
function loadMoreData(){
var dtx = view.contentHeight
var lastindex = model.loadMoredata()
view.positionViewAtIndex(lastindex,ListView.Beginning)
}

108
qml/chat/MessageArea.qml Normal file
View file

@ -0,0 +1,108 @@
import QtQuick 2.15
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import Dcchat 1.0
import DCStyle 1.0
import "MessageArea.js" as MS
Rectangle {
// default property alias data: view.data
id: mess_area
required property int chat_id
signal loadMoreData();
property alias model: model
color: MessStyle.mess.background
Layout.fillWidth: true
ChatRoomModel {
id:model
chatid: chat_id
}
MessageModel {
id:mess
chatid: chat_id
}
ColumnLayout {
anchors.fill: parent
Rectangle {
Layout.fillWidth: true
height: 40
color: "green"
z:2
Text {
id: banner
anchors.fill: parent
color: "white"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
ListView {
id:view
Layout.fillHeight: true
Layout.fillWidth: true
model : model
spacing: 1
delegate: MessageItem {
width: mess_area.width
}
cacheBuffer:20
//for ScrollBar
ScrollBar.vertical: ScrollBar {
id: scroll_bar
parent: parent
}
}
Rectangle {
// send bare
z:2
Layout.fillWidth: true
height: 30
RowLayout {
anchors.fill: parent
TextArea {
id : local
height: parent.height
Layout.fillWidth: true
}
Button {
id : btn
text: "send"
onClicked: {
mess.sendText(local.text)
local.text = ""
}
}
}
}
}
// load more message when scroll at end
Connections {
target: view
function onMovementEnded(){
if(view.atYBeginning )
{
MS.loadMoreData()
}
}
}
// handle when have incomming mess
Connections {
target: model
function onUpdateData(){
if( view.atYEnd )
{
Qt.callLater(MS.viewChange)
}
}
}
Component.onCompleted:
{
// view.model = model
banner.text = model.chatName()
view.positionViewAtEnd()
}
}

35
qml/chat/MessageItem.qml Normal file
View file

@ -0,0 +1,35 @@
import QtQuick 2.15
import QtQuick.Layouts 1.0
import DCStyle 1.0
Item{
// mode data
id: _mess
required property bool $local
required property string $text
required property string $user
required property date $date
// width: text.width
height: text.height + MessStyle.margin.padding
Layout.fillWidth: true
Rectangle {
id:rec
// chang size of x
x : $local ? parent.width - rec.width - MessStyle.margin.padding : MessStyle.margin.padding
color: $local ? MessStyle.mess.incoming.color : MessStyle.mess.outgoing.color
radius: 5
width: text.contentWidth + MessStyle.margin.padding
height: text.height + MessStyle.margin.padding
Text {
y: MessStyle.margin.border
x: MessStyle.margin.border
id : text
width: _mess.width - MessStyle.margin.maxsize
text: $text
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
}
}
}

14
qml/main.qml Normal file
View file

@ -0,0 +1,14 @@
import QtQuick 2.15
import QtQuick.Controls 2.0
import "./chat"
ApplicationWindow {
id:main
width: 1600
height: 800
visible: true
title: "lmao"
ChatList {
anchors.fill: parent
}
}

14
resource.qrc Normal file
View file

@ -0,0 +1,14 @@
<RCC>
<qresource prefix="/">
<file>qml/main.qml</file>
<file>qml/chat/ChatList.qml</file>
<file>qml/chat/ChatListView.qml</file>
<file>qml/chat/ChatListItem.qml</file>
<file>qml/DCStyle/ChatStyle.qml</file>
<file>qml/DCStyle/qmldir</file>
<file>qml/chat/MessageArea.qml</file>
<file>qml/chat/MessageItem.qml</file>
<file>qml/DCStyle/MessStyle.qml</file>
<file>qml/chat/MessageArea.js</file>
</qresource>
</RCC>

118
src/app/acc.cpp Normal file
View file

@ -0,0 +1,118 @@
#include "acc.h"
#include "task.h"
#include <QTextStream>
#include <deltachat/deltacpp.h>
using namespace dc;
Acc::Acc(Task* parent)
: QObject { parent }
, ts(stdout)
{
connect(parent, &Task::processInput, this, &Acc::proccsesInput);
}
void Acc::showUser()
{
auto list = Account::getInstance()->getAll();
ts << "Show user" << Qt::endl;
if (list.size() == 0) {
ts << "\tNo aviable user" << Qt::endl;
return;
}
for (auto acc : list) {
auto ctx = Account::getInstance()->getAccount(acc);
QString info = ctx->getConfig("addr");
ts << "\tId:" << acc << "\tUser: " << info << Qt::endl;
}
ts << "\n\tCurent user: " << Account::getInstance()->getSelectedAccount()->getConfig("addr")
<< Qt::endl;
}
void Acc::addUser(const QStringList& qm)
{
if (qm.size() < 4) {
ts << "Error:Not enought variable" << Qt::endl;
}
QString mail = qm.at(2);
QString pass = qm.at(3);
// new acc
auto manager = Account::getInstance();
auto id = manager->addAcount();
auto ctx = manager->getAccount(id);
ctx->setConfig("addr", mail);
ctx->setConfig("mail_pw", pass);
if (1) {
// local config
auto list = mail.split("@");
QString ser = "mail." + list.at(1);
// config imap
ctx->setConfig("mail_server", ser);
ctx->setConfig("mail_user", mail);
ctx->setConfig("mail_port", "143");
// smtp config
ctx->setConfig("send_server", ser);
ctx->setConfig("send_user", mail);
ctx->setConfig("send_pw", pass);
ctx->setConfig("send_port", "465");
}
ctx->configure();
ts << "\tUser is add" << Qt::endl;
}
void Acc::rmUser(const QStringList& qm)
{
QTextStream ts(stdout);
if (qm.size() < 3)
return;
uint32_t id = qm.at(2).toInt();
Account::getInstance()->removeAccount(id);
ts << "\tUser is removed" << Qt::endl;
}
void Acc::showHelp()
{
ts << "User Command" << Qt::endl;
ts << "\tuser show : show all user\n";
ts << "\tuser detail <id> : show full detail for user\n";
ts << "\tuser add <mail addr> <mail pass>: ADD USER\n";
ts << "\tuser use <id>: select it to default account\n";
ts << "\tuser rm <id>: remove user";
ts << Qt::endl;
}
void Acc::useUser(const QStringList& qm)
{
if (qm.size() < 3)
return;
uint32_t id = qm.at(2).toInt();
Account::getInstance()->setSelectAccount(id);
ts << "\tDefalt user set to id :" << id << Qt::endl;
}
void Acc::showQr(const QString& id)
{
int cid = id.toInt();
auto ctx = Account::getInstance()->getAccount(cid);
ts << "\tQrcode is: " << ctx->getSecurejoinQr(0) << Qt::endl;
}
void Acc::proccsesInput(const QStringList& qm)
{
auto cmd = qm.at(0);
if (cmd == "help") {
showHelp();
return;
} else if (cmd != "user")
return;
cmd = qm.at(1);
if (cmd == "show")
showUser();
else if (cmd == "add")
addUser(qm);
else if (cmd == "rm")
rmUser(qm);
else if (cmd == "use")
useUser(qm);
else if (cmd == "detail" && qm.size() == 3)
showQr(qm.at(2));
}

29
src/app/acc.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef ACC_H
#define ACC_H
#include <QObject>
#include <QTextStream>
class Task;
class Acc : public QObject
{
Q_OBJECT
private:
QTextStream ts;
public:
explicit Acc(Task *parent);
public slots:
void proccsesInput(const QStringList &qm);
private:
void showUser();
void addUser(const QStringList &qm);
void rmUser(const QStringList &qm);
void showHelp();
void useUser(const QStringList &qm);
void showQr(const QString &id);
};
#endif // ACC_H

11
src/app/app.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef APP_H
#define APP_H
#include "acc.h"
#include "chatui.h"
#include "contactui.h"
#include "msgshow.h"
#include "send.h"
#include "task.h"
#endif // APP_H

156
src/app/chatui.cpp Normal file
View file

@ -0,0 +1,156 @@
#include "chatui.h"
#include "task.h"
#include <deltachat/deltacpp.h>
ChatUi::ChatUi(Task* parent)
: QObject { parent }
, ts(stdout)
{
connect(parent, &Task::processInput, this, &ChatUi::proccsesInput);
}
void ChatUi::proccsesInput(const QStringList& qm)
{
if (qm.at(0) == "help") {
showHelp();
return;
}
if (qm.at(0) != "chat") {
return;
}
if (qm.size() < 2)
return;
auto cmd = qm.at(1);
if (cmd == "show") {
showChat();
} else if (cmd == "create") {
createWithContact(qm);
} else if (cmd == "remove") {
if (qm.size() == 3)
chatRemove(qm.at(2));
} else if (cmd == "group") {
if (qm.size() < 4)
return;
auto cmd2 = qm.at(3);
if (cmd2 == "create") {
createGroup(qm);
} else if (cmd2 == "add") {
addUser(qm);
} else if (cmd2 == "rm") {
rmUser(qm);
}
} else if (cmd == "send") {
chatSend(qm);
} else if (cmd == "list" && qm.size() == 3) {
listMess(qm.at(2));
} else {
ts << "Wrong command , using help for detail";
}
}
void ChatUi::showHelp()
{
ts << "Chat Command\n";
ts << "\tchat show : show avaible chat and id\n";
ts << "\tchat create <contact_id> : create a chat with contact id\n";
ts << "\tchat send <chat_id> \"mess\": send message to chat with id\n";
ts << "\tchat list <chat_id>: see last 10 message in chat with id\n";
ts << "\tchat remove <chat_id> : remove chat id\n";
ts << "\tchat group create <name>: create a group chat with name\n";
ts << "\tchat group add <chat_id> <contact_id>: add contact id to group chat\n";
ts << "\tchat group rm <chat_id> <contact_id>: remove contact id from group chat";
ts << Qt::endl;
}
void ChatUi::showChat()
{
auto ctx = dc::Account::getInstance()->getSelectedAccount();
auto chatlist = ctx->getChatlist(0, "");
int d = chatlist->getChatCount();
for (int i = 0; i < d; i++) {
int id = chatlist->getChatId(i);
auto chat = ctx->getChat(id);
ts << "\tChat Id: " << id << "\twith name" << chat->getName() << Qt::endl;
}
}
void ChatUi::createWithContact(const QStringList& qm)
{
if (qm.size() < 3) {
ts << "\tNot enought arument" << Qt::endl;
return;
}
int id = qm.at(2).toInt();
auto ctx = dc::Account::getInstance()->getSelectedAccount();
int rid = ctx->createChatByContactId(id);
ts << "\tNew chat is created with Id: " << id << Qt::endl;
}
void ChatUi::createGroup(const QStringList& qm)
{
auto name = qm.at(3);
auto ctx = dc::Account::getInstance()->getSelectedAccount();
int id = ctx->createGroupChat(name, false);
ts << "\tNew group chat is created with Id: " << id << Qt::endl;
}
void ChatUi::chatRemove(const QString& id)
{
int cid = id.toInt();
auto ctx = dc::Account::getInstance()->getSelectedAccount();
ctx->deleteChat(cid);
ts << "\tChat id " << id << "is delete" << Qt::endl;
}
void ChatUi::addUser(const QStringList& qm)
{
if (qm.size() != 5)
return;
int chat_id = qm.at(3).toInt();
int contact_id = qm.at(4).toInt();
auto ctx = dc::Account::getInstance()->getSelectedAccount();
ctx->addContactToChat(chat_id, contact_id);
ts << "\tContact " << contact_id << "is added to group" << Qt::endl;
}
void ChatUi::rmUser(const QStringList& qm)
{
if (qm.size() != 5)
return;
int chat_id = qm.at(3).toInt();
int contact_id = qm.at(4).toInt();
auto ctx = dc::Account::getInstance()->getSelectedAccount();
ctx->removeContactFromChat(chat_id, contact_id);
ts << "\tContact " << contact_id << "is remove from group" << Qt::endl;
}
void ChatUi::chatSend(const QStringList& qm)
{
if (qm.size() != 4) {
ts << "wrong command" << Qt::endl;
return;
}
int chat_id = qm.at(2).toInt();
auto mess = qm.at(3);
auto ctx = dc::Account::getInstance()->getSelectedAccount();
ctx->sendTextMessage(chat_id, mess);
}
void ChatUi::listMess(const QString& id)
{
int chat_id = id.toInt();
auto ctx = dc::Account::getInstance()->getSelectedAccount();
auto list = ctx->getMsgIdList(chat_id);
int v = list.count() - 10;
if (list.count() == 0) {
ts << "\tNo Mess in Chat " << Qt::endl;
return;
}
if (v < 0)
v = 0;
for (; v < list.count(); v++) {
auto mid = list.at(v);
auto msg = ctx->getMessage(mid);
ts << "\tMess: " << msg->getText() << Qt::endl;
}
}

30
src/app/chatui.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef CHATUI_H
#define CHATUI_H
#include <QObject>
#include <QTextStream>
class Task;
class ChatUi : public QObject
{
Q_OBJECT
QTextStream ts;
public:
explicit ChatUi(Task *parent);
public slots:
void proccsesInput(const QStringList &qm);
private:
void showHelp();
void showChat();
void createWithContact(const QStringList &qm);
void createGroup(const QStringList &qm);
void chatRemove(const QString &id);
void addUser(const QStringList &qm);
void rmUser(const QStringList &qm);
void chatSend(const QStringList &qm);
void listMess(const QString &id);
};
#endif // CHATUI_H

61
src/app/contactui.cpp Normal file
View file

@ -0,0 +1,61 @@
#include "contactui.h"
#include "task.h"
#include <deltachat/deltacpp.h>
ContactUi::ContactUi(Task* parent)
: QObject { parent }
, ts(stdout)
{
connect(parent, &Task::processInput, this, &ContactUi::proccsesInput);
}
void ContactUi::proccsesInput(const QStringList& qm)
{
if (qm.at(0) == "help") {
showHelp();
return;
}
if (qm.at(0) != "contact" || qm.size() < 2) {
return;
}
QString qs = qm.at(1);
if (qs == "show") {
listContact();
} else if (qs == "rm" && qm.size() == 3) {
removeContact(qm.at(2));
} else if (qs == "add" && qm.size() == 4) {
addContact(qm.at(2), qm.at(3));
}
}
void ContactUi::showHelp()
{
ts << "Contact comad:\n";
ts << "\tcontact show : show all contact\n";
ts << "\tcontact add <name> <mail_addr> : add contact\n";
ts << "\tcontact rm <id> : remove contact with id";
ts << Qt::endl;
}
void ContactUi::listContact()
{
auto ctx = dc::Account::getInstance()->getSelectedAccount();
auto list = ctx->getContacts(0, nullptr);
for (auto id : list) {
auto contact = ctx->getContact(id);
ts << "\tId:" << id << "\taddr:" << contact->getAddr() << Qt::endl;
}
}
void ContactUi::addContact(const QString& name, const QString& addr)
{
auto ctx = dc::Account::getInstance()->getSelectedAccount();
ctx->createContact(name, addr);
ts << "\tContact is added" << Qt::endl;
}
void ContactUi::removeContact(const QString& id)
{
uint32_t cid = id.toInt();
auto ctx = dc::Account::getInstance()->getSelectedAccount();
ctx->deleteContact(cid);
}

26
src/app/contactui.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef CONTACTUI_H
#define CONTACTUI_H
#include <QObject>
#include <QTextStream>
class Task;
class ContactUi : public QObject
{
Q_OBJECT
private:
QTextStream ts;
public:
explicit ContactUi(Task *parent);
public slots:
void proccsesInput(const QStringList &qm);
private:
void showHelp();
void listContact();
void addContact(const QString &name, const QString &addr);
void removeContact(const QString &id);
};
#endif // CONTACTUI_H

24
src/app/msgshow.cpp Normal file
View file

@ -0,0 +1,24 @@
#include "msgshow.h"
#include <QDebug>
#include <deltachat/deltacpp.h>
MsgShow::MsgShow() {}
void MsgShow::onIncomingMessage(uint32_t accountId, int chatId, int msgId)
{
auto acc = dc::Account::getInstance();
auto ctx = acc->getAccount(accountId);
auto msg = ctx->getMessage(msgId);
auto text = msg->getText();
qDebug() << "\tYou Got:" << text;
// auto chat = ctx->getChat(chatId);
// int info = msg->getInfoType();
// if (!chat->isProtected()) {
// auto qr = ctx->getSecurejoinQr(0);
// msg = ctx->newMessage(DC_MSG_TEXT);
// msg->setSubject("ENCRYPT_INFO");
// msg->setText(qr);
// ctx->sendMessage(chatId, msg);
// }
}

16
src/app/msgshow.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef MSGSHOW_H
#define MSGSHOW_H
#include <QObject>
class MsgShow : public QObject
{
Q_OBJECT
public:
MsgShow();
public slots:
void onIncomingMessage(uint32_t accountId, int chatId, int msgId);
};
#endif // MSGSHOW_H

7
src/app/send.cpp Normal file
View file

@ -0,0 +1,7 @@
#include "send.h"
#include "task.h"
Send::Send(Task *parent)
: QObject{parent}
{}
void Send::proccsesInput(const QStringList &qm) {}

19
src/app/send.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef SEND_H
#define SEND_H
#include <QObject>
class Task;
class Send : public QObject
{
Q_OBJECT
public:
explicit Send(Task *parent);
public slots:
void proccsesInput(const QStringList &qm);
private:
void send_mess(const QStringList &qm);
};
#endif // SEND_H

88
src/app/task.cpp Normal file
View file

@ -0,0 +1,88 @@
#include "task.h"
#include <QDebug>
#include <QTextStream>
Task::Task()
{
isrun = true;
connect(this, &Task::processInput, this, &Task::check);
}
static QStringList praseLine(const QString& line)
{
QStringList ret;
QString data = "";
bool quote = false;
for (int i = 0; i < line.count(); i++) {
auto c = line.at(i);
if (quote) {
if (c == '"') {
quote = false;
if (data != "") {
ret.append(data);
data = "";
}
} else {
data.append(c);
}
} else {
if (c == '"') {
quote = true;
} else {
if (c == ' ') {
if (data != "") {
ret.append(data);
data = "";
}
} else {
data.append(c);
}
}
}
}
if (data != "") {
ret.append(data);
}
return ret;
}
void Task::run()
{
QTextStream stream(stdin);
QString line = "";
fd_set rfds;
struct timeval tv;
int retval;
tv.tv_sec = 1; // Timeout: 1 seconds
tv.tv_usec = 0;
do {
FD_ZERO(&rfds);
FD_SET(fileno(stdin), &rfds);
retval = select(fileno(stdin) + 1, &rfds, NULL, NULL, &tv);
if (retval) {
line = stream.readLine();
if (line != "") {
QStringList qlist = praseLine(line);
emit processInput(qlist);
}
}
} while (isrun);
emit finish();
}
void Task::check(const QStringList& qm)
{
if (qm.at(0) == "q") {
this->isrun = 0;
} else if (qm.at(0) == "help") {
QTextStream ts(stdout);
ts << "\tq: quit application" << Qt::endl;
}
}
void Task::disablerun()
{
isrun = false;
}

23
src/app/task.h Normal file
View file

@ -0,0 +1,23 @@
#ifndef TASK_H
#define TASK_H
#include <QMap>
#include <QThread>
class Task : public QThread {
Q_OBJECT
bool isrun = true;
public:
Task();
void run();
void check(const QStringList& qm);
void disablerun();
signals:
void processInput(const QStringList& qm);
void finish();
};
#endif // TASK_H

224
src/deltachat/account.cpp Normal file
View file

@ -0,0 +1,224 @@
#include "account.h"
#include <QDebug>
#include <QStandardPaths>
#include "chat.h"
#include "context.h"
#include "event.h"
#include "eventemitter.h"
namespace dc {
std::shared_ptr<Account> Account::inst = nullptr;
Account::Account()
{
QString path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
const int writeable = true;
m_accounts = dc_accounts_new(path.toUtf8().constData(), writeable);
// install emiter
m_emit = new EventEmitter(dc_accounts_get_event_emitter(m_accounts));
}
Account::Account(QString path)
{
const int writeable = true;
m_accounts = dc_accounts_new(path.toUtf8().constData(), writeable);
// install emiter
m_emit = new EventEmitter(dc_accounts_get_event_emitter(m_accounts));
}
Account::~Account()
{
stopIo();
dc_accounts_unref(m_accounts);
m_emit->wait();
delete m_emit;
}
void Account::init(QString datapath)
{
if (datapath.isEmpty())
inst = std::shared_ptr<Account>(new Account());
else
inst = std::shared_ptr<Account>(new Account(datapath));
qRegisterMetaType<size_t>("size_t");
qRegisterMetaType<uint32_t>("uint32_t");
}
void Account::close()
{
inst = nullptr;
}
std::shared_ptr<Account> Account::getInstance()
{
return inst;
}
void Account::startIo()
{
dc_accounts_start_io(m_accounts);
}
void Account::stopIo()
{
dc_accounts_stop_io(m_accounts);
}
void Account::maybeNetWork()
{
dc_accounts_maybe_network(m_accounts);
}
void Account::maybeNetWorkLost()
{
dc_accounts_maybe_network_lost(m_accounts);
}
void Account::backgroundFetch(uint64_t timeout)
{
dc_accounts_background_fetch(m_accounts, timeout);
}
std::shared_ptr<Context> Account::getAccount(uint32_t id)
{
dc_context_t *ctx = dc_accounts_get_account(m_accounts, id);
if (ctx != nullptr) {
auto acc = std::shared_ptr<Context>(new Context(ctx));
return acc;
} else
return nullptr;
}
std::shared_ptr<Context> Account::getSelectedAccount()
{
dc_context_t *ctx = dc_accounts_get_selected_account(m_accounts);
if (ctx != nullptr) {
auto acc = std::shared_ptr<Context>(new Context(ctx));
return acc;
} else
return nullptr;
}
void Account::setSelectAccount(uint32_t id)
{
dc_accounts_select_account(m_accounts, id);
}
void Account::removeAccount(uint32_t id)
{
dc_accounts_remove_account(m_accounts, id);
}
uint32_t Account::addAcount()
{
return dc_accounts_add_account(m_accounts);
}
QList<uint32_t> Account::getAll()
{
dc_array_t *arr = dc_accounts_get_all(m_accounts);
QList<uint32_t> id;
for (int i = 0; i < dc_array_get_cnt(arr); i++) {
id.append(dc_array_get_id(arr, i));
}
dc_array_unref(arr);
return id;
}
void Account::startEventLoop()
{
// start io
startIo();
connect(m_emit, &EventEmitter::gotEvent, this, &Account::processEvent, Qt::DirectConnection);
m_emit->start();
}
std::shared_ptr<Context> Account::getUser(const QString &addr)
{
auto list = getAll();
for (auto id : list) {
auto ctx = getAccount(id);
if (ctx->getConfig("addr") == addr) {
return ctx;
}
}
return nullptr;
}
void Account::processEvent(QSharedPointer<Event> event)
{
int acc_id;
std::shared_ptr<Context> ctx;
std::shared_ptr<Chat> chat;
switch (event->getId()) {
/*
case DC_EVENT_SMTP_CONNECTED:
qInfo("SMTP connected: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_IMAP_CONNECTED:
qInfo("IMAP connected: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_SMTP_MESSAGE_SENT:
qInfo("SMTP message sent: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_IMAP_MESSAGE_DELETED:
qInfo("IMAP message deleted: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_IMAP_MESSAGE_MOVED:
qInfo("IMAP message moved: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_NEW_BLOB_FILE:
qInfo("New blob file: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_DELETED_BLOB_FILE:
qInfo("Deleted blob file: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_ERROR_SELF_NOT_IN_GROUP:
qCritical("Self not in group error: %s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_INFO:
qInfo("%s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_WARNING:
qWarning("%s", qUtf8Printable(event->getData2Str()));
break;
case DC_EVENT_ERROR:
qCritical("%s", qUtf8Printable(event->getData2Str()));
break;
//*/
case DC_EVENT_CHAT_MODIFIED:
emit chatModified(event->getAccountId(), event->getData1Int());
break;
case DC_EVENT_MSGS_CHANGED:
emit messagesChanged(event->getAccountId(), event->getData1Int(), event->getData2Int());
break;
case DC_EVENT_INCOMING_MSG:
ctx = Account::getInstance()->getAccount(event->getAccountId());
chat = ctx->getChat(event->getData1Int());
if (chat->isContactRequest()) {
ctx->acceptChat(event->getData1Int());
}
emit incomingMessage(event->getAccountId(), event->getData1Int(), event->getData2Int());
break;
case DC_EVENT_MSGS_NOTICED:
emit messagesNoticed(event->getAccountId(), event->getData1Int());
break;
case DC_EVENT_CONFIGURE_PROGRESS:
emit configureProgress(event->getAccountId(), event->getData1Int(), event->getData2Str());
acc_id = event->getAccountId();
if (event->getData1Int() == 1000) {
ctx = Account::getInstance()->getAccount(acc_id);
ctx->startIo();
}
break;
case DC_EVENT_IMEX_PROGRESS:
emit imexProgress(event->getAccountId(), event->getData1Int());
break;
default:
// qDebug() << "Not processing " << event->getId();
break;
}
}
} // namespace dc

73
src/deltachat/account.h Normal file
View file

@ -0,0 +1,73 @@
#ifndef ACCOUNT_H
#define ACCOUNT_H
#include "deltachat.h"
#include <QList>
#include <QObject>
#include <QSharedPointer>
#include <memory>
namespace dc {
class Context;
class Event;
class EventEmitter;
class Account : public QObject {
Q_OBJECT
private:
dc_accounts_t* m_accounts;
static std::shared_ptr<Account> inst;
EventEmitter* m_emit;
public:
Account();
Account(QString datapath);
~Account();
// init some proprey of deltachat
static void init(QString datapath);
// close library
static void close();
static std::shared_ptr<Account> getInstance();
// warper funtion
void startIo();
void stopIo();
// network
void maybeNetWork();
void maybeNetWorkLost();
// fetch
void backgroundFetch(uint64_t timeout);
// account
std::shared_ptr<Context> getAccount(uint32_t id);
std::shared_ptr<Context> getSelectedAccount();
void setSelectAccount(uint32_t id);
void removeAccount(uint32_t id);
uint32_t addAcount();
QList<uint32_t> getAll();
// custom funtion
void startEventLoop();
std::shared_ptr<Context> getUser(const QString& addr);
public slots:
void processEvent(QSharedPointer<Event> evt);
signals:
void chatModified(uint32_t accountId, int chatId);
void configureProgress(uint32_t accountId, int progress, QString comment);
void imexProgress(uint32_t accountId, int progress);
void incomingMessage(uint32_t accountId, int chatId, int msgId);
void messagesChanged(uint32_t accountId, int chatId, int msgId);
void messagesNoticed(uint32_t accountId, int chatId);
// for detail
void outGoingMessage(uint32_t accountId, int chatId);
};
} // namespace dc
#endif // ACCOUNT_H

69
src/deltachat/chat.cpp Normal file
View file

@ -0,0 +1,69 @@
#include "chat.h"
using namespace dc;
Chat::Chat(dc_chat_t *chat)
: QObject{nullptr}
, m_chat{chat}
{}
Chat::~Chat()
{
dc_chat_unref(m_chat);
}
uint32_t Chat::getId()
{
return dc_chat_get_id(m_chat);
}
int Chat::getType()
{
return dc_chat_get_type(m_chat);
}
QString Chat::getName()
{
char *name = dc_chat_get_name(m_chat);
QString result{name};
dc_str_unref(name);
return result;
}
QString Chat::getProfileImage()
{
char *profileImage = dc_chat_get_profile_image(m_chat);
QString result{profileImage};
dc_str_unref(profileImage);
return result;
}
bool Chat::isContactRequest()
{
return dc_chat_is_contact_request(m_chat);
}
bool Chat::canSend()
{
return dc_chat_can_send(m_chat);
}
bool Chat::isMuted()
{
return dc_chat_is_muted(m_chat);
}
int Chat::getVisibility()
{
return dc_chat_get_visibility(m_chat);
}
bool Chat::isProtected()
{
return dc_chat_is_protected(m_chat);
}
bool Chat::isProtectionBroken()
{
return dc_chat_is_protection_broken(m_chat);
}

33
src/deltachat/chat.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef CHAT_H
#define CHAT_H
#include <QObject>
#include <deltachat.h>
namespace dc {
class Chat : public QObject
{
Q_OBJECT
public:
explicit Chat(dc_chat_t *chat);
~Chat();
uint32_t getId();
int getType();
QString getName();
QString getProfileImage();
bool isContactRequest();
bool canSend();
bool isMuted();
int getVisibility();
bool isProtected();
bool isProtectionBroken();
private:
dc_chat_t *m_chat{nullptr};
};
} // namespace dc
#endif // CHAT_H

View file

@ -0,0 +1,37 @@
#include "chatlist.h"
#include "lot.h"
namespace dc {
Chatlist::Chatlist(dc_chatlist_t *chatlist)
: m_chatlist{chatlist}
{}
Chatlist::~Chatlist()
{
dc_chatlist_unref(m_chatlist);
}
size_t Chatlist::getChatCount() const
{
return dc_chatlist_get_cnt(m_chatlist);
}
uint32_t Chatlist::getChatId(size_t index) const
{
return dc_chatlist_get_chat_id(m_chatlist, index);
}
uint32_t Chatlist::getMsgId(size_t index) const
{
return dc_chatlist_get_msg_id(m_chatlist, index);
}
std::shared_ptr<Lot> Chatlist::getSummary(size_t index) const
{
auto lot = new Lot(dc_chatlist_get_summary(m_chatlist, index, NULL));
auto ret = std::shared_ptr<Lot>(lot);
return ret;
}
} // namespace dc

28
src/deltachat/chatlist.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef CHATLIST_H
#define CHATLIST_H
#include <QObject>
#include <deltachat.h>
#include <memory>
namespace dc {
class Lot;
class Chatlist : public QObject
{
Q_OBJECT
public:
explicit Chatlist(dc_chatlist_t *context);
~Chatlist();
size_t getChatCount() const;
uint32_t getChatId(size_t index) const;
uint32_t getMsgId(size_t index) const;
std::shared_ptr<Lot> getSummary(size_t index) const;
private:
dc_chatlist_t *m_chatlist{nullptr};
};
} // namespace dc
#endif // CHATLIST_H

51
src/deltachat/contact.cpp Normal file
View file

@ -0,0 +1,51 @@
#include "contact.h"
namespace dc {
Contact::Contact(dc_contact_t *contact)
: QObject{nullptr}
, m_contact{contact}
{}
Contact::~Contact()
{
dc_contact_unref(m_contact);
}
uint32_t Contact::getId()
{
return dc_contact_get_id(m_contact);
}
QString Contact::getAddr()
{
char *addr = dc_contact_get_addr(m_contact);
QString result{addr};
dc_str_unref(addr);
return result;
}
QString Contact::getName()
{
char *name = dc_contact_get_name(m_contact);
QString result{name};
dc_str_unref(name);
return result;
}
QString Contact::getDisplayName()
{
char *display_name = dc_contact_get_display_name(m_contact);
QString result{display_name};
dc_str_unref(display_name);
return result;
}
QString Contact::getProfileImage()
{
char *profileImage = dc_contact_get_profile_image(m_contact);
QString result{profileImage};
dc_str_unref(profileImage);
return result;
}
} // namespace dc

26
src/deltachat/contact.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef CONTACT_H
#define CONTACT_H
#include <QObject>
#include <deltachat.h>
namespace dc {
class Contact : public QObject
{
Q_OBJECT
public:
explicit Contact(dc_contact_t *contact);
~Contact();
uint32_t getId();
QString getAddr();
QString getName();
QString getDisplayName();
QString getProfileImage();
private:
dc_contact_t *m_contact{nullptr};
};
} // namespace dc
#endif // CONTACT_H

304
src/deltachat/context.cpp Normal file
View file

@ -0,0 +1,304 @@
#include "context.h"
#include "chat.h"
#include "chatlist.h"
#include "contact.h"
#include "lot.h"
#include "message.h"
#include <QDebug>
namespace dc {
Context::Context(dc_context_t* mctx)
{
m_context = mctx;
}
Context::~Context()
{
dc_context_unref(m_context);
}
void Context::configure()
{
dc_configure(m_context);
}
bool Context::isConfigured() const
{
return dc_is_configured(m_context);
}
void Context::startIo()
{
dc_start_io(m_context);
}
void Context::stopIo()
{
dc_stop_io(m_context);
}
void Context::maybeNetwork()
{
dc_maybe_network(m_context);
}
QString Context::getInfo()
{
char* info = dc_get_info(m_context);
QString result { info };
dc_str_unref(info);
return result;
}
std::shared_ptr<Chatlist> Context::getChatlist(int flags, QString query)
{
QByteArray utf8Query = query.toUtf8();
dc_chatlist_t* chatlist = dc_get_chatlist(m_context,
flags,
query.isEmpty() ? nullptr : utf8Query.constData(),
0);
auto p = new Chatlist(chatlist);
return std::shared_ptr<Chatlist>(p);
}
uint32_t Context::createChatByContactId(uint32_t contactId)
{
return dc_create_chat_by_contact_id(m_context, contactId);
}
uint32_t Context::createGroupChat(const QString& name, bool secure)
{
QByteArray str = name.toUtf8();
return dc_create_group_chat(m_context, secure, str.constData());
}
int Context::removeContactFromChat(uint32_t chat_id, uint32_t contact_id)
{
return dc_remove_contact_from_chat(m_context, chat_id, contact_id);
}
int Context::addContactToChat(uint32_t chat_id, uint32_t contact_id)
{
return dc_add_contact_to_chat(m_context, chat_id, contact_id);
}
uint32_t Context::getId()
{
return dc_get_id(m_context);
}
void Context::setChatVisibility(uint32_t chatId, int visibility)
{
dc_set_chat_visibility(m_context, chatId, visibility);
}
void Context::deleteChat(uint32_t chatId)
{
dc_delete_chat(m_context, chatId);
}
void Context::blockChat(uint32_t chatId)
{
dc_block_chat(m_context, chatId);
}
void Context::acceptChat(uint32_t chatId)
{
dc_accept_chat(m_context, chatId);
}
QString Context::getChatEncrinfo(uint32_t chatId)
{
char* encrinfo = dc_get_chat_encrinfo(m_context, chatId);
QString result { encrinfo };
dc_str_unref(encrinfo);
return result;
}
uint32_t Context::getChatEphemeralTimer(uint32_t chatId)
{
return dc_get_chat_ephemeral_timer(m_context, chatId);
}
std::shared_ptr<Chat> Context::getChat(uint32_t chatId)
{
dc_chat_t* chat = dc_get_chat(m_context, chatId);
return std::shared_ptr<Chat>(new Chat { chat });
}
QList<int> Context::getMsgIdList(uint32_t chatId)
{
QList<int> result;
dc_array_t* msgIdArray = dc_get_chat_msgs(m_context, chatId, 0, 0);
for (size_t i = 0; i < dc_array_get_cnt(msgIdArray); i++) {
result << dc_array_get_id(msgIdArray, i);
}
dc_array_unref(msgIdArray);
return result;
}
QList<int> Context::getContacts(uint32_t flags, QString query)
{
QList<int> result;
QByteArray utf8Query = query.toUtf8();
dc_array_t* contactsArray = dc_get_contacts(m_context, flags, utf8Query.constData());
for (size_t i = 0; i < dc_array_get_cnt(contactsArray); i++) {
result << dc_array_get_id(contactsArray, i);
}
dc_array_unref(contactsArray);
return result;
}
int Context::getFreshMsgCnt(uint32_t chatId)
{
return dc_get_fresh_msg_cnt(m_context, chatId);
}
void Context::marknoticedChat(uint32_t chatId)
{
return dc_marknoticed_chat(m_context, chatId);
}
void Context::markseenMsgs(QVector<uint32_t> msg_ids)
{
dc_markseen_msgs(m_context, msg_ids.constData(), msg_ids.count());
}
std::shared_ptr<Message> Context::getMessage(uint32_t msgId)
{
dc_msg_t* message = dc_get_msg(m_context, msgId);
auto m = new Message(message);
return std::shared_ptr<Message>(m);
}
std::shared_ptr<Contact> Context::getContact(uint32_t contactId)
{
dc_contact_t* contact = dc_get_contact(m_context, contactId);
return std::shared_ptr<Contact>(new Contact { contact });
}
uint32_t Context::createContact(QString name, QString addr)
{
QByteArray utf8name = name.toUtf8();
QByteArray utf8addr = addr.toUtf8();
return dc_create_contact(m_context, utf8name.constData(), utf8addr.constData());
}
int Context::deleteContact(uint32_t contact_id)
{
return dc_delete_contact(m_context, contact_id);
}
QString Context::getBlobdir()
{
char* blobdir = dc_get_blobdir(m_context);
QString result { blobdir };
dc_str_unref(blobdir);
return result;
}
bool Context::setConfig(QString key, QString value)
{
QByteArray utf8Key = key.toUtf8();
QByteArray utf8Value = value.toUtf8();
return dc_set_config(m_context, utf8Key.constData(), utf8Value.constData());
}
QString Context::getConfig(QString key)
{
QByteArray utf8Key = key.toUtf8();
char* value = dc_get_config(m_context, utf8Key.constData());
QString result { value };
dc_str_unref(value);
return result;
}
QString Context::getMessageInfo(uint32_t msgId)
{
char* info = dc_get_msg_info(m_context, msgId);
QString result { info };
dc_str_unref(info);
return result;
}
QString Context::getMessageHtml(uint32_t msgId)
{
char* html = dc_get_msg_html(m_context, msgId);
QString result { html };
dc_str_unref(html);
return result;
}
uint32_t Context::sendTextMessage(uint32_t chatId, QString textToSend)
{
QByteArray utf8Text = textToSend.toUtf8();
return dc_send_text_msg(m_context, chatId, utf8Text.constData());
}
void Context::setDraft(uint32_t chatId, std::shared_ptr<Message>& message)
{
dc_set_draft(m_context, chatId, message ? message->m_message : nullptr);
}
std::shared_ptr<Message> Context::getDraft(uint32_t chatId)
{
dc_msg_t* draft = dc_get_draft(m_context, chatId);
if (draft) {
return std::shared_ptr<Message>(new Message { draft });
} else {
return NULL;
}
}
bool Context::setChatMuteDuration(uint32_t chatId, int64_t duration)
{
return dc_set_chat_mute_duration(m_context, chatId, duration);
}
std::shared_ptr<Message> Context::newMessage(int viewtype)
{
dc_msg_t* message = dc_msg_new(m_context, viewtype);
return std::shared_ptr<Message>(new Message(message));
}
uint32_t Context::sendMessage(uint32_t chatId, std::shared_ptr<Message>& message)
{
return dc_send_msg(m_context, chatId, message->m_message);
}
void Context::importBackup(QString tarfile)
{
QByteArray utf8Text = tarfile.toUtf8();
return dc_imex(m_context, DC_IMEX_IMPORT_BACKUP, utf8Text.constData(), NULL);
}
std::shared_ptr<Lot> Context::checkQr(QString qr)
{
QByteArray data = qr.toUtf8();
auto ret = dc_check_qr(m_context, data.constData());
return std::shared_ptr<Lot>(new Lot(ret));
}
QString Context::getSecurejoinQrSvg(uint32_t id)
{
auto str = dc_get_securejoin_qr_svg(m_context, id);
QString ret(str);
dc_str_unref(str);
return ret;
}
QString Context::getSecurejoinQr(uint32_t id)
{
auto str = dc_get_securejoin_qr(m_context, id);
QString ret(str);
dc_str_unref(str);
return ret;
}
uint32_t Context::joinSecurejoin(QString qrcode)
{
auto qrdata = qrcode.toUtf8();
return dc_join_securejoin(m_context, qrdata.constData());
}
} // namespace dc

84
src/deltachat/context.h Normal file
View file

@ -0,0 +1,84 @@
#ifndef CONTEXT_H
#define CONTEXT_H
#include <QObject>
#include <QVariantList>
#include <deltachat.h>
#include <memory>
namespace dc {
class Message;
class Contact;
class Chat;
class Chatlist;
class Lot;
class Context : public QObject {
Q_OBJECT
private:
dc_context_t* m_context;
public:
Context(dc_context_t* mctx);
~Context();
void configure();
bool isConfigured() const;
QString getInfo();
void startIo();
void stopIo();
void maybeNetwork();
/* chat untion */
std::shared_ptr<Chatlist> getChatlist(int flags, QString query);
uint32_t createChatByContactId(uint32_t contactId);
void setChatVisibility(uint32_t chatId, int visibility);
void deleteChat(uint32_t chatId);
void blockChat(uint32_t chatId);
void acceptChat(uint32_t chatId);
QString getChatEncrinfo(uint32_t chatId);
uint32_t getChatEphemeralTimer(uint32_t chatId);
std::shared_ptr<Chat> getChat(uint32_t chatId);
/* contatct function */
QList<int> getContacts(uint32_t flags, QString query);
QList<int> getMsgIdList(uint32_t chatId);
int getFreshMsgCnt(uint32_t chatId);
void marknoticedChat(uint32_t chatId);
void markseenMsgs(QVector<uint32_t> msg_ids);
std::shared_ptr<Message> getMessage(uint32_t msgId);
std::shared_ptr<Contact> getContact(uint32_t contactId);
// contact
uint32_t createContact(QString name, QString addr);
int deleteContact(uint32_t contact_id);
uint32_t sendTextMessage(uint32_t chatId, QString textToSend);
void setDraft(uint32_t chatId, std::shared_ptr<Message>& message);
std::shared_ptr<Message> getDraft(uint32_t chatId);
QString getBlobdir();
bool setConfig(QString key, QString value);
QString getConfig(QString key);
bool setChatMuteDuration(uint32_t chatId, int64_t duration);
QString getMessageInfo(uint32_t msgId);
QString getMessageHtml(uint32_t msgId);
std::shared_ptr<Message> newMessage(int viewtype);
uint32_t sendMessage(uint32_t chatId, std::shared_ptr<Message>& message);
void importBackup(QString tarfile);
// qr code funtion
std::shared_ptr<Lot> checkQr(QString qr);
// create a image to scan
QString getSecurejoinQrSvg(uint32_t id = 0);
// create qr
QString getSecurejoinQr(uint32_t id = 0);
uint32_t joinSecurejoin(QString qrcode);
/* for chat grop*/
uint32_t createGroupChat(const QString& name, bool secure = true);
int removeContactFromChat(uint32_t chat_id, uint32_t contact_id);
int addContactToChat(uint32_t chat_id, uint32_t contact_id);
/* id */
uint32_t getId();
};
} // namespace dc
#endif // CONTEXT_H

12
src/deltachat/deltacpp.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef DELTACPP_H
#define DELTACPP_H
#include "account.h"
#include "chat.h"
#include "chatlist.h"
#include "contact.h"
#include "context.h"
#include "lot.h"
#include "message.h"
#endif // DELTACPP_H

42
src/deltachat/event.cpp Normal file
View file

@ -0,0 +1,42 @@
#include "event.h"
#include <QDebug>
namespace dc {
Event::Event(dc_event_t *event)
: m_event{event}
{}
Event::~Event()
{
dc_event_unref(m_event);
}
int Event::getId()
{
return dc_event_get_id(m_event);
}
int Event::getData1Int()
{
return dc_event_get_data1_int(m_event);
}
int Event::getData2Int()
{
return dc_event_get_data2_int(m_event);
}
QString Event::getData2Str()
{
char *data2 = dc_event_get_data2_str(m_event);
QString result{data2};
dc_str_unref(data2);
return result;
}
uint32_t Event::getAccountId()
{
return dc_event_get_account_id(m_event);
}
} // namespace dc

26
src/deltachat/event.h Normal file
View file

@ -0,0 +1,26 @@
#ifndef EVENT_H
#define EVENT_H
#include <QObject>
#include <deltachat.h>
namespace dc {
class Event : public QObject
{
Q_OBJECT
dc_event_t *m_event;
public:
explicit Event(dc_event_t *event);
~Event();
int getId();
int getData1Int();
int getData2Int();
QString getData2Str();
uint32_t getAccountId();
};
} // namespace dc
#endif // EVENT_H

View file

@ -0,0 +1,22 @@
#include "eventemitter.h"
#include "event.h"
namespace dc {
EventEmitter::EventEmitter(dc_event_emitter_t *emiter)
: m_emiter{emiter}
{}
EventEmitter::~EventEmitter()
{
dc_event_emitter_unref(m_emiter);
}
void EventEmitter::run()
{
dc_event_t *evt = nullptr;
while ((evt = dc_get_next_event(m_emiter)) != nullptr) {
auto e = QSharedPointer<Event>(new Event(evt));
emit gotEvent(e);
}
}
} // namespace dc

View file

@ -0,0 +1,30 @@
#ifndef EVENTEMITTER_H
#define EVENTEMITTER_H
#include <QObject>
#include <QSharedPointer>
#include <QThread>
#include <deltachat.h>
namespace dc {
class Event;
class EventEmitter : public QThread
{
Q_OBJECT
private:
dc_event_emitter_t *m_emiter;
public:
explicit EventEmitter(dc_event_emitter_t *emiter);
~EventEmitter();
void run();
signals:
void gotEvent(QSharedPointer<Event> evt);
};
} // namespace dc
#endif // EVENTEMITTER_H

49
src/deltachat/lot.cpp Normal file
View file

@ -0,0 +1,49 @@
#include "lot.h"
namespace dc {
Lot::Lot(dc_lot_t *lot)
: m_lot{lot}
{}
Lot::~Lot()
{
dc_lot_unref(m_lot);
}
QString Lot::getText1() const
{
char *text1 = dc_lot_get_text1(m_lot);
QString result{text1};
dc_str_unref(text1);
return result;
}
QString Lot::getText2() const
{
char *text2 = dc_lot_get_text2(m_lot);
QString result{text2};
dc_str_unref(text2);
return result;
}
int Lot::getText1Meaning() const
{
return dc_lot_get_text1_meaning(m_lot);
}
int Lot::getState() const
{
return dc_lot_get_state(m_lot);
}
uint32_t Lot::getId() const
{
return dc_lot_get_id(m_lot);
}
int64_t Lot::getTimestamp() const
{
return dc_lot_get_timestamp(m_lot);
}
} // namespace dc

25
src/deltachat/lot.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef LOT_H
#define LOT_H
#include <QObject>
#include <deltachat.h>
namespace dc {
class Lot : public QObject
{
Q_OBJECT
dc_lot_t *m_lot{nullptr};
public:
explicit Lot(dc_lot_t *lot);
~Lot();
QString getText1() const;
QString getText2() const;
int getText1Meaning() const;
int getState() const;
uint32_t getId() const;
int64_t getTimestamp() const;
};
} // namespace dc
#endif // LOT_H

191
src/deltachat/message.cpp Normal file
View file

@ -0,0 +1,191 @@
#include "message.h"
#include <QFile>
namespace dc {
Message::Message(dc_msg_t *mgs)
{
this->m_message = mgs;
}
Message::~Message()
{
dc_msg_unref(m_message);
}
uint32_t Message::getId()
{
return dc_msg_get_id(m_message);
}
uint32_t Message::getFromId()
{
return dc_msg_get_from_id(m_message);
}
uint32_t Message::getChatId()
{
return dc_msg_get_chat_id(m_message);
}
int Message::getViewtype()
{
return dc_msg_get_viewtype(m_message);
}
int Message::getState()
{
return dc_msg_get_state(m_message);
}
QDateTime Message::getTimestamp()
{
return QDateTime::fromSecsSinceEpoch(dc_msg_get_timestamp(m_message), Qt::UTC);
}
bool Message::saveAttach(QString dest)
{
if (!dest.isNull()) {
char *file = dc_msg_get_file(m_message);
QString fileUrl{file};
dc_str_unref(file);
// We need to replace, so we delete the file first.
if (QFile::exists(dest)) {
if (!QFile::remove(dest))
return false;
}
return QFile::copy(fileUrl, dest);
} else {
return false;
}
}
void Message::setText(QString text)
{
QByteArray utf8Text = text.toUtf8();
return dc_msg_set_text(m_message, utf8Text.constData());
}
QString Message::getText()
{
char *text = dc_msg_get_text(m_message);
QString result{text};
dc_str_unref(text);
return result;
}
void Message::setFile(QString file)
{
QByteArray utf8File = file.toUtf8();
return dc_msg_set_file(m_message, utf8File.constData(), NULL);
}
QString Message::getSubject()
{
char *subject = dc_msg_get_subject(m_message);
QString result{subject};
dc_str_unref(subject);
return result;
}
void Message::setSubject(QString sub)
{
QByteArray data = sub.toUtf8();
dc_msg_set_subject(m_message, data.constData());
}
QString Message::getFile()
{
char *file = dc_msg_get_file(m_message);
QString result{file};
dc_str_unref(file);
return result;
}
QString Message::getFilename()
{
char *filename = dc_msg_get_filename(m_message);
QString result{filename};
dc_str_unref(filename);
return result;
}
QString Message::getFilemime()
{
char *filemime = dc_msg_get_filemime(m_message);
QString result{filemime};
dc_str_unref(filemime);
return result;
}
int Message::getWidth()
{
return dc_msg_get_width(m_message);
}
int Message::getHeight()
{
return dc_msg_get_height(m_message);
}
bool Message::getShowPadlock()
{
return dc_msg_get_showpadlock(m_message);
}
bool Message::getIsBot()
{
return dc_msg_is_bot(m_message);
}
QString Message::getOverrideSenderName()
{
char *name = dc_msg_get_override_sender_name(m_message);
QString result{name};
dc_str_unref(name);
return result;
}
bool Message::isInfo()
{
return dc_msg_is_info(m_message);
}
QString Message::getError()
{
char *error = dc_msg_get_error(m_message);
QString result{error};
dc_str_unref(error);
return result;
}
bool Message::hasHtml()
{
return dc_msg_has_html(m_message);
}
QString Message::getQuotedText()
{
char *text = dc_msg_get_quoted_text(m_message);
QString result{text};
dc_str_unref(text);
return result;
}
std::shared_ptr<Message> Message::getQuotedMessage()
{
dc_msg_t *quote = dc_msg_get_quoted_msg(m_message);
if (quote) {
auto ret = std::shared_ptr<Message>(new Message(quote));
return ret;
} else {
return NULL;
}
}
int Message::getInfoType()
{
return dc_msg_get_info_type(m_message);
}
} // namespace dc

68
src/deltachat/message.h Normal file
View file

@ -0,0 +1,68 @@
#ifndef MESSAGE_H
#define MESSAGE_H
#include <QDateTime>
#include <QObject>
#include <deltachat.h>
#include <memory>
namespace dc {
class Message : public QObject
{
Q_OBJECT
private:
dc_msg_t *m_message;
public:
explicit Message(dc_msg_t *m_message);
~Message();
// function
uint32_t getId();
uint32_t getFromId();
uint32_t getChatId();
int getViewtype();
int getState();
QDateTime getTimestamp();
// int64_t getReceivedTimestamp();
// int64_t getSortTimestamp();
bool saveAttach(QString);
void setText(QString);
void setFile(QString);
QString getText();
QString getSubject();
void setSubject(QString sub);
QString getFile();
QString getFilename();
QString getFilemime();
//uint64_t getFilebytes();
int getWidth();
int getHeight();
//int getDuration();
bool getShowPadlock();
bool getIsBot();
//uint32_t getEphemeralTimer();
//int64_t getEphemeralTimestamp();
//... getsummary ...
QString getOverrideSenderName();
//hasDeviatingTimestamp
//hasLocation
//isSent
//isStarred
//isForwarded
bool isInfo();
QString getError();
bool hasHtml();
//isIncreation
//isSetupmessage
QString getQuotedText();
std::shared_ptr<Message> getQuotedMessage();
int getInfoType();
//
friend class Context;
};
} // namespace dc
#endif // MESSAGE_H

44
src/main.cpp Normal file
View file

@ -0,0 +1,44 @@
#include <QDebug>
#include <QFile>
#include <QGuiApplication>
#include <QObject>
#include <QQmlApplicationEngine>
#include <QTextStream>
#include <app/app.h>
#include <model/chat/chatcore.h>
using namespace dc;
static void init(Task* task)
{
Acc* m_acc = new Acc(task);
ContactUi* up = new ContactUi(task);
ChatUi* ui = new ChatUi(task);
(void)m_acc;
(void)up;
(void)ui;
}
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
ChatCore::init();
QQmlApplicationEngine engine;
engine.addImportPath(":/qml");
engine.load(QUrl(QLatin1String("qrc:/qml/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
qDebug() << "start amneiht chat";
MsgShow msg;
auto acc = Account::getInstance();
QObject::connect(acc.get(), &Account::incomingMessage, &msg, &MsgShow::onIncomingMessage);
Task* task = new Task();
init(task);
QObject::connect(task, &Task::finish, &app, &QGuiApplication::quit);
task->start();
app.exec();
ChatCore::close();
task->disablerun();
task->wait();
delete task;
}

View file

@ -0,0 +1,33 @@
#include "chatcore.h"
#include "chatlistmodel.h"
#include "chatproxymodel.h"
#include "chatroommodel.h"
#include "messagemodel.h"
#include <QStandardPaths>
#include <qqml.h>
ChatCore::ChatCore() { }
// contain declare
constexpr char ChatCore::QmlName[];
void ChatCore::init()
{
// for linux
auto path = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/chat";
dc::Account::init(path);
// @uri Dcchat
qmlRegisterType<ChatProxyModel>(ChatCore::QmlName, 1, 0, "ChatProxyModel");
qmlRegisterType<ChatListModel>(ChatCore::QmlName, 1, 0, "ChatListModel");
qmlRegisterType<ChatRoomModel>(ChatCore::QmlName, 1, 0, "ChatRoomModel");
qmlRegisterType<MessageModel>(ChatCore::QmlName, 1, 0, "MessageModel");
dc::Account::getInstance()->startEventLoop();
}
void ChatCore::close()
{
dc::Account::close();
}

18
src/model/chat/chatcore.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef CHATCORE_H
#define CHATCORE_H
#include <deltachat/deltacpp.h>
class ChatCore {
public:
ChatCore();
static void init();
static void close();
// constaince
static constexpr char QmlName[] = "Dcchat";
};
#endif // CHATCORE_H

View file

@ -0,0 +1,64 @@
#include "chatlistmodel.h"
#include "chatcore.h"
#include <QDebug>
ChatListModel::ChatListModel(QObject* parent)
: QAbstractListModel { parent }
{
auto acc = dc::Account::getInstance();
auto ctx = acc->getSelectedAccount();
if (ctx)
list = dc::Account::getInstance()->getSelectedAccount()->getChatlist(0, "");
}
int ChatListModel::rowCount(const QModelIndex& parent) const
{
if (list) {
return list->getChatCount();
}
return 0;
}
QHash<int, QByteArray> ChatListModel::roleNames() const
{
QHash<int, QByteArray> ret;
ret[ListRole::ChatID] = "$chatid";
ret[ListRole::Username] = "$name";
return ret;
}
QVariant ChatListModel::data(const QModelIndex& index, int role) const
{
int pid = index.row();
auto chat_id = list->getChatId(pid);
std::shared_ptr<dc::Chat> chat;
switch (role) {
case ListRole::ChatID:
return chat_id;
case ListRole::Username:
chat = dc::Account::getInstance()->getSelectedAccount()->getChat(chat_id);
return chat->getName();
default:
break;
}
return "";
}
QString ChatListModel::getName(const QVariant& index)
{
// row id
auto ctx = dc::Account::getInstance()->getSelectedAccount();
auto list = ctx->getChatlist(0, "");
int id = index.toInt();
auto chat_id = list->getChatId(id);
// qDebug() << "get chat with" + QString::number(chat_id);
if (chat_id >= 0) {
auto chat = ctx->getChat(chat_id);
return chat->getName();
}
qDebug() << "Error: can not get chat";
return "Error";
}

View file

@ -0,0 +1,35 @@
#ifndef CHATLISTMODEL_H
#define CHATLISTMODEL_H
#include "chatcore.h"
#include <QAbstractListModel>
class ChatListModel : public QAbstractListModel {
Q_OBJECT
private:
enum ListRole {
/** $chatid */
ChatID = Qt::UserRole,
/** $name */
Username //
};
std::shared_ptr<dc::Chatlist> list;
public:
explicit ChatListModel(QObject* parent = nullptr);
signals:
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex& parent) const;
QHash<int, QByteArray> roleNames() const;
QVariant data(const QModelIndex& index, int role) const;
Q_INVOKABLE QString getName(const QVariant& index);
// QAbstractItemModel interface
public:
};
#endif // CHATLISTMODEL_H

View file

@ -0,0 +1,36 @@
#include "chatproxymodel.h"
#include "chatlistmodel.h"
#include "chatcore.h"
ChatProxyModel::ChatProxyModel(QObject* parent)
: QSortFilterProxyModel { parent }
{
}
void ChatProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
{
model = static_cast<ChatListModel*>(sourceModel);
}
void ChatProxyModel::setFilterString(const QString& filer)
{
this->filter = filer;
emit filterChange();
}
bool ChatProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
{
auto name = model->getName(source_parent);
if (filter != "") {
return name.contains(filter);
}
return true;
}
bool ChatProxyModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const
{
// todo sort by arrival time
return source_left.row() > source_right.row();
}

View file

@ -0,0 +1,31 @@
#ifndef CHATPROXYMODEL_H
#define CHATPROXYMODEL_H
#include <QSortFilterProxyModel>
class ChatListModel;
class ChatProxyModel : public QSortFilterProxyModel {
Q_OBJECT
private:
ChatListModel* model;
QString filter = "";
public:
explicit ChatProxyModel(QObject* parent = nullptr);
// QAbstractProxyModel interface
public:
void setSourceModel(QAbstractItemModel* sourceModel);
Q_INVOKABLE void setFilterString(const QString& filer);
// QSortFilterProxyModel interface
protected:
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const;
signals:
void filterChange();
};
#endif // CHATPROXYMODEL_H

View file

@ -0,0 +1,145 @@
#include "chatroommodel.h"
#include "chatcore.h"
#include "messagemodel.h"
#include <QDebug>
ChatRoomModel::ChatRoomModel(QObject* parent)
: QAbstractListModel { parent }
{
mess_count = 10;
auto acc = dc::Account::getInstance();
connect(acc.get(), &dc::Account::incomingMessage, this, &ChatRoomModel::onIncomingMessage);
connect(acc.get(), &dc::Account::outGoingMessage, this, &ChatRoomModel::onOutGoingMessage);
connect(this, &ChatRoomModel::updateData, this, &ChatRoomModel::rowChange, Qt::DirectConnection);
}
int ChatRoomModel::rowCount(const QModelIndex& parent) const
{
return mess_count;
}
int ChatRoomModel::getChatid() const
{
return m_chatid;
}
void ChatRoomModel::setChatid(int newChatid)
{
if (m_chatid == newChatid)
return;
m_chatid = newChatid;
auto list = dc::Account::getInstance()->getSelectedAccount()->getMsgIdList(m_chatid);
// limit mess display
current_count = list.count();
if (current_count < 20) {
mess_count = list.count();
} else
mess_count = 20;
emit chatidChanged();
}
int ChatRoomModel::loadMoredata()
{
int pad = 20;
if (current_count > mess_count + pad)
mess_count = mess_count + pad;
else {
pad = current_count - mess_count;
mess_count = current_count;
}
rstart = 0;
rend = pad - 1;
emit this->updateData();
// for smooth
if (rend > 1)
rend = rend - 1;
return rend;
}
QString ChatRoomModel::chatName()
{
auto chat = dc::Account::getInstance()->getSelectedAccount()->getChat(m_chatid);
return chat->getName();
}
void ChatRoomModel::onIncomingMessage(uint32_t accountId, int chatId, int msgId)
{
auto id = dc::Account::getInstance()->getSelectedAccount()->getId();
if (accountId != id || chatId != m_chatid) {
return;
}
rstart = mess_count;
rend = mess_count;
auto list = dc::Account::getInstance()->getSelectedAccount()->getMsgIdList(m_chatid);
current_count = list.count();
mess_count++;
emit this->updateData();
}
void ChatRoomModel::onOutGoingMessage(uint32_t accountId, int chatId)
{
// realy same as incomming
auto id = dc::Account::getInstance()->getSelectedAccount()->getId();
if (accountId != id || chatId != m_chatid) {
return;
}
rstart = mess_count;
rend = mess_count;
auto list = dc::Account::getInstance()->getSelectedAccount()->getMsgIdList(m_chatid);
current_count = list.count();
mess_count++;
emit this->updateData();
}
void ChatRoomModel::rowChange()
{
// numver off message is display = messcount
beginInsertRows(QModelIndex(), rstart, rend);
endInsertRows();
}
QVariant ChatRoomModel::data(const QModelIndex& index, int role) const
{
auto lctx = dc::Account::getInstance()->getSelectedAccount();
auto list = lctx->getMsgIdList(m_chatid);
// revert show , lastest mess first
int id = (current_count - mess_count) + index.row();
// qDebug() << " run with" + QString::number(current_count) + " id:" + QString::number(index.row());
auto mess = lctx->getMessage(list.at(id));
if (role == Role::text) {
return mess->getText();
} else if (role == Role::date) {
return mess->getTimestamp();
} else if (role == Role::user) {
auto id = mess->getFromId();
if (id != DC_CONTACT_ID_SELF) {
auto contact = lctx->getContact(id);
return contact->getName();
}
} else if (role == Role::local) {
auto id = mess->getFromId();
return id == DC_CONTACT_ID_SELF;
}
return "";
}
QHash<int, QByteArray> ChatRoomModel::roleNames() const
{
QHash<int, QByteArray> role;
role[Role::text] = "$text";
role[Role::local] = "$local";
role[Role::date] = "$date";
role[Role::user] = "$user";
return role;
}
ChatRoomModel::~ChatRoomModel()
{
}

View file

@ -0,0 +1,50 @@
#ifndef CHATROOMMODEL_H
#define CHATROOMMODEL_H
#include <QAbstractListModel>
class ChatRoomModel : public QAbstractListModel {
Q_OBJECT
Q_PROPERTY(int chatid READ getChatid WRITE setChatid NOTIFY chatidChanged FINAL)
private:
int mess_count = 20;
int current_count;
int m_chatid;
// for insert row
int rstart, rend;
enum Role {
text = Qt::UserRole,
user,
local,
date
};
public:
explicit ChatRoomModel(QObject* parent = nullptr);
~ChatRoomModel();
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex& parent) const;
QVariant data(const QModelIndex& index, int role) const;
int getChatid() const;
void setChatid(int newChatid);
public:
Q_INVOKABLE int loadMoredata();
Q_INVOKABLE QString chatName();
// QAbstractItemModel interface
QHash<int, QByteArray> roleNames() const;
public slots:
void onIncomingMessage(uint32_t accountId, int chatId, int msgId);
void onOutGoingMessage(uint32_t accountId, int chatId);
signals:
void updateData();
void chatidChanged();
private:
void rowChange();
};
#endif // CHATROOMMODEL_H

View file

@ -0,0 +1,32 @@
#include "messagemodel.h"
#include "chatcore.h"
#include <QDebug>
MessageModel::MessageModel(QObject* parent)
: QObject { parent }
{
}
MessageModel::~MessageModel()
{
}
int MessageModel::getID() const
{
return m_id;
}
void MessageModel::setId(int newId)
{
if (m_id == newId)
return;
m_id = newId;
emit idChanged();
}
void MessageModel::sendText(const QString& Text)
{
auto ctx = dc::Account::getInstance()->getSelectedAccount();
ctx->sendTextMessage(m_id, Text);
emit dc::Account::getInstance()->outGoingMessage(ctx->getId(), m_id);
}

View file

@ -0,0 +1,27 @@
#ifndef MESSAGEMODEL_H
#define MESSAGEMODEL_H
#include <QDateTime>
#include <QObject>
class MessageModel : public QObject {
Q_OBJECT
Q_PROPERTY(int chatid READ getID WRITE setId NOTIFY idChanged FINAL)
public:
explicit MessageModel(QObject* parent = nullptr);
~MessageModel();
int getID() const;
void setId(int newId);
Q_INVOKABLE void sendText(const QString& Text);
signals:
void idChanged();
private:
// chat id
int m_id;
};
Q_DECLARE_METATYPE(MessageModel*);
#endif // MESSAGEMODEL_H