mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-23 08:55:26 +02:00
settings: refactor for SettingsView - stage two
1. Remove redundant functions in AvAdapter 2. Add CurrentDevice for video device treatment Audio device treatment should be improved in the next stage 3. Add QSortFilterProxyModel to all video list models and manage them together to avoid redundant function calls 4. Video device call action should be responsive to device change as well Gitlab: #508 Change-Id: I3df949a08bc19042b73f033139cd6ab06925c0b6
This commit is contained in:
parent
a196513d2e
commit
e0737f4b70
30 changed files with 893 additions and 1101 deletions
|
@ -67,10 +67,7 @@ set(COMMON_SOURCES
|
|||
${SRC_DIR}/mediacodeclistmodel.cpp
|
||||
${SRC_DIR}/accountstomigratelistmodel.cpp
|
||||
${SRC_DIR}/audiodevicemodel.cpp
|
||||
${SRC_DIR}/videoinputdevicemodel.cpp
|
||||
${SRC_DIR}/pluginlistpreferencemodel.cpp
|
||||
${SRC_DIR}/videoformatfpsmodel.cpp
|
||||
${SRC_DIR}/videoformatresolutionmodel.cpp
|
||||
${SRC_DIR}/audiomanagerlistmodel.cpp
|
||||
${SRC_DIR}/qmlregister.cpp
|
||||
${SRC_DIR}/utilsadapter.cpp
|
||||
|
@ -88,7 +85,8 @@ set(COMMON_SOURCES
|
|||
${SRC_DIR}/wizardviewstepmodel.cpp
|
||||
${SRC_DIR}/avatarregistry.cpp
|
||||
${SRC_DIR}/currentconversation.cpp
|
||||
${SRC_DIR}/currentaccount.cpp)
|
||||
${SRC_DIR}/currentaccount.cpp
|
||||
${SRC_DIR}/videodevices.cpp)
|
||||
|
||||
set(COMMON_HEADERS
|
||||
${SRC_DIR}/avatarimageprovider.h
|
||||
|
@ -123,10 +121,7 @@ set(COMMON_HEADERS
|
|||
${SRC_DIR}/mediacodeclistmodel.h
|
||||
${SRC_DIR}/accountstomigratelistmodel.h
|
||||
${SRC_DIR}/audiodevicemodel.h
|
||||
${SRC_DIR}/videoinputdevicemodel.h
|
||||
${SRC_DIR}/pluginlistpreferencemodel.h
|
||||
${SRC_DIR}/videoformatfpsmodel.h
|
||||
${SRC_DIR}/videoformatresolutionmodel.h
|
||||
${SRC_DIR}/audiomanagerlistmodel.h
|
||||
${SRC_DIR}/qmlregister.h
|
||||
${SRC_DIR}/abstractlistmodelbase.h
|
||||
|
@ -147,7 +142,8 @@ set(COMMON_HEADERS
|
|||
${SRC_DIR}/wizardviewstepmodel.h
|
||||
${SRC_DIR}/avatarregistry.h
|
||||
${SRC_DIR}/currentconversation.h
|
||||
${SRC_DIR}/currentaccount.h)
|
||||
${SRC_DIR}/currentaccount.h
|
||||
${SRC_DIR}/videodevices.h)
|
||||
|
||||
set(QML_LIBS
|
||||
Qt5::Quick
|
||||
|
|
|
@ -263,32 +263,12 @@ AccountAdapter::savePassword(const QString& accountId,
|
|||
return lrcInstance_->accountModel().changeAccountPassword(accountId, oldPassword, newPassword);
|
||||
}
|
||||
|
||||
void
|
||||
AccountAdapter::startPreviewing(bool force)
|
||||
{
|
||||
lrcInstance_->renderer()->startPreviewing(force);
|
||||
}
|
||||
|
||||
void
|
||||
AccountAdapter::stopPreviewing()
|
||||
{
|
||||
if (!lrcInstance_->hasActiveCall(true) && lrcInstance_->renderer()->isPreviewing()) {
|
||||
lrcInstance_->renderer()->stopPreviewing();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AccountAdapter::hasVideoCall()
|
||||
{
|
||||
return lrcInstance_->hasActiveCall(true);
|
||||
}
|
||||
|
||||
bool
|
||||
AccountAdapter::isPreviewing()
|
||||
{
|
||||
return lrcInstance_->renderer()->isPreviewing();
|
||||
}
|
||||
|
||||
void
|
||||
AccountAdapter::setCurrAccDisplayName(const QString& text)
|
||||
{
|
||||
|
|
|
@ -77,11 +77,7 @@ public:
|
|||
Q_INVOKABLE bool savePassword(const QString& accountId,
|
||||
const QString& oldPassword,
|
||||
const QString& newPassword);
|
||||
|
||||
Q_INVOKABLE void startPreviewing(bool force = false);
|
||||
Q_INVOKABLE void stopPreviewing();
|
||||
Q_INVOKABLE bool hasVideoCall();
|
||||
Q_INVOKABLE bool isPreviewing();
|
||||
Q_INVOKABLE void setCurrAccDisplayName(const QString& text);
|
||||
Q_INVOKABLE void setCurrentAccountAvatarFile(const QString& source);
|
||||
Q_INVOKABLE void setCurrentAccountAvatarBase64(const QString& source = {});
|
||||
|
|
|
@ -36,36 +36,18 @@
|
|||
AvAdapter::AvAdapter(LRCInstance* instance, QObject* parent)
|
||||
: QmlAdapterBase(instance, parent)
|
||||
{
|
||||
auto& avModel = lrcInstance_->avModel();
|
||||
|
||||
deviceListSize_ = avModel.getDevices().size();
|
||||
connect(&avModel, &lrc::api::AVModel::audioDeviceEvent, this, &AvAdapter::onAudioDeviceEvent);
|
||||
connect(&avModel, &lrc::api::AVModel::deviceEvent, this, &AvAdapter::onVideoDeviceEvent);
|
||||
connect(lrcInstance_->renderer(), &RenderManager::previewFrameStarted, [this]() {
|
||||
// TODO: listen to the correct signals that are needed to be added in daemon or lrc
|
||||
auto callId = getCurrentCallId();
|
||||
auto callId = lrcInstance_->getCurrentCallId();
|
||||
if (!callId.isEmpty())
|
||||
set_currentRenderingDeviceType(
|
||||
lrcInstance_->avModel().getCurrentRenderedDevice(callId).type);
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::selectVideoInputDeviceByName(const QString& deviceName)
|
||||
{
|
||||
auto deviceId = lrcInstance_->avModel().getDeviceIdFromName(deviceName);
|
||||
if (deviceId.isEmpty()) {
|
||||
qWarning() << "Couldn't find device: " << deviceName;
|
||||
return;
|
||||
}
|
||||
selectVideoInputDeviceById(deviceId);
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::selectVideoInputDeviceById(const QString& deviceId)
|
||||
{
|
||||
lrcInstance_->avModel().setCurrentVideoCaptureDevice(deviceId);
|
||||
lrcInstance_->avModel().switchInputTo(deviceId, getCurrentCallId());
|
||||
connect(&lrcInstance_->avModel(),
|
||||
&lrc::api::AVModel::audioDeviceEvent,
|
||||
this,
|
||||
&AvAdapter::onAudioDeviceEvent);
|
||||
}
|
||||
|
||||
// The top left corner of primary screen is (0, 0).
|
||||
|
@ -114,7 +96,7 @@ AvAdapter::shareEntireScreen(int screenNumber)
|
|||
rect.y(),
|
||||
rect.width() * screen->devicePixelRatio(),
|
||||
rect.height() * screen->devicePixelRatio(),
|
||||
getCurrentCallId());
|
||||
lrcInstance_->getCurrentCallId());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -127,7 +109,7 @@ AvAdapter::shareAllScreens()
|
|||
arrangementRect.y(),
|
||||
arrangementRect.width(),
|
||||
arrangementRect.height(),
|
||||
getCurrentCallId());
|
||||
lrcInstance_->getCurrentCallId());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -187,7 +169,7 @@ AvAdapter::captureAllScreens()
|
|||
void
|
||||
AvAdapter::shareFile(const QString& filePath)
|
||||
{
|
||||
lrcInstance_->avModel().setInputFile(filePath, getCurrentCallId());
|
||||
lrcInstance_->avModel().setInputFile(filePath, lrcInstance_->getCurrentCallId());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -206,7 +188,7 @@ AvAdapter::shareScreenArea(unsigned x, unsigned y, unsigned width, unsigned heig
|
|||
y,
|
||||
width < 128 ? 128 : width,
|
||||
height < 128 ? 128 : height,
|
||||
getCurrentCallId());
|
||||
lrcInstance_->getCurrentCallId());
|
||||
});
|
||||
#else
|
||||
lrcInstance_->avModel().setDisplay(getScreenNumber(),
|
||||
|
@ -214,14 +196,14 @@ AvAdapter::shareScreenArea(unsigned x, unsigned y, unsigned width, unsigned heig
|
|||
y,
|
||||
width < 128 ? 128 : width,
|
||||
height < 128 ? 128 : height,
|
||||
getCurrentCallId());
|
||||
lrcInstance_->getCurrentCallId());
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::stopSharing()
|
||||
{
|
||||
auto callId = getCurrentCallId();
|
||||
auto callId = lrcInstance_->getCurrentCallId();
|
||||
if (!callId.isEmpty())
|
||||
lrcInstance_->avModel().switchInputTo(lrcInstance_->avModel().getCurrentVideoCaptureDevice(),
|
||||
callId);
|
||||
|
@ -248,82 +230,6 @@ AvAdapter::onAudioDeviceEvent()
|
|||
Q_EMIT audioDeviceListChanged(inputs, outputs);
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::onVideoDeviceEvent()
|
||||
{
|
||||
auto& avModel = lrcInstance_->avModel();
|
||||
auto defaultDevice = avModel.getDefaultDevice();
|
||||
auto currentCaptureDevice = avModel.getCurrentVideoCaptureDevice();
|
||||
QString callId = getCurrentCallId();
|
||||
|
||||
/*
|
||||
* Decide whether a device has plugged, unplugged, or nothing has changed.
|
||||
*/
|
||||
auto deviceList = avModel.getDevices();
|
||||
auto currentDeviceListSize = deviceList.size();
|
||||
|
||||
DeviceEvent deviceEvent {DeviceEvent::None};
|
||||
if (currentDeviceListSize > deviceListSize_) {
|
||||
deviceEvent = DeviceEvent::Added;
|
||||
} else if (currentDeviceListSize < deviceListSize_) {
|
||||
/*
|
||||
* Check if the currentCaptureDevice is still in the device list.
|
||||
*/
|
||||
if (std::find(std::begin(deviceList), std::end(deviceList), currentCaptureDevice)
|
||||
== std::end(deviceList)) {
|
||||
deviceEvent = DeviceEvent::RemovedCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
auto cb = [this, currentDeviceListSize, deviceEvent, defaultDevice, callId] {
|
||||
auto& avModel = lrcInstance_->avModel();
|
||||
if (currentDeviceListSize == 0) {
|
||||
avModel.clearCurrentVideoCaptureDevice();
|
||||
avModel.switchInputTo({}, callId);
|
||||
avModel.stopPreview();
|
||||
} else if (deviceEvent == DeviceEvent::RemovedCurrent && currentDeviceListSize > 0) {
|
||||
avModel.setDefaultDevice(defaultDevice);
|
||||
avModel.setCurrentVideoCaptureDevice(defaultDevice);
|
||||
avModel.switchInputTo(defaultDevice, callId);
|
||||
}
|
||||
};
|
||||
|
||||
if (lrcInstance_->renderer()->isPreviewing()) {
|
||||
Utils::oneShotConnect(lrcInstance_->renderer(),
|
||||
&RenderManager::previewRenderingStopped,
|
||||
[cb] { QtConcurrent::run([cb]() { cb(); }); });
|
||||
} else {
|
||||
if (deviceEvent == DeviceEvent::Added && currentDeviceListSize == 1) {
|
||||
avModel.setDefaultDevice(defaultDevice);
|
||||
avModel.setCurrentVideoCaptureDevice(defaultDevice);
|
||||
if (callId.isEmpty()) {
|
||||
Q_EMIT videoDeviceAvailable();
|
||||
} else {
|
||||
avModel.switchInputTo(defaultDevice, callId);
|
||||
}
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
Q_EMIT videoDeviceListChanged(currentDeviceListSize);
|
||||
|
||||
deviceListSize_ = currentDeviceListSize;
|
||||
}
|
||||
|
||||
QString
|
||||
AvAdapter::getCurrentCallId()
|
||||
{
|
||||
try {
|
||||
const auto& convInfo = lrcInstance_->getConversationFromConvUid(
|
||||
lrcInstance_->get_selectedConvUid());
|
||||
auto call = lrcInstance_->getCallInfoForConversation(convInfo);
|
||||
return call ? call->id : QString();
|
||||
} catch (...) {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
AvAdapter::getScreenNumber() const
|
||||
{
|
||||
|
@ -349,30 +255,6 @@ AvAdapter::setDeviceName(const QString& deviceName)
|
|||
lrcInstance_->getCurrentAccountInfo().deviceModel->setCurrentDeviceName(deviceName);
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::setCurrentVideoDeviceRateAndResolution(qreal rate, const QString& resolution)
|
||||
{
|
||||
auto settings = lrcInstance_->avModel().getDeviceSettings(
|
||||
lrcInstance_->avModel().getCurrentVideoCaptureDevice());
|
||||
settings.rate = rate;
|
||||
settings.size = resolution;
|
||||
lrcInstance_->avModel().setDeviceSettings(settings);
|
||||
}
|
||||
|
||||
QString
|
||||
AvAdapter::getVideoSettingsSize(const QString& deviceId)
|
||||
{
|
||||
return lrcInstance_->avModel().getDeviceSettings(deviceId).size;
|
||||
}
|
||||
|
||||
int
|
||||
AvAdapter::getCurrentVideoDeviceCapabilitiesSize()
|
||||
{
|
||||
return lrcInstance_->avModel()
|
||||
.getDeviceCapabilities(lrcInstance_->avModel().getCurrentVideoCaptureDevice())
|
||||
.size();
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::enableCodec(unsigned int id, bool isToEnable)
|
||||
{
|
||||
|
@ -390,3 +272,34 @@ AvAdapter::decreaseCodecPriority(unsigned int id, bool isVideo)
|
|||
{
|
||||
lrcInstance_->getCurrentAccountInfo().codecModel->decreasePriority(id, isVideo);
|
||||
}
|
||||
|
||||
bool
|
||||
AvAdapter::getHardwareAcceleration()
|
||||
{
|
||||
return lrcInstance_->avModel().getHardwareAcceleration();
|
||||
}
|
||||
void
|
||||
AvAdapter::setHardwareAcceleration(bool accelerate)
|
||||
{
|
||||
lrcInstance_->avModel().setHardwareAcceleration(accelerate);
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::startPreviewing(bool force)
|
||||
{
|
||||
lrcInstance_->renderer()->startPreviewing(force);
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::stopPreviewing()
|
||||
{
|
||||
if (!lrcInstance_->hasActiveCall(true)) {
|
||||
lrcInstance_->renderer()->stopPreviewing();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AvAdapter::isPreviewing()
|
||||
{
|
||||
return lrcInstance_->renderer()->isPreviewing();
|
||||
}
|
|
@ -29,28 +29,20 @@
|
|||
class AvAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_PROPERTY(lrc::api::video::DeviceType, currentRenderingDeviceType)
|
||||
QML_RO_PROPERTY(lrc::api::video::DeviceType, currentRenderingDeviceType)
|
||||
|
||||
public:
|
||||
explicit AvAdapter(LRCInstance* instance, QObject* parent = nullptr);
|
||||
~AvAdapter() = default;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
void audioDeviceListChanged(int inputs, int outputs);
|
||||
void videoDeviceListChanged(int inputs);
|
||||
void screenCaptured(int screenNumber, QString source);
|
||||
void videoDeviceAvailable();
|
||||
// TODO: move to future audio device class
|
||||
void audioDeviceListChanged(int inputs, int outputs);
|
||||
|
||||
protected:
|
||||
void safeInit() override {};
|
||||
|
||||
// switch preview video input by device name
|
||||
Q_INVOKABLE void selectVideoInputDeviceByName(const QString& deviceName);
|
||||
|
||||
// switch preview video input by device id
|
||||
Q_INVOKABLE void selectVideoInputDeviceById(const QString& deviceId);
|
||||
|
||||
// Share the screen specificed by screen number.
|
||||
Q_INVOKABLE void shareEntireScreen(int screenNumber);
|
||||
|
||||
|
@ -76,31 +68,25 @@ protected:
|
|||
Q_INVOKABLE void stopAudioMeter();
|
||||
|
||||
Q_INVOKABLE void setDeviceName(const QString& deviceName);
|
||||
Q_INVOKABLE void setCurrentVideoDeviceRateAndResolution(qreal rate, const QString& resolution);
|
||||
Q_INVOKABLE QString getVideoSettingsSize(const QString& deviceId);
|
||||
Q_INVOKABLE int getCurrentVideoDeviceCapabilitiesSize();
|
||||
|
||||
Q_INVOKABLE void enableCodec(unsigned int id, bool isToEnable);
|
||||
Q_INVOKABLE void increaseCodecPriority(unsigned int id, bool isVideo);
|
||||
Q_INVOKABLE void decreaseCodecPriority(unsigned int id, bool isVideo);
|
||||
|
||||
// TODO: to be removed
|
||||
Q_INVOKABLE bool getHardwareAcceleration();
|
||||
Q_INVOKABLE void setHardwareAcceleration(bool accelerate);
|
||||
Q_INVOKABLE bool isPreviewing();
|
||||
Q_INVOKABLE void startPreviewing(bool force = false);
|
||||
Q_INVOKABLE void stopPreviewing();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onAudioDeviceEvent();
|
||||
void onVideoDeviceEvent();
|
||||
|
||||
private:
|
||||
// Get screens arrangement rect relative to primary screen.
|
||||
const QRect getAllScreensBoundingRect();
|
||||
|
||||
// Get current callId from current selected conv id.
|
||||
QString getCurrentCallId();
|
||||
|
||||
// Used to classify capture device events.
|
||||
enum class DeviceEvent { Added, RemovedCurrent, None };
|
||||
|
||||
// Used to track the capture device count.
|
||||
int deviceListSize_;
|
||||
|
||||
// Get the screen number
|
||||
int getScreenNumber() const;
|
||||
};
|
||||
|
|
|
@ -39,13 +39,13 @@ Item {
|
|||
height: boothLayout.height
|
||||
|
||||
function startBooth() {
|
||||
AccountAdapter.startPreviewing(false)
|
||||
AvAdapter.startPreviewing(false)
|
||||
isPreviewing = true
|
||||
}
|
||||
|
||||
function stopBooth(){
|
||||
if (!AccountAdapter.hasVideoCall()) {
|
||||
AccountAdapter.stopPreviewing()
|
||||
AvAdapter.stopPreviewing()
|
||||
}
|
||||
isPreviewing = false
|
||||
}
|
||||
|
@ -136,8 +136,6 @@ Item {
|
|||
anchors.margins: 1
|
||||
|
||||
visible: isPreviewing
|
||||
|
||||
onRenderingStopped: stopBooth()
|
||||
lrcInstance: LRCInstance
|
||||
|
||||
layer.enabled: true
|
||||
|
@ -148,6 +146,11 @@ Item {
|
|||
radius: avatarSize / 2
|
||||
}
|
||||
}
|
||||
|
||||
onRenderingStopped: {
|
||||
if (root.visible)
|
||||
stopBooth()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
|
@ -24,19 +24,23 @@ import net.jami.Constants 1.1
|
|||
ComboBox {
|
||||
id: root
|
||||
|
||||
property string tooltipText
|
||||
property string comboBoxBackgroundColor: JamiTheme.editBackgroundColor
|
||||
property alias tooltipText: toolTip.text
|
||||
property string placeholderText
|
||||
property string currentSelectionText: currentText
|
||||
property string comboBoxBackgroundColor: JamiTheme.editBackgroundColor
|
||||
|
||||
MaterialToolTip {
|
||||
id: toolTip
|
||||
|
||||
parent: root
|
||||
visible: hovered && (text.length > 0)
|
||||
delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
}
|
||||
|
||||
displayText: currentIndex !== -1 ?
|
||||
currentText :
|
||||
(placeholderText !== "" ?
|
||||
placeholderText :
|
||||
JamiStrings.notAvailable)
|
||||
|
||||
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
ToolTip.visible: hovered && (tooltipText.length > 0)
|
||||
ToolTip.text: tooltipText
|
||||
currentSelectionText : (placeholderText !== "" ?
|
||||
placeholderText :
|
||||
JamiStrings.notAvailable)
|
||||
|
||||
delegate: ItemDelegate {
|
||||
width: root.width
|
||||
|
@ -53,7 +57,6 @@ ComboBox {
|
|||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
highlighted: root.highlightedIndex === index
|
||||
background: Rectangle {
|
||||
color: highlighted? JamiTheme.selectedColor : JamiTheme.editBackgroundColor
|
||||
}
|
||||
|
@ -61,8 +64,10 @@ ComboBox {
|
|||
|
||||
indicator: Canvas {
|
||||
id: canvas
|
||||
|
||||
x: root.width - width - root.rightPadding
|
||||
y: root.topPadding + (root.availableHeight - height) / 2
|
||||
|
||||
width: 12
|
||||
height: 8
|
||||
contextType: "2d"
|
||||
|
@ -113,17 +118,17 @@ ComboBox {
|
|||
|
||||
contentItem: ListView {
|
||||
id: listView
|
||||
|
||||
clip: true
|
||||
implicitHeight: contentHeight
|
||||
model: root.delegateModel
|
||||
currentIndex: root.highlightedIndex
|
||||
|
||||
ScrollBar.vertical: ScrollBar { }
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: JamiTheme.editBackgroundColor
|
||||
border.color: "gray"
|
||||
border.color: JamiTheme.greyBorderColor
|
||||
radius: 2
|
||||
}
|
||||
}
|
||||
|
|
|
@ -417,3 +417,15 @@ LRCInstance::monitor(bool continuous)
|
|||
{
|
||||
lrc_->monitor(continuous);
|
||||
}
|
||||
|
||||
QString
|
||||
LRCInstance::getCurrentCallId()
|
||||
{
|
||||
try {
|
||||
const auto& convInfo = getConversationFromConvUid(get_selectedConvUid());
|
||||
auto call = getCallInfoForConversation(convInfo);
|
||||
return call ? call->id : QString();
|
||||
} catch (...) {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ public:
|
|||
|
||||
const account::Info& getAccountInfo(const QString& accountId);
|
||||
const account::Info& getCurrentAccountInfo();
|
||||
QString getCurrentCallId();
|
||||
QString getCallIdForConversationUid(const QString& convUid, const QString& accountId);
|
||||
const call::Info* getCallInfo(const QString& callId, const QString& accountId);
|
||||
const call::Info* getCallInfoForConversation(const conversation::Info& convInfo,
|
||||
|
|
|
@ -57,7 +57,6 @@ Rectangle {
|
|||
property string currentAccountId: LRCInstance.currentAccountId
|
||||
onCurrentAccountIdChanged: {
|
||||
if (inSettingsView) {
|
||||
settingsView.accountListChanged()
|
||||
settingsView.setSelected(settingsView.selectedMenu, true)
|
||||
} else {
|
||||
backToMainView(true)
|
||||
|
|
|
@ -70,11 +70,6 @@ Control {
|
|||
audioOutputDeviceListModel.reset();
|
||||
audioOutputMenuAction.enabled = outputs
|
||||
}
|
||||
|
||||
function onVideoDeviceListChanged(inputs) {
|
||||
videoInputDeviceListModel.reset();
|
||||
videoInputMenuAction.enabled = inputs
|
||||
}
|
||||
}
|
||||
|
||||
property list<Action> menuActions: [
|
||||
|
@ -144,34 +139,16 @@ Control {
|
|||
},
|
||||
Action {
|
||||
id: videoInputMenuAction
|
||||
enabled: VideoDevices.listSize !== 0
|
||||
text: JamiStrings.selectVideoDevice
|
||||
Component.onCompleted: enabled = videoInputDeviceListModel.rowCount()
|
||||
property var listModel: VideoInputDeviceModel {
|
||||
id: videoInputDeviceListModel
|
||||
lrcInstance: LRCInstance
|
||||
}
|
||||
property var listModel: VideoDevices.devicesSourceModel()
|
||||
function accept(index) {
|
||||
if (listModel.deviceCount() < 1)
|
||||
if (VideoDevices.listSize < 1)
|
||||
return
|
||||
try {
|
||||
var deviceId = listModel.data(
|
||||
listModel.index(index, 0),
|
||||
VideoInputDeviceModel.DeviceId)
|
||||
var deviceName = listModel.data(
|
||||
listModel.index(index, 0),
|
||||
VideoInputDeviceModel.DeviceName)
|
||||
if (deviceId.length === 0) {
|
||||
console.warn("Couldn't find device: " + deviceName)
|
||||
return
|
||||
}
|
||||
if (AVModel.getCurrentVideoCaptureDevice() !== deviceId) {
|
||||
AVModel.setCurrentVideoCaptureDevice(deviceId)
|
||||
AVModel.setDefaultDevice(deviceId)
|
||||
}
|
||||
AvAdapter.selectVideoInputDeviceById(deviceId)
|
||||
} catch (err) {
|
||||
console.warn(err.message)
|
||||
}
|
||||
// TODO: change it when we can suppot showing default and
|
||||
// current rendering device at the same time and
|
||||
// start and stop preview logic in here should be in LRC
|
||||
VideoDevices.setDefaultDevice(index, true)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -190,10 +190,11 @@ Rectangle {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: AvAdapter
|
||||
target: VideoDevices
|
||||
|
||||
function onVideoDeviceListChanged(inputs) {
|
||||
previewRenderer.visible = (inputs !== 0)
|
||||
// TODO: previewRenderer visible should be listening to a property
|
||||
function onDeviceListChanged() {
|
||||
previewRenderer.visible = VideoDevices.listSize !== 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ Rectangle {
|
|||
updateState(RecordBox.States.INIT)
|
||||
|
||||
if (isVideo) {
|
||||
AccountAdapter.startPreviewing(false)
|
||||
AvAdapter.startPreviewing(false)
|
||||
previewAvailable = true
|
||||
}
|
||||
}
|
||||
|
@ -67,10 +67,9 @@ Rectangle {
|
|||
function scaleHeight() {
|
||||
height = preferredHeight
|
||||
if (isVideo) {
|
||||
var device = AVModel.getDefaultDevice()
|
||||
var settings = AvAdapter.getVideoSettingsSize(device)
|
||||
var res = settings.split("x")
|
||||
var aspectRatio = res[1] / res[0]
|
||||
var resolution = VideoDevices.defaultRes
|
||||
var resVec = resolution.split("x")
|
||||
var aspectRatio = resVec[1] / resVec[0]
|
||||
if (aspectRatio) {
|
||||
height = preferredWidth * aspectRatio
|
||||
} else {
|
||||
|
@ -80,8 +79,8 @@ Rectangle {
|
|||
}
|
||||
|
||||
function closeRecorder() {
|
||||
if (isVideo && AccountAdapter.isPreviewing()) {
|
||||
AccountAdapter.stopPreviewing()
|
||||
if (isVideo && AvAdapter.isPreviewing()) {
|
||||
AvAdapter.stopPreviewing()
|
||||
}
|
||||
stopRecording()
|
||||
visible = false
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "conversationsadapter.h"
|
||||
#include "currentconversation.h"
|
||||
#include "currentaccount.h"
|
||||
#include "videodevices.h"
|
||||
|
||||
#include "accountlistmodel.h"
|
||||
#include "accountstomigratelistmodel.h"
|
||||
|
@ -52,9 +53,6 @@
|
|||
#include "pluginlistpreferencemodel.h"
|
||||
#include "previewrenderer.h"
|
||||
#include "version.h"
|
||||
#include "videoformatfpsmodel.h"
|
||||
#include "videoformatresolutionmodel.h"
|
||||
#include "videoinputdevicemodel.h"
|
||||
#include "wizardviewstepmodel.h"
|
||||
|
||||
#include "api/peerdiscoverymodel.h"
|
||||
|
@ -116,6 +114,7 @@ registerTypes(QQmlEngine* engine,
|
|||
auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
|
||||
auto currentConversation = new CurrentConversation(lrcInstance, parent);
|
||||
auto currentAccount = new CurrentAccount(lrcInstance, appSettingsManager, parent);
|
||||
auto videoDevices = new VideoDevices(lrcInstance, parent);
|
||||
|
||||
// qml adapter registration
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, callAdapter, "CallAdapter");
|
||||
|
@ -128,6 +127,7 @@ registerTypes(QQmlEngine* engine,
|
|||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, pluginAdapter, "PluginAdapter");
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentConversation, "CurrentConversation");
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, currentAccount, "CurrentAccount");
|
||||
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, videoDevices, "VideoDevices");
|
||||
|
||||
// TODO: remove these
|
||||
QML_REGISTERSINGLETONTYPE_CUSTOM(NS_MODELS, AVModel, &lrcInstance->avModel())
|
||||
|
@ -152,9 +152,6 @@ registerTypes(QQmlEngine* engine,
|
|||
QML_REGISTERTYPE(NS_MODELS, AccountsToMigrateListModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, AudioDeviceModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, AudioManagerListModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, VideoInputDeviceModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, VideoFormatResolutionModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, VideoFormatFpsModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, PluginListPreferenceModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, FilesToSendListModel);
|
||||
QML_REGISTERTYPE(NS_MODELS, SmartListModel);
|
||||
|
@ -216,6 +213,9 @@ registerTypes(QQmlEngine* engine,
|
|||
QML_REGISTERUNCREATABLE(NS_ENUMS, NetWorkManager)
|
||||
QML_REGISTERUNCREATABLE(NS_ENUMS, WizardViewStepModel)
|
||||
QML_REGISTERUNCREATABLE(NS_ENUMS, DeviceItemListModel)
|
||||
QML_REGISTERUNCREATABLE(NS_ENUMS, VideoInputDeviceModel)
|
||||
QML_REGISTERUNCREATABLE(NS_ENUMS, VideoFormatResolutionModel)
|
||||
QML_REGISTERUNCREATABLE(NS_ENUMS, VideoFormatFpsModel)
|
||||
|
||||
engine->addImageProvider(QLatin1String("qrImage"), new QrImageProvider(lrcInstance));
|
||||
engine->addImageProvider(QLatin1String("avatarImage"),
|
||||
|
|
|
@ -80,6 +80,29 @@ oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender,
|
|||
});
|
||||
}
|
||||
|
||||
template<typename Func1, typename Func2>
|
||||
void
|
||||
oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender,
|
||||
Func1 signal,
|
||||
QObject* context,
|
||||
Func2 slot,
|
||||
Qt::ConnectionType connectionType = Qt::ConnectionType::AutoConnection)
|
||||
{
|
||||
QMetaObject::Connection* const connection = new QMetaObject::Connection;
|
||||
*connection = QObject::connect(sender, signal, context, slot, connectionType);
|
||||
QMetaObject::Connection* const disconnectConnection = new QMetaObject::Connection;
|
||||
*disconnectConnection = QObject::connect(sender, signal, [connection, disconnectConnection] {
|
||||
if (connection) {
|
||||
QObject::disconnect(*connection);
|
||||
delete connection;
|
||||
}
|
||||
if (disconnectConnection) {
|
||||
QObject::disconnect(*disconnectConnection);
|
||||
delete disconnectConnection;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Func1, typename Func2, typename Func3>
|
||||
void
|
||||
oneShotConnect(const typename QtPrivate::FunctionPointer<Func1>::Object* sender,
|
||||
|
|
|
@ -234,10 +234,6 @@ RenderManager::isPreviewing()
|
|||
void
|
||||
RenderManager::stopPreviewing()
|
||||
{
|
||||
if (!previewFrameWrapper_->isRendering()) {
|
||||
return;
|
||||
}
|
||||
|
||||
previewFrameWrapper_->stopRendering();
|
||||
avModel_.stopPreview();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ Rectangle {
|
|||
if(visible){
|
||||
setSelected(selectedMenu,true)
|
||||
} else {
|
||||
AccountAdapter.stopPreviewing()
|
||||
AvAdapter.stopPreviewing()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,12 +50,10 @@ Rectangle {
|
|||
if(selectedMenu === sel && (!recovery)) { return }
|
||||
switch(sel) {
|
||||
case SettingsView.Account:
|
||||
AccountAdapter.stopPreviewing()
|
||||
selectedMenu = sel
|
||||
pageIdCurrentAccountSettings.updateAccountInfoDisplayed()
|
||||
break
|
||||
case SettingsView.General:
|
||||
AccountAdapter.stopPreviewing()
|
||||
selectedMenu = sel
|
||||
break
|
||||
case SettingsView.Media:
|
||||
|
@ -63,25 +61,15 @@ Rectangle {
|
|||
avSettings.populateAVSettings()
|
||||
break
|
||||
case SettingsView.Plugin:
|
||||
AccountAdapter.stopPreviewing()
|
||||
selectedMenu = sel
|
||||
pluginSettings.populatePluginSettings()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
id: accountListChangedConnection
|
||||
target: LRCInstance
|
||||
|
||||
function onAccountListChanged() {
|
||||
accountListChanged()
|
||||
}
|
||||
}
|
||||
|
||||
// slots
|
||||
function leaveSettingsSlot(showMainView) {
|
||||
AccountAdapter.stopPreviewing()
|
||||
AvAdapter.stopPreviewing()
|
||||
settingsViewRect.stopBooth()
|
||||
if (showMainView)
|
||||
settingsViewNeedToShowMainView()
|
||||
|
@ -89,16 +77,6 @@ Rectangle {
|
|||
settingsViewNeedToShowNewWizardWindow()
|
||||
}
|
||||
|
||||
function accountListChanged() {
|
||||
var accountList = AccountAdapter.model.getAccountList()
|
||||
if(accountList.length === 0)
|
||||
return
|
||||
var device = AVModel.getDefaultDevice()
|
||||
if(device.length === 0) {
|
||||
AVModel.setCurrentVideoCaptureDevice(device)
|
||||
}
|
||||
}
|
||||
|
||||
property int selectedMenu: SettingsView.Account
|
||||
// signal to redirect the page to main view
|
||||
signal settingsViewNeedToShowMainView()
|
||||
|
|
|
@ -267,8 +267,8 @@ ColumnLayout {
|
|||
|
||||
modelIndex: CurrentAccount.method_TLS
|
||||
|
||||
onModelIndexChanged: CurrentAccount.method_TLS =
|
||||
parseInt(comboModel.get(modelIndex).secondArg)
|
||||
onActivated: CurrentAccount.method_TLS =
|
||||
parseInt(comboModel.get(modelIndex).secondArg)
|
||||
}
|
||||
|
||||
SettingsMaterialLineEdit {
|
||||
|
|
|
@ -75,7 +75,7 @@ ColumnLayout {
|
|||
tipText: JamiStrings.selectAudioInputDevice
|
||||
role: "DeviceName"
|
||||
|
||||
onModelIndexChanged: {
|
||||
onActivated: {
|
||||
AvAdapter.stopAudioMeter()
|
||||
AVModel.setInputDevice(comboModel.data(
|
||||
comboModel.index(modelIndex, 0),
|
||||
|
@ -114,7 +114,7 @@ ColumnLayout {
|
|||
tipText: JamiStrings.selectAudioOutputDevice
|
||||
role: "DeviceName"
|
||||
|
||||
onModelIndexChanged: {
|
||||
onActivated: {
|
||||
AvAdapter.stopAudioMeter()
|
||||
AVModel.setOutputDevice(comboModel.data(
|
||||
comboModel.index(modelIndex, 0),
|
||||
|
@ -140,7 +140,7 @@ ColumnLayout {
|
|||
tipText: JamiStrings.selectRingtoneOutputDevice
|
||||
role: "DeviceName"
|
||||
|
||||
onModelIndexChanged: {
|
||||
onActivated: {
|
||||
AvAdapter.stopAudioMeter()
|
||||
AVModel.setRingtoneDevice(comboModel.data(
|
||||
comboModel.index(modelIndex, 0),
|
||||
|
@ -164,7 +164,7 @@ ColumnLayout {
|
|||
widthOfComboBox: itemWidth
|
||||
role: "ID_UTF8"
|
||||
|
||||
onModelIndexChanged: {
|
||||
onActivated: {
|
||||
AvAdapter.stopAudioMeter()
|
||||
var selectedAudioManager = comboModel.data(
|
||||
comboModel.index(modelIndex, 0), AudioManagerListModel.AudioManagerID)
|
||||
|
|
|
@ -34,20 +34,10 @@ Rectangle {
|
|||
|
||||
function populateAVSettings() {
|
||||
audioSettings.populateAudioSettings()
|
||||
videoSettings.populateVideoSettings()
|
||||
}
|
||||
|
||||
color: JamiTheme.secondaryBackgroundColor
|
||||
|
||||
Connections {
|
||||
target: AvAdapter
|
||||
|
||||
function onVideoDeviceAvailable() {
|
||||
if (root.visible)
|
||||
videoSettings.startPreviewing()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: avSettingsColumnLayout
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ RowLayout {
|
|||
property alias tipText: comboBoxOfLayout.tooltipText
|
||||
property alias role: comboBoxOfLayout.textRole
|
||||
property alias placeholderText: comboBoxOfLayout.placeholderText
|
||||
property alias currentSelectionText: comboBoxOfLayout.currentSelectionText
|
||||
property alias enabled: comboBoxOfLayout.enabled
|
||||
property alias fontPointSize: comboBoxOfLayout.font.pointSize
|
||||
property alias modelIndex: comboBoxOfLayout.currentIndex
|
||||
|
@ -38,6 +39,8 @@ RowLayout {
|
|||
property int heightOfLayout: 30
|
||||
property int widthOfComboBox: 50
|
||||
|
||||
signal activated
|
||||
|
||||
ElidedTextLabel {
|
||||
id: label
|
||||
|
||||
|
@ -62,5 +65,7 @@ RowLayout {
|
|||
|
||||
textRole: role
|
||||
tooltipText: tipText
|
||||
|
||||
onActivated: root.activated()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,79 +35,72 @@ ColumnLayout {
|
|||
property bool previewAvailable: false
|
||||
property int itemWidth
|
||||
|
||||
Connections {
|
||||
target: AvAdapter
|
||||
|
||||
function onVideoDeviceListChanged() {
|
||||
populateVideoSettings()
|
||||
}
|
||||
}
|
||||
|
||||
function startPreviewing(force = false) {
|
||||
if (root.visible) {
|
||||
AccountAdapter.startPreviewing(force)
|
||||
AvAdapter.startPreviewing(force)
|
||||
previewAvailable = true
|
||||
}
|
||||
}
|
||||
|
||||
function populateVideoSettings() {
|
||||
deviceComboBoxSetting.comboModel.reset()
|
||||
|
||||
var count = deviceComboBoxSetting.comboModel.deviceCount()
|
||||
|
||||
previewWidget.visible = count > 0
|
||||
deviceComboBoxSetting.enabled = count > 0
|
||||
resolutionComboBoxSetting.enabled = count > 0
|
||||
fpsComboBoxSetting.enabled = count > 0
|
||||
|
||||
if (count === 0) {
|
||||
resolutionComboBoxSetting.reset()
|
||||
fpsComboBoxSetting.reset()
|
||||
} else {
|
||||
deviceComboBoxSetting.modelIndex =
|
||||
deviceComboBoxSetting.comboModel.getCurrentIndex()
|
||||
}
|
||||
hardwareAccelControl.checked = AVModel.getHardwareAcceleration()
|
||||
}
|
||||
|
||||
function slotDeviceBoxCurrentIndexChanged(index) {
|
||||
if (deviceComboBoxSetting.comboModel.deviceCount() <= 0)
|
||||
return
|
||||
|
||||
try {
|
||||
var deviceId = deviceComboBoxSetting.comboModel.data(
|
||||
deviceComboBoxSetting.comboModel.index(index, 0),
|
||||
VideoInputDeviceModel.DeviceId)
|
||||
var deviceName = deviceComboBoxSetting.comboModel.data(
|
||||
deviceComboBoxSetting.comboModel.index(index, 0),
|
||||
VideoInputDeviceModel.DeviceName)
|
||||
if(deviceId.length === 0) {
|
||||
console.warn("Couldn't find device: " + deviceName)
|
||||
return
|
||||
function updatePreviewRatio() {
|
||||
var resolution = VideoDevices.defaultRes
|
||||
if (resolution.length !== 0) {
|
||||
var resVec = resolution.split("x")
|
||||
var ratio = resVec[1] / resVec[0]
|
||||
if (ratio) {
|
||||
aspectRatio = ratio
|
||||
} else {
|
||||
console.error("Could not scale recording video preview")
|
||||
}
|
||||
|
||||
if (AVModel.getCurrentVideoCaptureDevice() !== deviceId) {
|
||||
AVModel.setCurrentVideoCaptureDevice(deviceId)
|
||||
AVModel.setDefaultDevice(deviceId)
|
||||
}
|
||||
|
||||
resolutionComboBoxSetting.reset()
|
||||
} catch(err){ console.warn(err.message) }
|
||||
}
|
||||
|
||||
function updatePreviewRatio(resolution) {
|
||||
var res = resolution.split("x")
|
||||
var ratio = res[1] / res[0]
|
||||
if (ratio) {
|
||||
aspectRatio = ratio
|
||||
} else {
|
||||
console.error("Could not scale recording video preview")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible)
|
||||
startPreviewing(true)
|
||||
if (visible) {
|
||||
hardwareAccelControl.checked = AvAdapter.getHardwareAcceleration()
|
||||
updatePreviewRatio()
|
||||
if (previewWidget.visible)
|
||||
startPreviewing(true)
|
||||
} else {
|
||||
AvAdapter.stopPreviewing()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: VideoDevices
|
||||
|
||||
function onDefaultResChanged() {
|
||||
updatePreviewRatio()
|
||||
}
|
||||
|
||||
function onDeviceAvailable() {
|
||||
startPreviewing()
|
||||
}
|
||||
|
||||
function onDeviceListChanged() {
|
||||
var deviceModel = deviceComboBoxSetting.comboModel
|
||||
var resModel = resolutionComboBoxSetting.comboModel
|
||||
var fpsModel = fpsComboBoxSetting.comboModel
|
||||
|
||||
var resultList = deviceModel.match(deviceModel.index(0, 0),
|
||||
VideoInputDeviceModel.DeviceId,
|
||||
VideoDevices.defaultId)
|
||||
deviceComboBoxSetting.modelIndex = resultList.length > 0 ?
|
||||
resultList[0].row : deviceModel.rowCount() ? 0 : -1
|
||||
|
||||
resultList = resModel.match(resModel.index(0, 0),
|
||||
VideoFormatResolutionModel.Resolution,
|
||||
VideoDevices.defaultRes)
|
||||
resolutionComboBoxSetting.modelIndex = resultList.length > 0 ?
|
||||
resultList[0].row : deviceModel.rowCount() ? 0 : -1
|
||||
|
||||
resultList = fpsModel.match(fpsModel.index(0, 0),
|
||||
VideoFormatFpsModel.FPS,
|
||||
VideoDevices.defaultFps)
|
||||
fpsComboBoxSetting.modelIndex = resultList.length > 0 ?
|
||||
resultList[0].row : deviceModel.rowCount() ? 0 : -1
|
||||
}
|
||||
}
|
||||
|
||||
ElidedTextLabel {
|
||||
|
@ -126,98 +119,66 @@ ColumnLayout {
|
|||
Layout.preferredHeight: JamiTheme.preferredFieldHeight
|
||||
Layout.leftMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
labelText: JamiStrings.device
|
||||
enabled: VideoDevices.listSize !== 0
|
||||
|
||||
fontPointSize: JamiTheme.settingsFontSize
|
||||
comboModel: VideoInputDeviceModel {
|
||||
lrcInstance: LRCInstance
|
||||
}
|
||||
widthOfComboBox: itemWidth
|
||||
|
||||
labelText: JamiStrings.device
|
||||
tipText: JamiStrings.selectVideoDevice
|
||||
role: "DeviceName_UTF8"
|
||||
|
||||
onModelIndexChanged: slotDeviceBoxCurrentIndexChanged(modelIndex)
|
||||
|
||||
placeholderText: JamiStrings.noVideoDevice
|
||||
currentSelectionText: VideoDevices.defaultName
|
||||
comboModel: VideoDevices.devicesFilterModel()
|
||||
role: "DeviceName"
|
||||
|
||||
onActivated: {
|
||||
// TODO: start and stop preview logic in here should be in LRC
|
||||
AvAdapter.stopPreviewing()
|
||||
VideoDevices.setDefaultDevice(modelIndex)
|
||||
startPreviewing()
|
||||
}
|
||||
}
|
||||
|
||||
SettingsComboBox {
|
||||
id: resolutionComboBoxSetting
|
||||
|
||||
function reset() {
|
||||
modelIndex = -1
|
||||
comboModel.reset()
|
||||
modelIndex = 0
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: JamiTheme.preferredFieldHeight
|
||||
Layout.leftMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
labelText: JamiStrings.resolution
|
||||
fontPointSize: JamiTheme.settingsFontSize
|
||||
comboModel: VideoFormatResolutionModel {
|
||||
lrcInstance: LRCInstance
|
||||
}
|
||||
enabled: VideoDevices.listSize !== 0
|
||||
|
||||
widthOfComboBox: itemWidth
|
||||
fontPointSize: JamiTheme.settingsFontSize
|
||||
|
||||
labelText: JamiStrings.resolution
|
||||
currentSelectionText: VideoDevices.defaultRes
|
||||
tipText: JamiStrings.selectVideoResolution
|
||||
role: "Resolution_UTF8"
|
||||
comboModel: VideoDevices.resFilterModel()
|
||||
role: "Resolution"
|
||||
|
||||
modelIndex: -1
|
||||
|
||||
onModelIndexChanged: {
|
||||
if (modelIndex === -1)
|
||||
return
|
||||
var resolution = comboModel.data(comboModel.index(modelIndex, 0),
|
||||
VideoFormatResolutionModel.Resolution)
|
||||
fpsComboBoxSetting.comboModel.currentResolution = resolution
|
||||
fpsComboBoxSetting.modelIndex = 0
|
||||
|
||||
var rate = fpsComboBoxSetting.comboModel.data(
|
||||
fpsComboBoxSetting.comboModel.index(0, 0),
|
||||
VideoFormatFpsModel.FPS)
|
||||
|
||||
AvAdapter.setCurrentVideoDeviceRateAndResolution(rate, resolution)
|
||||
updatePreviewRatio(resolution)
|
||||
}
|
||||
onActivated: VideoDevices.setDefaultDeviceRes(modelIndex)
|
||||
}
|
||||
|
||||
SettingsComboBox {
|
||||
id: fpsComboBoxSetting
|
||||
|
||||
function reset() {
|
||||
modelIndex = -1
|
||||
comboModel.reset()
|
||||
modelIndex = 0
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: JamiTheme.preferredFieldHeight
|
||||
Layout.leftMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
labelText: JamiStrings.fps
|
||||
fontPointSize: JamiTheme.settingsFontSize
|
||||
comboModel: VideoFormatFpsModel {
|
||||
lrcInstance: LRCInstance
|
||||
}
|
||||
enabled: VideoDevices.listSize !== 0
|
||||
|
||||
widthOfComboBox: itemWidth
|
||||
fontPointSize: JamiTheme.settingsFontSize
|
||||
|
||||
tipText: JamiStrings.selectFPS
|
||||
role: "FPS_ToDisplay_UTF8"
|
||||
labelText: JamiStrings.fps
|
||||
currentSelectionText: VideoDevices.defaultFps.toString()
|
||||
comboModel: VideoDevices.fpsFilterModel()
|
||||
role: "FPS"
|
||||
|
||||
modelIndex: -1
|
||||
|
||||
onModelIndexChanged: {
|
||||
if (modelIndex === -1)
|
||||
return
|
||||
var resolution = resolutionComboBoxSetting.comboModel.data(
|
||||
resolutionComboBoxSetting.comboModel.index(
|
||||
resolutionComboBoxSetting.modelIndex, 0),
|
||||
VideoFormatResolutionModel.Resolution)
|
||||
|
||||
var rate = comboModel.data(comboModel.index(modelIndex, 0),
|
||||
VideoFormatFpsModel.FPS)
|
||||
|
||||
AvAdapter.setCurrentVideoDeviceRateAndResolution(rate, resolution)
|
||||
}
|
||||
onActivated: VideoDevices.setDefaultDeviceFps(modelIndex)
|
||||
}
|
||||
|
||||
ToggleSwitch {
|
||||
|
@ -230,7 +191,7 @@ ColumnLayout {
|
|||
fontPointSize: JamiTheme.settingsFontSize
|
||||
|
||||
onSwitchToggled: {
|
||||
AVModel.setHardwareAcceleration(checked)
|
||||
AvAdapter.setHardwareAcceleration(checked)
|
||||
startPreviewing(true)
|
||||
}
|
||||
}
|
||||
|
@ -247,8 +208,7 @@ ColumnLayout {
|
|||
Layout.preferredWidth: itemWidth * 2
|
||||
Layout.bottomMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
color: "white"
|
||||
radius: 5
|
||||
color: JamiTheme.primaryForegroundColor
|
||||
|
||||
PreviewRenderer {
|
||||
id: previewWidget
|
||||
|
@ -257,6 +217,7 @@ ColumnLayout {
|
|||
|
||||
lrcInstance: LRCInstance
|
||||
|
||||
visible: VideoDevices.listSize !== 0
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: rectBox
|
||||
|
@ -265,6 +226,7 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
Label {
|
||||
// TODO: proper use of previewAvailable
|
||||
visible: !previewAvailable
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
|
443
src/videodevices.cpp
Normal file
443
src/videodevices.cpp
Normal file
|
@ -0,0 +1,443 @@
|
|||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "videodevices.h"
|
||||
|
||||
// VideoInputDeviceModel
|
||||
VideoInputDeviceModel::VideoInputDeviceModel(LRCInstance* lrcInstance,
|
||||
VideoDevices* videoDeviceInstance)
|
||||
: QAbstractListModel(videoDeviceInstance)
|
||||
, lrcInstance_(lrcInstance)
|
||||
, videoDevices_(videoDeviceInstance)
|
||||
{}
|
||||
|
||||
VideoInputDeviceModel::~VideoInputDeviceModel() {}
|
||||
|
||||
int
|
||||
VideoInputDeviceModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid() && lrcInstance_) {
|
||||
return videoDevices_->get_listSize();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoInputDeviceModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
auto deviceList = lrcInstance_->avModel().getDevices();
|
||||
if (!index.isValid() || deviceList.size() == 0 || index.row() >= deviceList.size()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
auto currentDeviceSetting = lrcInstance_->avModel().getDeviceSettings(deviceList[index.row()]);
|
||||
|
||||
switch (role) {
|
||||
case Role::DeviceName:
|
||||
return QVariant(currentDeviceSetting.name);
|
||||
case Role::DeviceId:
|
||||
return QVariant(currentDeviceSetting.id);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
VideoInputDeviceModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[DeviceName] = "DeviceName";
|
||||
roles[DeviceId] = "DeviceId";
|
||||
return roles;
|
||||
}
|
||||
|
||||
int
|
||||
VideoInputDeviceModel::getCurrentIndex() const
|
||||
{
|
||||
QString currentId = videoDevices_->get_defaultId();
|
||||
auto resultList = match(index(0, 0), DeviceId, QVariant(currentId));
|
||||
return resultList.size() > 0 ? resultList[0].row() : 0;
|
||||
}
|
||||
|
||||
// VideoFormatResolutionModel
|
||||
VideoFormatResolutionModel::VideoFormatResolutionModel(LRCInstance* lrcInstance,
|
||||
VideoDevices* videoDeviceInstance)
|
||||
: QAbstractListModel(videoDeviceInstance)
|
||||
, lrcInstance_(lrcInstance)
|
||||
, videoDevices_(videoDeviceInstance)
|
||||
{}
|
||||
|
||||
VideoFormatResolutionModel::~VideoFormatResolutionModel() {}
|
||||
|
||||
int
|
||||
VideoFormatResolutionModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid() && lrcInstance_) {
|
||||
return videoDevices_->get_defaultResRateList().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoFormatResolutionModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
auto& channelCaps = videoDevices_->get_defaultResRateList();
|
||||
if (!index.isValid() || channelCaps.size() <= index.row() || channelCaps.size() == 0) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Role::Resolution:
|
||||
return QVariant(channelCaps.at(index.row()).first);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
VideoFormatResolutionModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Resolution] = "Resolution";
|
||||
return roles;
|
||||
}
|
||||
|
||||
int
|
||||
VideoFormatResolutionModel::getCurrentIndex() const
|
||||
{
|
||||
QString currentDeviceId = videoDevices_->get_defaultId();
|
||||
QString currentResolution = videoDevices_->get_defaultRes();
|
||||
auto resultList = match(index(0, 0), Resolution, QVariant(currentResolution));
|
||||
|
||||
return resultList.size() > 0 ? resultList[0].row() : 0;
|
||||
}
|
||||
|
||||
// VideoFormatFpsModel
|
||||
VideoFormatFpsModel::VideoFormatFpsModel(LRCInstance* lrcInstance, VideoDevices* videoDeviceInstance)
|
||||
: QAbstractListModel(videoDeviceInstance)
|
||||
, lrcInstance_(lrcInstance)
|
||||
, videoDevices_(videoDeviceInstance)
|
||||
{}
|
||||
|
||||
VideoFormatFpsModel::~VideoFormatFpsModel() {}
|
||||
|
||||
int
|
||||
VideoFormatFpsModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid() && lrcInstance_) {
|
||||
return videoDevices_->get_defaultFpsList().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoFormatFpsModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
auto& fpsList = videoDevices_->get_defaultFpsList();
|
||||
if (!index.isValid() || fpsList.size() == 0 || index.row() >= fpsList.size()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Role::FPS:
|
||||
return QVariant(static_cast<int>(fpsList[index.row()]));
|
||||
case Role::FPS_Float:
|
||||
return QVariant(fpsList[index.row()]);
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
VideoFormatFpsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[FPS] = "FPS";
|
||||
roles[FPS_Float] = "FPS_Float";
|
||||
return roles;
|
||||
}
|
||||
|
||||
int
|
||||
VideoFormatFpsModel::getCurrentIndex() const
|
||||
{
|
||||
QString currentDeviceId = videoDevices_->get_defaultId();
|
||||
float currentFps = videoDevices_->get_defaultFps();
|
||||
auto resultList = match(index(0, 0), FPS, QVariant(currentFps));
|
||||
|
||||
return resultList.size() > 0 ? resultList[0].row() : 0;
|
||||
}
|
||||
|
||||
// VideoDevices
|
||||
VideoDevices::VideoDevices(LRCInstance* lrcInstance, QObject* parent)
|
||||
: QObject(parent)
|
||||
, lrcInstance_(lrcInstance)
|
||||
, devicesFilterModel_(new CurrentItemFilterModel(this))
|
||||
, resFilterModel_(new CurrentItemFilterModel(this))
|
||||
, fpsFilterModel_(new CurrentItemFilterModel(this))
|
||||
{
|
||||
devicesSourceModel_ = new VideoInputDeviceModel(lrcInstance, this);
|
||||
resSourceModel_ = new VideoFormatResolutionModel(lrcInstance, this);
|
||||
fpsSourceModel_ = new VideoFormatFpsModel(lrcInstance, this);
|
||||
|
||||
devicesFilterModel_->setSourceModel(devicesSourceModel_);
|
||||
resFilterModel_->setSourceModel(resSourceModel_);
|
||||
fpsFilterModel_->setSourceModel(fpsSourceModel_);
|
||||
|
||||
devicesFilterModel_->setFilterRole(VideoInputDeviceModel::DeviceName);
|
||||
resFilterModel_->setFilterRole(VideoFormatResolutionModel::Resolution);
|
||||
fpsFilterModel_->setFilterRole(VideoFormatFpsModel::FPS);
|
||||
|
||||
connect(&lrcInstance_->avModel(),
|
||||
&lrc::api::AVModel::deviceEvent,
|
||||
this,
|
||||
&VideoDevices::onVideoDeviceEvent);
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
VideoDevices::~VideoDevices() {}
|
||||
|
||||
QVariant
|
||||
VideoDevices::devicesFilterModel()
|
||||
{
|
||||
return QVariant::fromValue(devicesFilterModel_);
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoDevices::devicesSourceModel()
|
||||
{
|
||||
return QVariant::fromValue(devicesSourceModel_);
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoDevices::resFilterModel()
|
||||
{
|
||||
return QVariant::fromValue(resFilterModel_);
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoDevices::resSourceModel()
|
||||
{
|
||||
return QVariant::fromValue(resSourceModel_);
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoDevices::fpsFilterModel()
|
||||
{
|
||||
return QVariant::fromValue(fpsFilterModel_);
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoDevices::fpsSourceModel()
|
||||
{
|
||||
return QVariant::fromValue(fpsSourceModel_);
|
||||
}
|
||||
|
||||
void
|
||||
VideoDevices::setDefaultDevice(int index, bool useSourceModel)
|
||||
{
|
||||
QString deviceId {};
|
||||
auto callId = lrcInstance_->getCurrentCallId();
|
||||
|
||||
if (useSourceModel)
|
||||
deviceId = devicesSourceModel_
|
||||
->data(devicesSourceModel_->index(index, 0), VideoInputDeviceModel::DeviceId)
|
||||
.toString();
|
||||
else
|
||||
deviceId = devicesFilterModel_
|
||||
->data(devicesFilterModel_->index(index, 0), VideoInputDeviceModel::DeviceId)
|
||||
.toString();
|
||||
|
||||
lrcInstance_->avModel().setDefaultDevice(deviceId);
|
||||
|
||||
if (!callId.isEmpty())
|
||||
lrcInstance_->avModel().switchInputTo(deviceId, callId);
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void
|
||||
VideoDevices::setDefaultDeviceRes(int index)
|
||||
{
|
||||
auto& channelCaps = get_defaultResRateList();
|
||||
auto settings = lrcInstance_->avModel().getDeviceSettings(get_defaultId());
|
||||
settings.size = resFilterModel_
|
||||
->data(resFilterModel_->index(index, 0),
|
||||
VideoFormatResolutionModel::Resolution)
|
||||
.toString();
|
||||
|
||||
for (int i = 0; i < channelCaps.size(); i++) {
|
||||
if (channelCaps[i].first == settings.size) {
|
||||
settings.rate = channelCaps[i].second.at(0);
|
||||
lrcInstance_->avModel().setDeviceSettings(settings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void
|
||||
VideoDevices::setDefaultDeviceFps(int index)
|
||||
{
|
||||
auto settings = lrcInstance_->avModel().getDeviceSettings(get_defaultId());
|
||||
settings.size = get_defaultRes();
|
||||
settings.rate = fpsFilterModel_
|
||||
->data(fpsFilterModel_->index(index, 0), VideoFormatFpsModel::FPS_Float)
|
||||
.toFloat();
|
||||
|
||||
lrcInstance_->avModel().setDeviceSettings(settings);
|
||||
|
||||
updateData();
|
||||
}
|
||||
|
||||
void
|
||||
VideoDevices::updateData()
|
||||
{
|
||||
set_listSize(lrcInstance_->avModel().getDevices().size());
|
||||
|
||||
if (get_listSize() != 0) {
|
||||
auto defaultDevice = lrcInstance_->avModel().getDefaultDevice();
|
||||
auto defaultDeviceSettings = lrcInstance_->avModel().getDeviceSettings(defaultDevice);
|
||||
auto defaultDeviceCap = lrcInstance_->avModel().getDeviceCapabilities(defaultDevice);
|
||||
auto currentResRateList = defaultDeviceCap[defaultDeviceSettings.channel.isEmpty()
|
||||
? "default"
|
||||
: defaultDeviceSettings.channel];
|
||||
lrc::api::video::FrameratesList fpsList;
|
||||
|
||||
for (int i = 0; i < currentResRateList.size(); i++) {
|
||||
if (currentResRateList[i].first == defaultDeviceSettings.size) {
|
||||
fpsList = currentResRateList[i].second;
|
||||
}
|
||||
}
|
||||
|
||||
set_defaultChannel(defaultDeviceSettings.channel);
|
||||
set_defaultId(defaultDeviceSettings.id);
|
||||
set_defaultName(defaultDeviceSettings.name);
|
||||
set_defaultRes(defaultDeviceSettings.size);
|
||||
set_defaultFps(defaultDeviceSettings.rate);
|
||||
set_defaultResRateList(currentResRateList);
|
||||
set_defaultFpsList(fpsList);
|
||||
|
||||
devicesFilterModel_->setCurrentItemFilter(defaultDeviceSettings.name);
|
||||
resFilterModel_->setCurrentItemFilter(defaultDeviceSettings.size);
|
||||
fpsFilterModel_->setCurrentItemFilter(static_cast<int>(defaultDeviceSettings.rate));
|
||||
} else {
|
||||
set_defaultChannel("");
|
||||
set_defaultId("");
|
||||
set_defaultName("");
|
||||
set_defaultRes("");
|
||||
set_defaultFps(0);
|
||||
set_defaultResRateList({});
|
||||
set_defaultFpsList({});
|
||||
|
||||
devicesFilterModel_->setCurrentItemFilter("");
|
||||
resFilterModel_->setCurrentItemFilter("");
|
||||
fpsFilterModel_->setCurrentItemFilter(0);
|
||||
}
|
||||
|
||||
devicesSourceModel_->reset();
|
||||
resSourceModel_->reset();
|
||||
fpsSourceModel_->reset();
|
||||
}
|
||||
|
||||
void
|
||||
VideoDevices::onVideoDeviceEvent()
|
||||
{
|
||||
auto& avModel = lrcInstance_->avModel();
|
||||
auto defaultDevice = avModel.getDefaultDevice();
|
||||
QString callId = lrcInstance_->getCurrentCallId();
|
||||
|
||||
// Decide whether a device has plugged, unplugged, or nothing has changed.
|
||||
auto deviceList = avModel.getDevices();
|
||||
auto currentDeviceListSize = deviceList.size();
|
||||
auto previousDeviceListSize = get_listSize();
|
||||
|
||||
DeviceEvent deviceEvent {DeviceEvent::None};
|
||||
if (currentDeviceListSize > previousDeviceListSize) {
|
||||
if (previousDeviceListSize == 0)
|
||||
deviceEvent = DeviceEvent::FirstDevice;
|
||||
else
|
||||
deviceEvent = DeviceEvent::Added;
|
||||
} else if (currentDeviceListSize < previousDeviceListSize) {
|
||||
deviceEvent = DeviceEvent::Removed;
|
||||
}
|
||||
|
||||
auto cb = [this, currentDeviceListSize, deviceEvent, defaultDevice, callId] {
|
||||
auto& avModel = lrcInstance_->avModel();
|
||||
if (currentDeviceListSize == 0) {
|
||||
avModel.switchInputTo({}, callId);
|
||||
avModel.stopPreview();
|
||||
} else if (deviceEvent == DeviceEvent::Removed) {
|
||||
avModel.switchInputTo(defaultDevice, callId);
|
||||
}
|
||||
|
||||
updateData();
|
||||
Q_EMIT deviceListChanged(currentDeviceListSize);
|
||||
};
|
||||
|
||||
if (deviceEvent == DeviceEvent::Added) {
|
||||
updateData();
|
||||
Q_EMIT deviceListChanged(currentDeviceListSize);
|
||||
} else if (deviceEvent == DeviceEvent::FirstDevice) {
|
||||
updateData();
|
||||
|
||||
if (callId.isEmpty()) {
|
||||
Q_EMIT deviceAvailable();
|
||||
} else {
|
||||
avModel.switchInputTo(defaultDevice, callId);
|
||||
}
|
||||
|
||||
Q_EMIT deviceListChanged(currentDeviceListSize);
|
||||
} else if (lrcInstance_->renderer()->isPreviewing()) {
|
||||
updateData();
|
||||
|
||||
// Use QueuedConnection to make sure that it happens at the event loop of current device
|
||||
Utils::oneShotConnect(
|
||||
lrcInstance_->renderer(),
|
||||
&RenderManager::previewRenderingStopped,
|
||||
this,
|
||||
[cb] { cb(); },
|
||||
Qt::QueuedConnection);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
const lrc::api::video::ResRateList&
|
||||
VideoDevices::get_defaultResRateList()
|
||||
{
|
||||
return defaultResRateList_;
|
||||
}
|
||||
|
||||
void
|
||||
VideoDevices::set_defaultResRateList(lrc::api::video::ResRateList resRateList)
|
||||
{
|
||||
defaultResRateList_.swap(resRateList);
|
||||
}
|
||||
|
||||
const lrc::api::video::FrameratesList&
|
||||
VideoDevices::get_defaultFpsList()
|
||||
{
|
||||
return defaultFpsList_;
|
||||
}
|
||||
|
||||
void
|
||||
VideoDevices::set_defaultFpsList(lrc::api::video::FrameratesList rateList)
|
||||
{
|
||||
defaultFpsList_.swap(rateList);
|
||||
}
|
205
src/videodevices.h
Normal file
205
src/videodevices.h
Normal file
|
@ -0,0 +1,205 @@
|
|||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lrcinstance.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
#include "api/newdevicemodel.h"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QObject>
|
||||
|
||||
class VideoDevices;
|
||||
|
||||
class CurrentItemFilterModel final : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CurrentItemFilterModel(QObject* parent = nullptr)
|
||||
: QSortFilterProxyModel(parent)
|
||||
|
||||
{}
|
||||
|
||||
void setCurrentItemFilter(const QVariant& filter)
|
||||
{
|
||||
currentItemFilter_ = filter;
|
||||
}
|
||||
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override
|
||||
{
|
||||
// Do not filter if there is only one item.
|
||||
if (currentItemFilter_.isNull() || sourceModel()->rowCount() == 1)
|
||||
return true;
|
||||
|
||||
// Exclude current item filter.
|
||||
auto index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
return index.data(filterRole()) != currentItemFilter_ && !index.parent().isValid();
|
||||
}
|
||||
|
||||
private:
|
||||
QVariant currentItemFilter_ {};
|
||||
};
|
||||
|
||||
class VideoInputDeviceModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Role { DeviceName = Qt::UserRole + 1, DeviceId };
|
||||
Q_ENUM(Role)
|
||||
|
||||
explicit VideoInputDeviceModel(LRCInstance* lrcInstance, VideoDevices* videoDeviceInstance);
|
||||
~VideoInputDeviceModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void reset()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
// Get model index of the current device
|
||||
Q_INVOKABLE int getCurrentIndex() const;
|
||||
|
||||
private:
|
||||
LRCInstance* lrcInstance_ {nullptr};
|
||||
VideoDevices* const videoDevices_;
|
||||
};
|
||||
|
||||
class VideoFormatResolutionModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Role { Resolution = Qt::UserRole + 1 };
|
||||
Q_ENUM(Role)
|
||||
|
||||
explicit VideoFormatResolutionModel(LRCInstance* lrcInstance, VideoDevices* videoDeviceInstance);
|
||||
~VideoFormatResolutionModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void reset()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
// Get model index of the current device
|
||||
Q_INVOKABLE int getCurrentIndex() const;
|
||||
|
||||
private:
|
||||
LRCInstance* lrcInstance_ {nullptr};
|
||||
VideoDevices* const videoDevices_;
|
||||
};
|
||||
|
||||
class VideoFormatFpsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Role { FPS = Qt::UserRole + 1, FPS_Float };
|
||||
Q_ENUM(Role)
|
||||
|
||||
explicit VideoFormatFpsModel(LRCInstance* lrcInstance, VideoDevices* videoDeviceInstance);
|
||||
~VideoFormatFpsModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void reset()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
// Get model index of the current device
|
||||
Q_INVOKABLE int getCurrentIndex() const;
|
||||
|
||||
private:
|
||||
LRCInstance* lrcInstance_;
|
||||
VideoDevices* const videoDevices_;
|
||||
};
|
||||
|
||||
class VideoDevices : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_RO_PROPERTY(int, listSize)
|
||||
|
||||
QML_RO_PROPERTY(QString, defaultChannel)
|
||||
QML_RO_PROPERTY(QString, defaultId)
|
||||
QML_RO_PROPERTY(QString, defaultName)
|
||||
QML_RO_PROPERTY(QString, defaultRes)
|
||||
QML_RO_PROPERTY(int, defaultFps)
|
||||
|
||||
public:
|
||||
explicit VideoDevices(LRCInstance* lrcInstance, QObject* parent = nullptr);
|
||||
~VideoDevices();
|
||||
|
||||
Q_INVOKABLE QVariant devicesFilterModel();
|
||||
Q_INVOKABLE QVariant devicesSourceModel();
|
||||
|
||||
Q_INVOKABLE QVariant resFilterModel();
|
||||
Q_INVOKABLE QVariant resSourceModel();
|
||||
|
||||
Q_INVOKABLE QVariant fpsFilterModel();
|
||||
Q_INVOKABLE QVariant fpsSourceModel();
|
||||
|
||||
Q_INVOKABLE void setDefaultDevice(int index, bool useSourceModel = false);
|
||||
Q_INVOKABLE void setDefaultDeviceRes(int index);
|
||||
Q_INVOKABLE void setDefaultDeviceFps(int index);
|
||||
|
||||
const lrc::api::video::ResRateList& get_defaultResRateList();
|
||||
void set_defaultResRateList(lrc::api::video::ResRateList resRateList);
|
||||
|
||||
const lrc::api::video::FrameratesList& get_defaultFpsList();
|
||||
void set_defaultFpsList(lrc::api::video::FrameratesList rateList);
|
||||
|
||||
Q_SIGNALS:
|
||||
void deviceAvailable();
|
||||
void deviceListChanged(int inputs);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onVideoDeviceEvent();
|
||||
|
||||
private:
|
||||
// Used to classify capture device events.
|
||||
enum class DeviceEvent { FirstDevice, Added, Removed, None };
|
||||
|
||||
void updateData();
|
||||
|
||||
LRCInstance* lrcInstance_;
|
||||
|
||||
CurrentItemFilterModel* devicesFilterModel_;
|
||||
CurrentItemFilterModel* resFilterModel_;
|
||||
CurrentItemFilterModel* fpsFilterModel_;
|
||||
|
||||
VideoInputDeviceModel* devicesSourceModel_;
|
||||
VideoFormatResolutionModel* resSourceModel_;
|
||||
VideoFormatFpsModel* fpsSourceModel_;
|
||||
|
||||
lrc::api::video::ResRateList defaultResRateList_;
|
||||
lrc::api::video::FrameratesList defaultFpsList_;
|
||||
};
|
|
@ -1,226 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019-2020 by Savoir-faire Linux
|
||||
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "videoformatfpsmodel.h"
|
||||
|
||||
#include "lrcinstance.h"
|
||||
|
||||
#include "api/account.h"
|
||||
#include "api/contact.h"
|
||||
#include "api/conversation.h"
|
||||
#include "api/newdevicemodel.h"
|
||||
|
||||
VideoFormatFpsModel::VideoFormatFpsModel(QObject* parent)
|
||||
: AbstractListModelBase(parent)
|
||||
{
|
||||
connect(this, &AbstractListModelBase::lrcInstanceChanged, [this] {
|
||||
if (lrcInstance_)
|
||||
try {
|
||||
QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
|
||||
currentResolution_ = currentSettings.size;
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << "Constructor of VideoFormatFpsModel, exception: " << e.what();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
VideoFormatFpsModel::~VideoFormatFpsModel() {}
|
||||
|
||||
int
|
||||
VideoFormatFpsModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid() && lrcInstance_) {
|
||||
/*
|
||||
* Count.
|
||||
*/
|
||||
QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
|
||||
if (deviceCapabilities.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
|
||||
auto currentChannel = currentSettings.channel;
|
||||
currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
|
||||
auto channelCaps = deviceCapabilities[currentChannel];
|
||||
|
||||
bool resolutionFound = false;
|
||||
int indexOfCurrentResolutionInResRateList = 0;
|
||||
|
||||
for (int i = 0; i < channelCaps.size(); i++) {
|
||||
if (channelCaps[i].first == currentResolution_) {
|
||||
indexOfCurrentResolutionInResRateList = i;
|
||||
resolutionFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (resolutionFound) {
|
||||
auto fpsList = channelCaps[indexOfCurrentResolutionInResRateList].second;
|
||||
return fpsList.size();
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* A valid QModelIndex returns 0 as no entry has sub-elements.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
VideoFormatFpsModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
/*
|
||||
* Only need one column.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoFormatFpsModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
try {
|
||||
QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
|
||||
|
||||
auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
|
||||
auto currentChannel = currentSettings.channel;
|
||||
currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
|
||||
auto channelCaps = deviceCapabilities[currentChannel];
|
||||
|
||||
bool resolutionFound = false;
|
||||
int indexOfCurrentResolutionInResRateList = 0;
|
||||
|
||||
for (int i = 0; i < channelCaps.size(); i++) {
|
||||
if (channelCaps[i].first == currentResolution_) {
|
||||
indexOfCurrentResolutionInResRateList = i;
|
||||
resolutionFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!index.isValid() || channelCaps.size() <= index.row() || deviceCapabilities.size() == 0
|
||||
|| !resolutionFound) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
auto fpsList = channelCaps[indexOfCurrentResolutionInResRateList].second;
|
||||
|
||||
switch (role) {
|
||||
case Role::FPS:
|
||||
return QVariant(fpsList[index.row()]);
|
||||
case Role::FPS_ToDisplay_UTF8:
|
||||
QString rateDisplayUtf8 = QString("%1 fps").arg((int) fpsList[index.row()]);
|
||||
return QVariant(rateDisplayUtf8.toUtf8());
|
||||
}
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
VideoFormatFpsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[FPS] = "FPS";
|
||||
roles[FPS_ToDisplay_UTF8] = "FPS_ToDisplay_UTF8";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
VideoFormatFpsModel::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
if (column != 0) {
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
if (row >= 0 && row < rowCount()) {
|
||||
return createIndex(row, column);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
VideoFormatFpsModel::parent(const QModelIndex& child) const
|
||||
{
|
||||
Q_UNUSED(child);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
Qt::ItemFlags
|
||||
VideoFormatFpsModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
|
||||
if (!index.isValid()) {
|
||||
return QAbstractItemModel::flags(index);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
void
|
||||
VideoFormatFpsModel::reset()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int
|
||||
VideoFormatFpsModel::getCurrentSettingIndex()
|
||||
{
|
||||
int resultRowIndex = 0;
|
||||
try {
|
||||
QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
|
||||
float currentFps = currentSettings.rate;
|
||||
auto resultList = match(index(0, 0), FPS, QVariant(currentFps));
|
||||
|
||||
if (resultList.size() > 0) {
|
||||
resultRowIndex = resultList[0].row();
|
||||
}
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
|
||||
return resultRowIndex;
|
||||
}
|
||||
|
||||
QString
|
||||
VideoFormatFpsModel::getCurrentResolution()
|
||||
{
|
||||
return currentResolution_;
|
||||
}
|
||||
|
||||
void
|
||||
VideoFormatFpsModel::setCurrentResolution(QString resNew)
|
||||
{
|
||||
if (currentResolution_ != resNew) {
|
||||
currentResolution_ = resNew;
|
||||
reset();
|
||||
Q_EMIT currentResolutionChanged(resNew);
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019-2020 by Savoir-faire Linux
|
||||
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "abstractlistmodelbase.h"
|
||||
|
||||
class VideoFormatFpsModel : public AbstractListModelBase
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString currentResolution READ getCurrentResolution WRITE setCurrentResolution NOTIFY
|
||||
currentResolutionChanged);
|
||||
|
||||
public:
|
||||
enum Role { FPS = Qt::UserRole + 1, FPS_ToDisplay_UTF8 };
|
||||
Q_ENUM(Role)
|
||||
|
||||
explicit VideoFormatFpsModel(QObject* parent = nullptr);
|
||||
~VideoFormatFpsModel();
|
||||
|
||||
/*
|
||||
* QAbstractListModel override.
|
||||
*/
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
/*
|
||||
* Override role name as access point in qml.
|
||||
*/
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex& child) const;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||
|
||||
/*
|
||||
* This function is to reset the model when there's new account added.
|
||||
*/
|
||||
Q_INVOKABLE void reset();
|
||||
/*
|
||||
* This function is to get the current device id in the demon.
|
||||
*/
|
||||
Q_INVOKABLE int getCurrentSettingIndex();
|
||||
|
||||
/*
|
||||
* Getters and setters
|
||||
*/
|
||||
QString getCurrentResolution();
|
||||
void setCurrentResolution(QString resNew);
|
||||
|
||||
Q_SIGNALS:
|
||||
void currentResolutionChanged(QString resNew);
|
||||
|
||||
private:
|
||||
QString currentResolution_;
|
||||
};
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019-2020 by Savoir-faire Linux
|
||||
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "videoformatresolutionmodel.h"
|
||||
|
||||
#include "lrcinstance.h"
|
||||
|
||||
#include "api/account.h"
|
||||
#include "api/contact.h"
|
||||
#include "api/conversation.h"
|
||||
#include "api/newdevicemodel.h"
|
||||
|
||||
VideoFormatResolutionModel::VideoFormatResolutionModel(QObject* parent)
|
||||
: AbstractListModelBase(parent)
|
||||
{}
|
||||
|
||||
VideoFormatResolutionModel::~VideoFormatResolutionModel() {}
|
||||
|
||||
int
|
||||
VideoFormatResolutionModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid() && lrcInstance_) {
|
||||
/*
|
||||
* Count.
|
||||
*/
|
||||
QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
|
||||
if (deviceCapabilities.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
|
||||
auto currentChannel = currentSettings.channel;
|
||||
currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
|
||||
auto channelCaps = deviceCapabilities[currentChannel];
|
||||
|
||||
return channelCaps.size();
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* A valid QModelIndex returns 0 as no entry has sub-elements.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
VideoFormatResolutionModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
/*
|
||||
* Only need one column.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoFormatResolutionModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
try {
|
||||
QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto deviceCapabilities = lrcInstance_->avModel().getDeviceCapabilities(currentDeviceId);
|
||||
|
||||
auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
|
||||
auto currentChannel = currentSettings.channel;
|
||||
currentChannel = currentChannel.isEmpty() ? "default" : currentChannel;
|
||||
auto channelCaps = deviceCapabilities[currentChannel];
|
||||
|
||||
if (!index.isValid() || channelCaps.size() <= index.row()
|
||||
|| deviceCapabilities.size() == 0) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case Role::Resolution:
|
||||
return QVariant(channelCaps.at(index.row()).first);
|
||||
case Role::Resolution_UTF8:
|
||||
return QVariant(channelCaps.at(index.row()).first.toUtf8());
|
||||
}
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
VideoFormatResolutionModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Resolution] = "Resolution";
|
||||
roles[Resolution_UTF8] = "Resolution_UTF8";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
VideoFormatResolutionModel::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
if (column != 0) {
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
if (row >= 0 && row < rowCount()) {
|
||||
return createIndex(row, column);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
VideoFormatResolutionModel::parent(const QModelIndex& child) const
|
||||
{
|
||||
Q_UNUSED(child);
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
Qt::ItemFlags
|
||||
VideoFormatResolutionModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
auto flags = QAbstractItemModel::flags(index) | Qt::ItemNeverHasChildren | Qt::ItemIsSelectable;
|
||||
if (!index.isValid()) {
|
||||
return QAbstractItemModel::flags(index);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
void
|
||||
VideoFormatResolutionModel::reset()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int
|
||||
VideoFormatResolutionModel::getCurrentSettingIndex()
|
||||
{
|
||||
int resultRowIndex = 0;
|
||||
try {
|
||||
QString currentDeviceId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto currentSettings = lrcInstance_->avModel().getDeviceSettings(currentDeviceId);
|
||||
QString currentResolution = currentSettings.size;
|
||||
auto resultList = match(index(0, 0), Resolution, QVariant(currentResolution));
|
||||
|
||||
if (resultList.size() > 0) {
|
||||
resultRowIndex = resultList[0].row();
|
||||
}
|
||||
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << e.what();
|
||||
}
|
||||
|
||||
return resultRowIndex;
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019-2020 by Savoir-faire Linux
|
||||
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "abstractlistmodelbase.h"
|
||||
|
||||
class VideoFormatResolutionModel : public AbstractListModelBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Role { Resolution = Qt::UserRole + 1, Resolution_UTF8 };
|
||||
Q_ENUM(Role)
|
||||
|
||||
explicit VideoFormatResolutionModel(QObject* parent = nullptr);
|
||||
~VideoFormatResolutionModel();
|
||||
|
||||
/*
|
||||
* QAbstractListModel override.
|
||||
*/
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
/*
|
||||
* Override role name as access point in qml.
|
||||
*/
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const;
|
||||
QModelIndex parent(const QModelIndex& child) const;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||
|
||||
/*
|
||||
* This function is to reset the model when there's new account added.
|
||||
*/
|
||||
Q_INVOKABLE void reset();
|
||||
/*
|
||||
* This function is to get the current device id in the demon.
|
||||
*/
|
||||
Q_INVOKABLE int getCurrentSettingIndex();
|
||||
};
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019-2020 by Savoir-faire Linux
|
||||
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "videoinputdevicemodel.h"
|
||||
|
||||
#include "lrcinstance.h"
|
||||
|
||||
#include "api/newdevicemodel.h"
|
||||
|
||||
VideoInputDeviceModel::VideoInputDeviceModel(QObject* parent)
|
||||
: AbstractListModelBase(parent)
|
||||
{}
|
||||
|
||||
VideoInputDeviceModel::~VideoInputDeviceModel() {}
|
||||
|
||||
int
|
||||
VideoInputDeviceModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
if (!parent.isValid() && lrcInstance_) {
|
||||
return lrcInstance_->avModel().getDevices().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QVariant
|
||||
VideoInputDeviceModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
auto deviceList = lrcInstance_->avModel().getDevices();
|
||||
if (!index.isValid()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (deviceList.size() <= index.row()) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
auto currentDeviceSetting = lrcInstance_->avModel().getDeviceSettings(deviceList[index.row()]);
|
||||
|
||||
switch (role) {
|
||||
case Role::DeviceChannel:
|
||||
return QVariant((QString) currentDeviceSetting.channel);
|
||||
case Role::DeviceName:
|
||||
return QVariant(currentDeviceSetting.name);
|
||||
case Role::DeviceId:
|
||||
return QVariant(currentDeviceSetting.id);
|
||||
case Role::CurrentFrameRate:
|
||||
return QVariant((float) currentDeviceSetting.rate);
|
||||
case Role::CurrentResolution:
|
||||
return QVariant((QString) currentDeviceSetting.size);
|
||||
case Role::DeviceName_UTF8:
|
||||
return QVariant(currentDeviceSetting.name.toUtf8());
|
||||
case Role::isCurrent:
|
||||
return QVariant(index.row() == getCurrentIndex());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray>
|
||||
VideoInputDeviceModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[DeviceChannel] = "DeviceChannel";
|
||||
roles[DeviceName] = "DeviceName";
|
||||
roles[DeviceId] = "DeviceId";
|
||||
roles[CurrentFrameRate] = "CurrentFrameRate";
|
||||
roles[CurrentResolution] = "CurrentResolution";
|
||||
roles[DeviceName_UTF8] = "DeviceName_UTF8";
|
||||
roles[isCurrent] = "isCurrent";
|
||||
return roles;
|
||||
}
|
||||
|
||||
void
|
||||
VideoInputDeviceModel::reset()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int
|
||||
VideoInputDeviceModel::deviceCount()
|
||||
{
|
||||
return lrcInstance_->avModel().getDevices().size();
|
||||
}
|
||||
|
||||
int
|
||||
VideoInputDeviceModel::getCurrentIndex() const
|
||||
{
|
||||
QString currentId = lrcInstance_->avModel().getCurrentVideoCaptureDevice();
|
||||
auto resultList = match(index(0, 0), DeviceId, QVariant(currentId));
|
||||
return resultList.size() > 0 ? resultList[0].row() : 0;
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019-2020 by Savoir-faire Linux
|
||||
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "abstractlistmodelbase.h"
|
||||
|
||||
class VideoInputDeviceModel : public AbstractListModelBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Role {
|
||||
DeviceName = Qt::UserRole + 1,
|
||||
DeviceChannel,
|
||||
DeviceId,
|
||||
CurrentFrameRate,
|
||||
CurrentResolution,
|
||||
DeviceName_UTF8,
|
||||
isCurrent
|
||||
};
|
||||
Q_ENUM(Role)
|
||||
|
||||
explicit VideoInputDeviceModel(QObject* parent = nullptr);
|
||||
~VideoInputDeviceModel();
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
Q_INVOKABLE void reset();
|
||||
Q_INVOKABLE int deviceCount();
|
||||
|
||||
// get model index of the current device
|
||||
Q_INVOKABLE int getCurrentIndex() const;
|
||||
};
|
Loading…
Add table
Reference in a new issue