Add translator core, mailitem model, main.cpp, and en translation
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(WinoMailQt VERSION 1.0.0 LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Find Qt components
|
||||||
|
find_package(Qt6 COMPONENTS Core Gui Widgets Network Sql WebEngineWidgets REQUIRED)
|
||||||
|
|
||||||
|
# Find optional libraries (example: libetpan, gmime)
|
||||||
|
# find_package(PkgConfig REQUIRED)
|
||||||
|
# pkg_check_modules(LIBETPAN REQUIRED libetpan)
|
||||||
|
# pkg_check_modules(GMIME REQUIRED gmime-2.6)
|
||||||
|
|
||||||
|
# Include directories
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
# Source files - we will add them later
|
||||||
|
set(SRC_FILES
|
||||||
|
src/core/translator.cpp
|
||||||
|
src/services/synchronizer.cpp
|
||||||
|
# placeholder
|
||||||
|
)
|
||||||
|
|
||||||
|
# Executable
|
||||||
|
add_executable(wino-mail-qt ${SRC_FILES})
|
||||||
|
|
||||||
|
# Link Qt
|
||||||
|
target_link_libraries(wino-mail-qt PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Network Qt6::Sql Qt6::WebEngineWidgets)
|
||||||
|
|
||||||
|
# If using external libs
|
||||||
|
# target_link_libraries(wino-mail-qt PRIVATE ${LIBETPAN_LIBRARIES} ${GMIME_LIBRARIES})
|
||||||
|
# target_include_directories(wino-mail-qt PRIVATE ${LIBETPAN_INCLUDE_DIRS} ${GMIME_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
# Install (optional)
|
||||||
|
install(TARGETS wino-mail-qt DESTINATION bin)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"appName": "Wino Mail",
|
||||||
|
"welcomeMessage": "Welcome to Wino Mail",
|
||||||
|
"settings": "Settings",
|
||||||
|
"inbox": "Inbox",
|
||||||
|
"sent": "Sent",
|
||||||
|
"drafts": "Drafts",
|
||||||
|
"trash": "Trash"
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#include "translator.h"
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
Translator& Translator::instance()
|
||||||
|
{
|
||||||
|
static Translator instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Translator::loadLanguage(const QString& langCode)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
m_translations.clear();
|
||||||
|
|
||||||
|
QString filePath = QStringLiteral("resources/translations/%1/resources.json").arg(langCode);
|
||||||
|
QFile file(filePath);
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
qWarning() << "Failed to open translation file:" << filePath;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray jsonData = file.readAll();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
QJsonParseError parseError;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
|
||||||
|
if (parseError.error != QJsonParseError::NoError) {
|
||||||
|
qWarning() << "Failed to parse translation JSON:" << parseError.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!doc.isObject()) {
|
||||||
|
qWarning() << "Translation JSON is not an object";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject obj = doc.object();
|
||||||
|
for (auto it = obj.begin(); it != obj.end(); ++it) {
|
||||||
|
if (it.value().isString()) {
|
||||||
|
m_translations.insert(it.key(), it.value().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentLang = langCode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Translator::tr(const QString& key) const
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
auto it = m_translations.find(key);
|
||||||
|
if (it != m_translations.end()) {
|
||||||
|
return it.value();
|
||||||
|
}
|
||||||
|
return key; // fallback to key
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
|
class Translator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Translator& instance();
|
||||||
|
~Translator() = default;
|
||||||
|
|
||||||
|
// Load translation file for given language code (e.g., "en_US")
|
||||||
|
bool loadLanguage(const QString& langCode);
|
||||||
|
|
||||||
|
// Translate a key, returns translated string or key if not found
|
||||||
|
QString tr(const QString& key) const;
|
||||||
|
|
||||||
|
// Get current language code
|
||||||
|
QString currentLanguage() const { return m_currentLang; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Translator() = default;
|
||||||
|
Q_DISABLE_COPY(Translator)
|
||||||
|
|
||||||
|
QMap<QString, QString> m_translations;
|
||||||
|
QString m_currentLang;
|
||||||
|
mutable QMutex m_mutex;
|
||||||
|
};
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "core/translator.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
// Load English translation
|
||||||
|
Translator& translator = Translator::instance();
|
||||||
|
if (!translator.loadLanguage("en_US")) {
|
||||||
|
qWarning() << "Failed to load translation";
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << translator.tr("appName");
|
||||||
|
qDebug() << translator.tr("welcomeMessage");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user