diff --git a/src/widget/form/chatform.cpp b/src/widget/form/chatform.cpp index 75cfc413a..5a8eabfc9 100644 --- a/src/widget/form/chatform.cpp +++ b/src/widget/form/chatform.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -147,6 +148,9 @@ ChatForm::ChatForm(Friend* chatFriend) loadHistoryAction = menu.addAction(QString(), this, SLOT(onLoadHistory())); copyStatusAction = statusMessageMenu.addAction(QString(), this, SLOT(onCopyStatusMessage())); + exportChatAction = + menu.addAction(QIcon::fromTheme("document-save"), QString(), this, SLOT(onExportChat())); + const Core* core = Core::getInstance(); connect(core, &Core::fileReceiveRequested, this, &ChatForm::onFileRecvRequest); connect(core, &Core::friendAvatarChanged, this, &ChatForm::onAvatarChange); @@ -669,6 +673,22 @@ void ChatForm::onLoadChatHistory() } } +QString getMsgAuthorDispName(const ToxPk& authorPk, const QString& dispName) +{ + QString authorStr; + const Core* core = Core::getInstance(); + bool isSelf = authorPk == core->getSelfId().getPublicKey(); + + if (!dispName.isEmpty()) { + authorStr = dispName; + } else if (isSelf) { + authorStr = core->getUsername(); + } else { + authorStr = ChatForm::resolveToxPk(authorPk); + } + return authorStr; +} + // TODO: Split on smaller methods (style) void ChatForm::loadHistory(const QDateTime& since, bool processUndelivered) { @@ -713,17 +733,9 @@ void ChatForm::loadHistory(const QDateTime& since, bool processUndelivered) // Show each messages const Core* core = Core::getInstance(); ToxPk authorPk(ToxId(it.sender).getPublicKey()); - QString authorStr; + QString authorStr = getMsgAuthorDispName(authorPk, it.dispName); bool isSelf = authorPk == core->getSelfId().getPublicKey(); - if (!it.dispName.isEmpty()) { - authorStr = it.dispName; - } else if (isSelf) { - authorStr = core->getUsername(); - } else { - authorStr = resolveToxPk(authorPk); - } - bool isAction = it.message.startsWith(ACTION_PREFIX, Qt::CaseInsensitive); bool needSending = !it.isSent && isSelf; @@ -994,6 +1006,7 @@ void ChatForm::retranslateUi() QString micObjectName = micButton->objectName(); loadHistoryAction->setText(tr("Load chat history...")); copyStatusAction->setText(tr("Copy")); + exportChatAction->setText(tr("Export to file")); updateMuteMicButton(); updateMuteVolButton(); @@ -1002,3 +1015,35 @@ void ChatForm::retranslateUi() netcam->setShowMessages(chatWidget->isVisible()); } } + +void ChatForm::onExportChat() +{ + History* history = Nexus::getProfile()->getHistory(); + QString pk = f->getPublicKey().toString(); + QDateTime epochStart = QDateTime::fromMSecsSinceEpoch(0); + QDateTime now = QDateTime::currentDateTime(); + QList msgs = history->getChatHistory(pk, epochStart, now); + + QString path = QFileDialog::getSaveFileName(0, tr("Save chat log"), QString{}, QString{}, 0, + QFileDialog::DontUseNativeDialog); + if (path.isEmpty()) { + return; + } + + QFile file(path); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + return; + } + + QString buffer; + for (const auto& it : msgs) { + QString timestamp = it.timestamp.toString(); + ToxPk authorPk(ToxId(it.sender).getPublicKey()); + QString author = getMsgAuthorDispName(authorPk, it.dispName); + + QString line = QString("%1\t%2\t%3\n").arg(timestamp, author, it.message); + buffer = buffer % line; + } + file.write(buffer.toUtf8()); + file.close(); +} diff --git a/src/widget/form/chatform.h b/src/widget/form/chatform.h index 1af2788d0..18e2826a2 100644 --- a/src/widget/form/chatform.h +++ b/src/widget/form/chatform.h @@ -27,6 +27,7 @@ #include "genericchatform.h" #include "src/core/corestructs.h" +#include "src/persistence/history.h" #include "src/widget/tool/screenshotgrabber.h" class Friend; @@ -99,6 +100,7 @@ private slots: void onScreenshotTaken(const QPixmap& pixmap); void doScreenshot(); void onCopyStatusMessage(); + void onExportChat(); private: void updateMuteMicButton(); @@ -129,6 +131,7 @@ private: OfflineMsgEngine* offlineEngine; QAction* loadHistoryAction; QAction* copyStatusAction; + QAction* exportChatAction; QHash ftransWidgets; QPointer callConfirm;