Guard desktop modal owners and remove obsolete message helpers
This commit is contained in:
1 parent
8b2b68d383
commit
7556695cc5
3 files changed
+20
-51
No files matched your search
@@ -179,8 +179,7 @@ MainWindow::MainWindow(QWidget *parent, DbManager* db, const QString& cfgPath,
|
||||
m_cpuLoadTimer = new QTimer(this);
|
||||
m_cpuLoadTimer->setTimerType(Qt::PreciseTimer);
|
||||
connect(m_cpuLoadTimer, &QTimer::timeout, this, [this] {
|
||||
auto* inst = gui_bridge_get_inst();
|
||||
if (!m_node || !m_node->isRunning() || !inst || !gui_bridge_is_uasync_ready()) {
|
||||
if (!m_node || !m_node->isRunning() || !gui_bridge_is_uasync_ready()) {
|
||||
m_cpuLoadPending = false; m_channelList->setCpuLoad(0); return;
|
||||
}
|
||||
if (m_cpuLoadPending) return;
|
||||
@@ -889,6 +888,7 @@ void MainWindow::onRadioCallEvent(const uint8_t* data, int len) {
|
||||
auto* box = new QMessageBox(QMessageBox::Question, QCoreApplication::translate("ChatGui", "Radio call"),
|
||||
QCoreApplication::translate("ChatGui", incoming ? "Incoming radio call from %1\nChannel: %2" : "Calling %1 by radio\nChannel: %2")
|
||||
.arg(name, channelName), QMessageBox::NoButton, this);
|
||||
box->setTextFormat(Qt::PlainText);
|
||||
box->setAttribute(Qt::WA_DeleteOnClose);
|
||||
m_radioCallId = id; m_radioCallWindow = box; m_radioCallAnswered = false;
|
||||
if (incoming) {
|
||||
@@ -1291,8 +1291,8 @@ void MainWindow::onTrayActivated(QSystemTrayIcon::ActivationReason reason) {
|
||||
void MainWindow::showShareInviteDialog(const QString& channelId) {
|
||||
if (!m_db || !m_db->isOpen()) return;
|
||||
|
||||
ShareInviteDialog dlg(channelId, m_db, this);
|
||||
dlg.exec();
|
||||
QPointer<ShareInviteDialog> dialog = new ShareInviteDialog(channelId, m_db, this);
|
||||
auto release = qScopeGuard([&] { delete dialog.data(); }); dialog->exec();
|
||||
}
|
||||
|
||||
void MainWindow::showInviteByLinkDialog(const QString& channelId) {
|
||||
@@ -1300,8 +1300,8 @@ void MainWindow::showInviteByLinkDialog(const QString& channelId) {
|
||||
QMessageBox::warning(this, QCoreApplication::translate("ChatGui", "Error"), QCoreApplication::translate("ChatGui", "Node is not running."));
|
||||
return;
|
||||
}
|
||||
InviteByLinkDialog dlg(channelId, m_node, this);
|
||||
dlg.exec();
|
||||
QPointer<InviteByLinkDialog> dialog = new InviteByLinkDialog(channelId, m_node, this);
|
||||
auto release = qScopeGuard([&] { delete dialog.data(); }); dialog->exec();
|
||||
}
|
||||
|
||||
void MainWindow::showJoinDialog() {
|
||||
@@ -1321,14 +1321,15 @@ void MainWindow::showJoinDialog() {
|
||||
autoLink = selText;
|
||||
}
|
||||
|
||||
JoinDialog dlg(m_node, m_db, this, autoLink);
|
||||
dlg.exec();
|
||||
QPointer<JoinDialog> dialog = new JoinDialog(m_node, m_db, this, autoLink);
|
||||
auto release = qScopeGuard([&] { delete dialog.data(); }); dialog->exec();
|
||||
}
|
||||
|
||||
void MainWindow::showSettings() {
|
||||
SettingsDialog dlg(m_cfgPath, m_db, m_node, m_recorder, this);
|
||||
dlg.exec();
|
||||
reloadChannels();
|
||||
QPointer<MainWindow> self(this);
|
||||
QPointer<SettingsDialog> dialog = new SettingsDialog(m_cfgPath, m_db, m_node, m_recorder, this);
|
||||
auto release = qScopeGuard([&] { delete dialog.data(); }); dialog->exec();
|
||||
if (self) reloadChannels();
|
||||
}
|
||||
|
||||
void MainWindow::openVideo(const QString& filePath) {
|
||||
@@ -1457,10 +1458,12 @@ void MainWindow::onCreateGroupRequested() {
|
||||
return;
|
||||
}
|
||||
|
||||
CreateGroupDialog dlg(this);
|
||||
if (dlg.exec() != QDialog::Accepted) return;
|
||||
QPointer<MainWindow> self(this); QPointer<CreateGroupDialog> dialog = new CreateGroupDialog(this);
|
||||
auto release = qScopeGuard([&] { delete dialog.data(); });
|
||||
const int result = dialog->exec();
|
||||
if (!self || !dialog || result != QDialog::Accepted) return;
|
||||
|
||||
QString name = dlg.groupName();
|
||||
QString name = dialog->groupName();
|
||||
if (name.isEmpty()) return;
|
||||
|
||||
auto* arg = static_cast<chat_create_auto_arg*>(u_calloc(1, sizeof(chat_create_auto_arg)));
|
||||
|
||||
@@ -104,40 +104,6 @@ static QPixmap makeAvatar(const QColor &color, const QString &letter, int size =
|
||||
return pix;
|
||||
}
|
||||
|
||||
static QVariant makeReaction(const QString &emoji, int count,
|
||||
const QList<QColor> &colors = {}) {
|
||||
QVariantMap m;
|
||||
m["emoji"] = emoji;
|
||||
m["count"] = count;
|
||||
if (!colors.isEmpty())
|
||||
m["colors"] = QVariant::fromValue(colors);
|
||||
return m;
|
||||
}
|
||||
|
||||
static QString parseJsonField(const QByteArray& data, const char* field) {
|
||||
QByteArray pat = QByteArray("\"") + field + "\":\"";
|
||||
int idx = data.indexOf(pat);
|
||||
if (idx < 0) return {};
|
||||
idx += pat.size();
|
||||
int end = data.indexOf('"', idx);
|
||||
if (end < 0) return {};
|
||||
return QString::fromUtf8(data.mid(idx, end - idx));
|
||||
}
|
||||
|
||||
static QString parseJsonFieldNum(const QByteArray& data, const char* field) {
|
||||
QByteArray pat = QByteArray("\"") + field + "\":";
|
||||
int idx = data.indexOf(pat);
|
||||
if (idx < 0) return {};
|
||||
idx += pat.size();
|
||||
int end = data.indexOf(',', idx);
|
||||
if (end < 0) end = data.indexOf('}', idx);
|
||||
if (end < 0) return {};
|
||||
return QString::fromUtf8(data.mid(idx, end - idx));
|
||||
}
|
||||
|
||||
static QString contentTypeFromJson(const QByteArray& data) {
|
||||
return parseJsonField(data, "ct");
|
||||
}
|
||||
|
||||
static void setVoiceMessageRoles(QStandardItem* item, const QByteArray& data,
|
||||
const QString& contentType, const QString& mediaDirBase,
|
||||
@@ -154,7 +120,6 @@ static void setVoiceMessageRoles(QStandardItem* item, const QByteArray& data,
|
||||
}
|
||||
}
|
||||
QString ct = contentType;
|
||||
if (ct.isEmpty()) ct = contentTypeFromJson(data);
|
||||
if (ct.isEmpty()) ct = "text/plain";
|
||||
item->setData(ct, MsgContentTypeRole);
|
||||
item->setData(channelId, MsgChannelIdRole);
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
* start подтверждает готовность сервисов и медиапривязок перед входом в poll.
|
||||
* start/stop/настройки принадлежат GUI-потоку; настройки менять при остановленном узле.
|
||||
* requestStop допускается из другого потока, stop ждёт worker и освобождает uasync вне callbacks.
|
||||
* Worker уничтожает instance; идентичность и NTP читаются через защищённую копию состояния,
|
||||
* обновляемую перед подтверждением старта и после каждого poll. instance — только заимствованный
|
||||
* Worker уничтожает instance после подтверждённого stopping в GUI: читатели SQLite должны снять handle в его слотах.
|
||||
* Идентичность, путь БД и NTP читаются через защищённую копию состояния перед стартом и после poll.
|
||||
* instance — только заимствованный
|
||||
* указатель для кода ядра: использовать в uasync, согласовав время жизни с stop/restart.
|
||||
* Logger общий для процесса; путь файла принадлежит объекту до закрытия лога. */
|
||||
#ifndef UTUN_NODE_H
|
||||
|
||||
Reference in new issue
Block a user