|
|
|
|
@ -65,132 +65,22 @@ MainWindow::MainWindow(QWidget *parent, DbManager* db, const QString& cfgPath,
|
|
|
|
|
const QString& dbPath, const QString& debugFile, |
|
|
|
|
const QString& debugLevel, const QString& debugCategories) |
|
|
|
|
: QMainWindow(parent) |
|
|
|
|
, m_channelList(nullptr) |
|
|
|
|
, m_messageList(nullptr) |
|
|
|
|
, m_accountList(nullptr) |
|
|
|
|
, m_trayIcon(nullptr) |
|
|
|
|
, m_trayMenu(nullptr) |
|
|
|
|
, m_db(db) |
|
|
|
|
, m_cfgPath(cfgPath) |
|
|
|
|
, m_cfgDbPath(dbPath) |
|
|
|
|
, m_cfgDebugFile(debugFile) |
|
|
|
|
, m_cfgDebugLevel(debugLevel) |
|
|
|
|
, m_channelList(nullptr), m_messageList(nullptr), m_accountList(nullptr) |
|
|
|
|
, m_trayIcon(nullptr), m_trayMenu(nullptr) |
|
|
|
|
, m_db(db), m_cfgPath(cfgPath), m_cfgDbPath(dbPath) |
|
|
|
|
, m_cfgDebugFile(debugFile), m_cfgDebugLevel(debugLevel) |
|
|
|
|
, m_cfgDebugCategories(debugCategories) |
|
|
|
|
{ |
|
|
|
|
setWindowTitle("Chat"); |
|
|
|
|
resize(900, 600); |
|
|
|
|
setupUi(); |
|
|
|
|
setupTray(); |
|
|
|
|
|
|
|
|
|
SoundManager* sm = SoundManager::instance(); |
|
|
|
|
if (sm->init()) { |
|
|
|
|
QString soundDir; |
|
|
|
|
QString msgInFile, msgOutFile, connectFile, disconnectFile; |
|
|
|
|
|
|
|
|
|
QFile cfgFile(m_cfgPath); |
|
|
|
|
if (cfgFile.open(QIODevice::ReadOnly | QIODevice::Text)) { |
|
|
|
|
bool inGui = false; |
|
|
|
|
QTextStream in(&cfgFile); |
|
|
|
|
while (!in.atEnd()) { |
|
|
|
|
QString line = in.readLine().trimmed(); |
|
|
|
|
if (line == "[gui]") { inGui = true; continue; } |
|
|
|
|
if (line.startsWith("[") && line.endsWith("]")) inGui = false; |
|
|
|
|
if (!inGui) continue; |
|
|
|
|
if (line.startsWith("sound_dir=")) |
|
|
|
|
soundDir = line.mid(10).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_msg_incoming=")) |
|
|
|
|
msgInFile = line.mid(19).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_msg_outgoing=")) |
|
|
|
|
msgOutFile = line.mid(19).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_connect=")) |
|
|
|
|
connectFile = line.mid(14).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_disconnect=")) |
|
|
|
|
disconnectFile = line.mid(17).trimmed(); |
|
|
|
|
} |
|
|
|
|
cfgFile.close(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (soundDir.isEmpty()) soundDir = "sounds"; |
|
|
|
|
QDir binDir(QApplication::applicationDirPath()); |
|
|
|
|
QString baseDir = QDir::isAbsolutePath(soundDir) ? soundDir |
|
|
|
|
: binDir.absoluteFilePath(soundDir); |
|
|
|
|
auto resolvePath = [&baseDir](const QString& file) -> QString { |
|
|
|
|
if (file.isEmpty()) return {}; |
|
|
|
|
return QDir::cleanPath(baseDir + "/" + file); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct { const char* name; QString file; } events[] = { |
|
|
|
|
{"msg_incoming", msgInFile}, |
|
|
|
|
{"msg_outgoing", msgOutFile}, |
|
|
|
|
{"connect", connectFile}, |
|
|
|
|
{"disconnect", disconnectFile}, |
|
|
|
|
}; |
|
|
|
|
for (auto& e : events) { |
|
|
|
|
if (!e.file.isEmpty()) { |
|
|
|
|
QString path = resolvePath(e.file); |
|
|
|
|
sm->loadSound(e.name, path); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (m_db && m_db->isOpen()) { |
|
|
|
|
sm->setEnabled(m_db->getUiStateInt("sound_enabled", 1)); |
|
|
|
|
sm->setVolume(m_db->getUiStateInt("sound_volume", 80) / 100.0f); |
|
|
|
|
QString soundEvents[] = {"msg_incoming", "msg_outgoing", "connect", "disconnect"}; |
|
|
|
|
for (int i = 0; i < 4; i++) { |
|
|
|
|
const QString& ek = soundEvents[i]; |
|
|
|
|
bool on = m_db->getUiStateInt(QStringLiteral("sound_%1_on").arg(ek), i == 0 ? 1 : 0); |
|
|
|
|
float ev = m_db->getUiStateInt(QStringLiteral("sound_%1_vol").arg(ek), 80) / 100.0f; |
|
|
|
|
sm->setEvent(ek, on, ev); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setupSoundFromConfig(); |
|
|
|
|
if (m_db) { |
|
|
|
|
s_mainWindow = this; |
|
|
|
|
gui_bridge_set_msg_received_cb(onMsgReceivedCallback); |
|
|
|
|
gui_bridge_set_channel_updated_cb(onChannelUpdatedCallback); |
|
|
|
|
gui_bridge_set_members_changed_cb(onMembersChangedCallback); |
|
|
|
|
gui_bridge_set_my_node_id_cb([](uint64_t nid) { |
|
|
|
|
qDebug("MainWindow: MY_NODE_ID setMyNodeId(%016llx)", (unsigned long long)nid); |
|
|
|
|
if (s_mainWindow && s_mainWindow->m_db) s_mainWindow->m_db->setMyNodeId((quint64)nid); |
|
|
|
|
}); |
|
|
|
|
gui_bridge_set_auto_connect_status_cb(onAutoConnectStatusCallback); |
|
|
|
|
gui_bridge_set_channel_peers_online_cb(onChannelPeersOnlineCallback); |
|
|
|
|
gui_bridge_set_db_ready_cb([]() { |
|
|
|
|
if (!s_mainWindow || !s_mainWindow->m_db) return; |
|
|
|
|
s_mainWindow->m_db->setDb(chat_core_get_db()); |
|
|
|
|
s_mainWindow->m_channelList->loadChannels(); |
|
|
|
|
|
|
|
|
|
QString lastCid = QSettings().value("last_channel_id").toString(); |
|
|
|
|
if (!lastCid.isEmpty()) { |
|
|
|
|
s_mainWindow->m_channelList->selectChannel(lastCid); |
|
|
|
|
s_mainWindow->m_accountList->setChannel(lastCid); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
setupBridgeCallbacks(); |
|
|
|
|
setupMessaging(); |
|
|
|
|
setupNode(); |
|
|
|
|
|
|
|
|
|
connect(m_channelList, &ChannelList::channelSelected, |
|
|
|
|
this, [this](const QString& channelId) { |
|
|
|
|
QSettings().setValue("last_channel_id", channelId); |
|
|
|
|
m_currentChannelId = channelId; |
|
|
|
|
m_messageList->loadChannel(channelId); |
|
|
|
|
m_accountList->setChannel(channelId); |
|
|
|
|
|
|
|
|
|
QByteArray cidBA = channelId.toUtf8(); |
|
|
|
|
char* cid = u_strdup(cidBA.constData()); |
|
|
|
|
if (cid) gui_bridge_post_uasync_fn(chat_core_connect_channel_trampoline, cid); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
connect(m_channelList, &ChannelList::inviteRequested, |
|
|
|
|
this, &MainWindow::showInviteDialog); |
|
|
|
|
connect(m_channelList, &ChannelList::joinRequested, |
|
|
|
|
this, &MainWindow::showJoinDialog); |
|
|
|
|
connect(m_channelList, &ChannelList::createGroupRequested, |
|
|
|
|
this, &MainWindow::onCreateGroupRequested); |
|
|
|
|
connect(m_channelList, &ChannelList::settingsRequested, |
|
|
|
|
this, &MainWindow::showSettings); |
|
|
|
|
setupConnects(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -245,10 +135,95 @@ void MainWindow::setupNode() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::setupMessaging() { |
|
|
|
|
/* Initialize gui_bridge (GUI side) */ |
|
|
|
|
gui_bridge_init(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::setupSoundFromConfig() { |
|
|
|
|
SoundManager* sm = SoundManager::instance(); |
|
|
|
|
if (!sm->init()) return; |
|
|
|
|
|
|
|
|
|
QString soundDir, msgInFile, msgOutFile, connectFile, disconnectFile; |
|
|
|
|
QFile cfgFile(m_cfgPath); |
|
|
|
|
if (cfgFile.open(QIODevice::ReadOnly | QIODevice::Text)) { |
|
|
|
|
bool inGui = false; |
|
|
|
|
QTextStream in(&cfgFile); |
|
|
|
|
while (!in.atEnd()) { |
|
|
|
|
QString line = in.readLine().trimmed(); |
|
|
|
|
if (line == "[gui]") { inGui = true; continue; } |
|
|
|
|
if (line.startsWith("[") && line.endsWith("]")) inGui = false; |
|
|
|
|
if (!inGui) continue; |
|
|
|
|
if (line.startsWith("sound_dir=")) soundDir = line.mid(10).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_msg_incoming=")) msgInFile = line.mid(19).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_msg_outgoing=")) msgOutFile = line.mid(19).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_connect=")) connectFile = line.mid(14).trimmed(); |
|
|
|
|
else if (line.startsWith("sound_disconnect=")) disconnectFile = line.mid(17).trimmed(); |
|
|
|
|
} |
|
|
|
|
cfgFile.close(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (soundDir.isEmpty()) soundDir = "sounds"; |
|
|
|
|
QDir binDir(QApplication::applicationDirPath()); |
|
|
|
|
QString baseDir = QDir::isAbsolutePath(soundDir) ? soundDir : binDir.absoluteFilePath(soundDir); |
|
|
|
|
auto resolvePath = [&baseDir](const QString& f) { return f.isEmpty() ? QString() : QDir::cleanPath(baseDir + "/" + f); }; |
|
|
|
|
|
|
|
|
|
struct { const char* name; QString file; } events[] = { |
|
|
|
|
{"msg_incoming", msgInFile}, {"msg_outgoing", msgOutFile}, |
|
|
|
|
{"connect", connectFile}, {"disconnect", disconnectFile}, |
|
|
|
|
}; |
|
|
|
|
for (auto& e : events) { if (!e.file.isEmpty()) sm->loadSound(e.name, resolvePath(e.file)); } |
|
|
|
|
|
|
|
|
|
if (m_db && m_db->isOpen()) { |
|
|
|
|
sm->setEnabled(m_db->getUiStateInt("sound_enabled", 1)); |
|
|
|
|
sm->setVolume(m_db->getUiStateInt("sound_volume", 80) / 100.0f); |
|
|
|
|
QString se[] = {"msg_incoming", "msg_outgoing", "connect", "disconnect"}; |
|
|
|
|
for (int i = 0; i < 4; i++) { |
|
|
|
|
const QString& ek = se[i]; |
|
|
|
|
sm->setEvent(ek, m_db->getUiStateInt(QStringLiteral("sound_%1_on").arg(ek), i == 0 ? 1 : 0), |
|
|
|
|
m_db->getUiStateInt(QStringLiteral("sound_%1_vol").arg(ek), 80) / 100.0f); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::setupBridgeCallbacks() { |
|
|
|
|
s_mainWindow = this; |
|
|
|
|
gui_bridge_set_msg_received_cb(onMsgReceivedCallback); |
|
|
|
|
gui_bridge_set_channel_updated_cb(onChannelUpdatedCallback); |
|
|
|
|
gui_bridge_set_members_changed_cb(onMembersChangedCallback); |
|
|
|
|
gui_bridge_set_my_node_id_cb([](uint64_t nid) { |
|
|
|
|
qDebug("MainWindow: MY_NODE_ID setMyNodeId(%016llx)", (unsigned long long)nid); |
|
|
|
|
if (s_mainWindow && s_mainWindow->m_db) s_mainWindow->m_db->setMyNodeId((quint64)nid); |
|
|
|
|
}); |
|
|
|
|
gui_bridge_set_auto_connect_status_cb(onAutoConnectStatusCallback); |
|
|
|
|
gui_bridge_set_channel_peers_online_cb(onChannelPeersOnlineCallback); |
|
|
|
|
gui_bridge_set_db_ready_cb([]() { |
|
|
|
|
if (!s_mainWindow || !s_mainWindow->m_db) return; |
|
|
|
|
s_mainWindow->m_db->setDb(chat_core_get_db()); |
|
|
|
|
s_mainWindow->m_channelList->loadChannels(); |
|
|
|
|
QString lastCid = QSettings().value("last_channel_id").toString(); |
|
|
|
|
if (!lastCid.isEmpty()) { |
|
|
|
|
s_mainWindow->m_channelList->selectChannel(lastCid); |
|
|
|
|
s_mainWindow->m_accountList->setChannel(lastCid); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::setupConnects() { |
|
|
|
|
connect(m_channelList, &ChannelList::channelSelected, |
|
|
|
|
this, [this](const QString& channelId) { |
|
|
|
|
QSettings().setValue("last_channel_id", channelId); |
|
|
|
|
m_currentChannelId = channelId; |
|
|
|
|
m_messageList->loadChannel(channelId); |
|
|
|
|
m_accountList->setChannel(channelId); |
|
|
|
|
QByteArray cidBA = channelId.toUtf8(); |
|
|
|
|
char* cid = u_strdup(cidBA.constData()); |
|
|
|
|
if (cid) gui_bridge_post_uasync_fn(chat_core_connect_channel_trampoline, cid); |
|
|
|
|
}); |
|
|
|
|
connect(m_channelList, &ChannelList::inviteRequested, this, &MainWindow::showInviteDialog); |
|
|
|
|
connect(m_channelList, &ChannelList::joinRequested, this, &MainWindow::showJoinDialog); |
|
|
|
|
connect(m_channelList, &ChannelList::createGroupRequested, this, &MainWindow::onCreateGroupRequested); |
|
|
|
|
connect(m_channelList, &ChannelList::settingsRequested, this, &MainWindow::showSettings); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::setupTray() { |
|
|
|
|
m_trayIcon = new QSystemTrayIcon(this); |
|
|
|
|
m_trayIcon->setIcon(style()->standardIcon(QStyle::SP_ComputerIcon)); |
|
|
|
|
|