Commit 01c69521 authored by Andreas Traczyk's avatar Andreas Traczyk

record widgets: cleanup, refactor

Change-Id: Ifee1bdc6332e10937389bde7734bd07ea6c52070
parent da6dcc39
......@@ -244,16 +244,16 @@ void MessageWebView::runJsText()
void
MessageWebView::openAudioRecorder(int spikePosX, int spikePosY)
{
if (LRCInstance::hasVideoCall() || LRCInstance::avModel().getDevices().size() == 0) {
if (LRCInstance::avModel().getAudioInputDevices().size() == 0) {
// TODO: this predicate should be observed and used to show/hide the
// send audio message button in the webview
return;
}
// spikePosX, spikePosY are positions relative to Document
auto pointOfVideoButton = mapToGlobal(QPoint(spikePosX, spikePosY));
auto recorderWidth = recordWidget_->size().width();
auto recorderHeight = recordWidget_->size().height();
recordWidget_->getContainer()->setGeometry(pointOfVideoButton.x() - recorderWidth / 2,
pointOfVideoButton.y() - recorderHeight - recordWidgetMargin_,
recorderWidth, recorderHeight);
auto pointOfAudioButton = mapToGlobal(QPoint(spikePosX, spikePosY));
recordWidget_->getContainer()->move(
pointOfAudioButton.x() - recordWidget_->width() / 2,
pointOfAudioButton.y() - recordWidget_->height() - recordWidgetMargin_);
recordWidget_->openRecorder(true);
}
......@@ -261,15 +261,15 @@ void
MessageWebView::openVideoRecorder(int spikePosX, int spikePosY)
{
if (LRCInstance::hasVideoCall() || LRCInstance::avModel().getDevices().size() == 0) {
// TODO: this predicate should be observed and used to show/hide the
// send video message button in the webview
return;
}
// spikePosX, spikePosY are positions relative to Document
auto pointOfVideoButton = mapToGlobal(QPoint(spikePosX, spikePosY));
auto recorderWidth = recordWidget_->size().width();
auto recorderHeight = recordWidget_->size().height();
recordWidget_->getContainer()->setGeometry(pointOfVideoButton.x() - recorderWidth / 2,
pointOfVideoButton.y() - recorderHeight - recordWidgetMargin_,
recorderWidth, recorderHeight);
recordWidget_->getContainer()->move(
pointOfVideoButton.x() - recordWidget_->width() / 2,
pointOfVideoButton.y() - recordWidget_->height() - recordWidgetMargin_);
recordWidget_->openRecorder(false);
}
......
/**************************************************************************
* Copyright (C) 2015-2019 by Savoir-faire Linux *
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Yang Wang <yang.wang@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
......@@ -16,11 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
**************************************************************************/
#include "recordwidget.h"
#include "recordoverlay.h"
#include "ui_recordoverlay.h"
#include "recordwidget.h"
#include "utils.h"
RecordOverlay::RecordOverlay(RecordWidget* recordWidget) :
......@@ -85,11 +84,13 @@ RecordOverlay::switchToAboutToRecordPage()
ui->timerLabel->setText("00:00");
ui->redDotBlinkable->setVisible(false);
ui->recordOverlayStartOrFinishRecordingBtn->setVisible(true);
if(ui->recordOverlayStartOrFinishRecordingBtn->isChecked()) ui->recordOverlayStartOrFinishRecordingBtn->setOverlayButtonChecked(false);
if (ui->recordOverlayStartOrFinishRecordingBtn->isChecked()) {
ui->recordOverlayStartOrFinishRecordingBtn->setOverlayButtonChecked(false);
}
ui->recordOverlayRerecordBtn->setVisible(false);
ui->recordOverlaySendBtn->setVisible(false);
ui->recordOverlayDeleteBtn->setVisible(false);
ui->recordOverlayStartOrFinishRecordingBtn->setToolTip("press to start the audio record");
ui->recordOverlayStartOrFinishRecordingBtn->setToolTip(tr("press to start the audio record"));
}
void
......@@ -102,11 +103,13 @@ RecordOverlay::switchToRecordingPage()
ui->recordOverlayDeleteBtn->setVisible(false);
ui->recordOverlayRerecordBtn->setVisible(true);
ui->recordOverlaySendBtn->setVisible(false);
if(!ui->recordOverlayStartOrFinishRecordingBtn->isChecked()) ui->recordOverlayStartOrFinishRecordingBtn->setOverlayButtonChecked(true);
if (!ui->recordOverlayStartOrFinishRecordingBtn->isChecked()) {
ui->recordOverlayStartOrFinishRecordingBtn->setOverlayButtonChecked(true);
}
// set the tool tip
ui->recordOverlayStartOrFinishRecordingBtn->setToolTip("press to finish the audio record");
ui->recordOverlayDeleteBtn->setToolTip("press to stop the record");
ui->recordOverlayRerecordBtn->setToolTip("press to restart the audio record");
ui->recordOverlayStartOrFinishRecordingBtn->setToolTip(tr("press to finish the audio record"));
ui->recordOverlayDeleteBtn->setToolTip(tr("press to stop the record"));
ui->recordOverlayRerecordBtn->setToolTip(tr("press to restart the audio record"));
}
void
......@@ -118,9 +121,9 @@ RecordOverlay::switchToRecordedPage()
ui->recordOverlaySendBtn->setVisible(true);
ui->recordOverlayDeleteBtn->setVisible(true);
// set the tool tip
ui->recordOverlayRerecordBtn->setToolTip("press to restart the record");
ui->recordOverlaySendBtn->setToolTip("press to send");
ui->recordOverlayDeleteBtn->setToolTip("press to delete the recorded clip");
ui->recordOverlayRerecordBtn->setToolTip(tr("press to restart the record"));
ui->recordOverlaySendBtn->setToolTip(tr("press to send"));
ui->recordOverlayDeleteBtn->setToolTip(tr("press to delete the recorded clip"));
}
void
......@@ -162,7 +165,7 @@ RecordOverlay::on_recordOverlayStartOrFinishRecordingBtn_toggled(bool checked)
{
if(status_ == RecorderStatus::aboutToRecord) {
// start record function call, if call succeed, switch the page to recording page and start the timer
if(recordWidget_->actionToStartRecord()) {
if(recordWidget_->startRecording()) {
setUpRecorderStatus(RecorderStatus::recording);
} else {
ui->recordOverlayStartOrFinishRecordingBtn->setOverlayButtonChecked(!checked);
......@@ -170,7 +173,7 @@ RecordOverlay::on_recordOverlayStartOrFinishRecordingBtn_toggled(bool checked)
}
} else if(status_ == RecorderStatus::recording) {
// finish the record, if it succeed, switch the page and re-initialize the timer
if(recordWidget_->actionToFinishRecord()) {
if(recordWidget_->finishRecording()) {
setUpRecorderStatus(RecorderStatus::recorded);
} else {
ui->recordOverlayStartOrFinishRecordingBtn->setOverlayButtonChecked(!checked);
......@@ -188,7 +191,7 @@ RecordOverlay::on_recordOverlaySendBtn_pressed()
qDebug() << "The contented is not recorded and cannot be sent out";
return;
}
if(recordWidget_->actionToSend()) {
if(recordWidget_->sendRecording()) {
setUpRecorderStatus(RecorderStatus::aboutToRecord);
// define what to do when the record is sent out
recordWidget_->getContainer()->accept();
......@@ -199,12 +202,11 @@ void
RecordOverlay::on_recordOverlayDeleteBtn_pressed()
{
if(status_ != RecorderStatus::recorded) {
qDebug() << "The contente is not recorded and cannot be deleted";
qDebug() << "The content is not recorded and cannot be deleted";
return;
}
if(recordWidget_->actionToDeleteRecord()) {
setUpRecorderStatus(RecorderStatus::aboutToRecord);
}
recordWidget_->deleteRecording();
setUpRecorderStatus(RecorderStatus::aboutToRecord);
}
void
......@@ -214,17 +216,15 @@ RecordOverlay::on_recordOverlayRerecordBtn_pressed()
qDebug() << "it's not on the recording page and thus there's cannot re-record";
return;
}
if(recordWidget_->actionToReRecord()) {
// re-initialize the timer at the same time
setUpRecorderStatus(RecorderStatus::recording);
}
recordWidget_->recordAgain();
// re-initialize the timer at the same time
setUpRecorderStatus(RecorderStatus::recording);
}
void
RecordOverlay::whenAudioRecordProgressUpdate()
{
currentTime_ ++;
ui->timerLabel->setText(Utils::convertTimeDisplayFromMilisecond(currentTime_));
ui->timerLabel->setText(Utils::formattedTime(++currentTime_));
}
QPixmap
......@@ -238,4 +238,3 @@ RecordOverlay::setOriginPix(QPixmap pix)
{
redDotPix_ = pix;
}
/**************************************************************************
* Copyright (C) 2015-2019 by Savoir-faire Linux *
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Yang Wang <yang.wang@savoirfairelinux.com> *
* *
* This program is free software; you can redistribute it and/or modify *
......@@ -18,9 +18,6 @@
#pragma once
#include <QWidget>
#include <QTimer>
#include "widgethelpers.h"
namespace Ui {
......
......@@ -19,6 +19,9 @@
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="pixRedDot" stdset="0">
<pixmap resource="ressources.qrc">:/images/icons/av_icons/fiber_manual_record-24px.svg</pixmap>
</property>
......
/**************************************************************************
* Copyright (C) 2015-2019 by Savoir-faire Linux *
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Yang Wang <yang.wang@savoirfairelinux.com> *
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> *
* *
......@@ -24,7 +24,9 @@
#include <QtConcurrent/QtConcurrent>
RecordWidget::RecordWidget(QWidget *parent) :
PopupWidget(parent, Qt::black, PopupDialog::SpikeLabelAlignment::AlignHCenter),
PopupWidget(parent,
Qt::black,
PopupDialog::SpikeLabelAlignment::AlignHCenter),
ui(new Ui::RecordWidget)
{
ui->setupUi(this);
......@@ -34,62 +36,57 @@ RecordWidget::RecordWidget(QWidget *parent) :
}
RecordWidget::~RecordWidget()
{
}
{}
bool
RecordWidget::actionToStartRecord()
RecordWidget::startRecording()
{
bool isSuccessful = false;
if(!isAudio_ && !LRCInstance::renderer()->isPreviewing()){return isSuccessful;}
try {
recordedFilePath_ = QString::fromStdString(LRCInstance::avModel().startLocalRecorder(isAudio_));
isSuccessful = true;
}
catch (...) {
} catch (...) {
qDebug() << "The start of record fails";
}
return isSuccessful;
}
bool
RecordWidget::actionToFinishRecord()
RecordWidget::finishRecording()
{
bool isSuccessful = false;
try {
LRCInstance::avModel().stopLocalRecorder(recordedFilePath_.toStdString());
isSuccessful = true;
}
catch (...) {
} catch (...) {
qDebug() << "The finish of record fails";
}
return isSuccessful;
}
bool
RecordWidget::actionToReRecord()
void
RecordWidget::recordAgain()
{
QtConcurrent::run(
[this] {
Utils::oneShotConnect(&LRCInstance::avModel(), &lrc::api::AVModel::recordPlaybackStopped,
[this] {
deleteRecordedFileDetached(recordedFilePath_);
recordedFilePath_ = QString::fromStdString(LRCInstance::avModel().startLocalRecorder(isAudio_));
});
Utils::forceDeleteAsync(recordedFilePath_);
recordedFilePath_ = QString::fromStdString(LRCInstance::avModel().startLocalRecorder(isAudio_));
});
LRCInstance::avModel().stopLocalRecorder(recordedFilePath_.toStdString());
});
return true;
}
bool
RecordWidget::actionToDeleteRecord()
void
RecordWidget::deleteRecording()
{
deleteRecordedFileDetached(recordedFilePath_);
return true;
Utils::forceDeleteAsync(recordedFilePath_);
}
bool
RecordWidget::actionToSend()
RecordWidget::sendRecording()
{
bool isSuccessful = false;
// send out the stored video file
......@@ -101,31 +98,25 @@ RecordWidget::actionToSend()
// reset file path, make sure that the file that is needed to sent will not be deleted
recordedFilePath_.clear();
isSuccessful = true;
}
catch (...) {
} catch (...) {
qDebug().noquote() << "\n" << "Send file failed !" << "\n";
}
return isSuccessful;
}
bool
RecordWidget::isAudio()
{
return isAudio_;
}
void
RecordWidget::openRecorder(bool isaudio)
RecordWidget::openRecorder(bool isAudio)
{
isAudio_ = isaudio;
widgetContainer_->show();
isAudio_ = isAudio;
if(!isAudio_) {
LRCInstance::avModel().startPreview();
}
widgetContainer_->show();
}
void RecordWidget::resizeEvent(QResizeEvent* event)
{
Q_UNUSED(event);
recordOverlay_->resize(this->size());
previewWidget_->resize(this->size());
......@@ -135,26 +126,8 @@ void RecordWidget::resizeEvent(QResizeEvent* event)
void
RecordWidget::hideEvent(QHideEvent* event)
{
Q_UNUSED(event);
if(!isAudio_) {
LRCInstance::avModel().stopPreview();
}
}
void
RecordWidget::deleteRecordedFileDetached(const QString deleteFilePath)
{
// keep deleting file until the process holding it let go
// Or the file itself does not exist anymore
QtConcurrent::run(
[deleteFilePath] {
QFile file(deleteFilePath);
if (!QFile::exists(deleteFilePath))
return;
int deletionCount { 0 };
while (!file.remove() && deletionCount < 5) {
qDebug().noquote() << "\n" << file.errorString() << "\n";
QThread::msleep(10);
++ deletionCount;
}
});
}
/**************************************************************************
* Copyright (C) 2015-2019 by Savoir-faire Linux *
* Copyright (C) 2019 by Savoir-faire Linux *
* Author: Yang Wang <yang.wang@savoirfairelinux.com> *
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com> *
* *
......@@ -19,43 +19,35 @@
#pragma once
#include <QWidget>
#include "widgethelpers.h"
#include "recordoverlay.h"
#include "previewwidget.h"
#include <QWidget>
namespace Ui {
class RecordWidget;
}
class RecordWidget : public PopupWidget
class RecordWidget final : public PopupWidget
{
Q_OBJECT
public:
explicit RecordWidget(QWidget *parent = nullptr);
~RecordWidget();
bool startRecording();
bool finishRecording();
bool sendRecording();
void recordAgain();
void deleteRecording();
bool actionToStartRecord();
bool actionToFinishRecord();
bool actionToReRecord();
bool actionToDeleteRecord();
bool actionToSend();
bool isAudio();
void openRecorder(bool isaudio);
void openRecorder(bool isAudio);
protected:
void resizeEvent(QResizeEvent* event);
void resizeEvent(QResizeEvent* event) override;
void hideEvent(QHideEvent* event) override;
private:
void deleteRecordedFileDetached(const QString deleteFilePath);
private:
Ui::RecordWidget* ui;
......@@ -64,4 +56,4 @@ private:
bool isAudio_ = true;
QString recordedFilePath_;
};
};
\ No newline at end of file
......@@ -40,6 +40,7 @@
#include <QFile>
#include <QMessageBox>
#include <QScreen>
#include <QtConcurrent/QtConcurrent>
#include <globalinstances.h>
......@@ -302,6 +303,25 @@ Utils::getRealSize(QScreen* screen)
#endif
}
void
Utils::forceDeleteAsync(const QString& path)
{
// keep deleting file until the process holding it let go
// Or the file itself does not exist anymore
QtConcurrent::run(
[path] {
QFile file(path);
if (!QFile::exists(path))
return;
int retries{ 0 };
while (!file.remove() && retries < 5) {
qDebug().noquote() << "\n" << file.errorString() << "\n";
QThread::msleep(10);
++retries;
}
});
}
void
Utils::cleanUpdateFiles()
{
......@@ -645,24 +665,23 @@ Utils::cropImage(const QImage& img)
}
QString
Utils::convertTimeDisplayFromMilisecond(int seconds)
{
int minutes = seconds/ 60;
int secondToDisplay = seconds % 60;
std::string sec, min, time;
if(secondToDisplay / 10 < 1) {
sec = "0" + std::to_string(secondToDisplay);
} else {
sec = std::to_string(secondToDisplay);
}
if(minutes / 10 < 1) {
min = "0" + std::to_string(minutes);
Utils::formattedTime(int duration)
{
if (duration == 0) return {};
std::string formattedString;
auto minutes = duration / 60;
auto seconds = duration % 60;
if (minutes > 0) {
formattedString += std::to_string(minutes) + ":";
if (formattedString.length() == 2) {
formattedString = "0" + formattedString;
}
} else {
min = std::to_string(minutes);
formattedString += "00:";
}
time = min + ":" + sec;
return QString::fromStdString(time);
if (seconds < 10) formattedString += "0";
formattedString += std::to_string(seconds);
return QString::fromStdString(formattedString);
}
QByteArray
......
......@@ -72,7 +72,7 @@ void setStackWidget(QStackedWidget *stack, QWidget *widget);
void showSystemNotification(QWidget* widget, const QString& message, long delay = 5000);
void showSystemNotification(QWidget* widget, const QString& sender, const QString& message, long delay = 5000);
QSize getRealSize(QScreen* screen);
void drawBlackCircularImageOntoLabel(QLabel* containerWidget);
void forceDeleteAsync(const QString& path);
// updates
void cleanUpdateFiles();
......@@ -109,7 +109,7 @@ QImage accountPhoto(const lrc::api::account::Info& accountInfo, const QSize& siz
QImage cropImage(const QImage& img);
// time
QString convertTimeDisplayFromMilisecond(int seconds);
QString formattedTime(int seconds);
// misc helpers
void swapQListWidgetItems(QListWidget* list, bool down = true);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment