Feature: custom shortcuts on main page.

#LINQT-1506
This commit is contained in:
Julien Wadel 2025-01-09 09:29:20 +01:00
parent 6833dd10d2
commit d5f8c1af0a
7 changed files with 100 additions and 13 deletions

View file

@ -110,6 +110,9 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
INIT_CORE_MEMBER(Ipv6Enabled, settingsModel)
INIT_CORE_MEMBER(ConfigLocale, settingsModel)
INIT_CORE_MEMBER(DownloadFolder, settingsModel)
INIT_CORE_MEMBER(ShortcutCount, settingsModel)
INIT_CORE_MEMBER(Shortcuts, settingsModel)
}
SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
@ -178,6 +181,8 @@ SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
mIpv6Enabled = settingsCore.mIpv6Enabled;
mConfigLocale = settingsCore.mConfigLocale;
mDownloadFolder = settingsCore.mDownloadFolder;
mShortcutCount = settingsCore.mShortcutCount;
mShortcuts = settingsCore.mShortcuts;
}
SettingsCore::~SettingsCore() {
@ -339,6 +344,10 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
configLocale, ConfigLocale)
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
downloadFolder, DownloadFolder)
DEFINE_CORE_GET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, int, shortcutCount,
ShortcutCount)
DEFINE_CORE_GET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QVariantList,
shortcuts, Shortcuts)
auto coreModelConnection = QSharedPointer<SafeConnection<SettingsCore, CoreModel>>(
new SafeConnection<SettingsCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
@ -936,4 +945,4 @@ void SettingsCore::undo() {
});
});
}
}
}

View file

@ -212,10 +212,11 @@ public:
DECLARE_CORE_GETSET(bool, exitOnClose, ExitOnClose)
DECLARE_CORE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
DECLARE_CORE_GETSET_MEMBER(bool, ipv6Enabled, Ipv6Enabled)
DECLARE_CORE_GETSET_MEMBER(QVariantList, audioCodecs, AudioCodecs)
DECLARE_CORE_GETSET_MEMBER(QVariantList, videoCodecs, VideoCodecs)
DECLARE_CORE_GETSET(QString, configLocale, ConfigLocale)
DECLARE_CORE_GETSET(QString, downloadFolder, DownloadFolder)
// Read-only
DECLARE_CORE_MEMBER(int, shortcutCount, ShortcutCount)
DECLARE_CORE_MEMBER(QVariantList, shortcuts, Shortcuts)
signals:
@ -306,7 +307,7 @@ private:
QVariantList mConferenceLayouts;
QVariantMap mConferenceLayout;
// Video
QStringList mVideoDevices;
QString mVideoDevice;

View file

@ -620,6 +620,47 @@ bool SettingsModel::getShowChats() const {
return mConfig->getBool(UiSection, "disable_chat_feature", false);
}*/
QVariantList SettingsModel::getShortcuts() const {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
QVariantList shortcuts;
auto sections = mConfig->getSectionsNamesList();
for (auto section : sections) {
auto sectionTokens = Utils::coreStringToAppString(section).split('_');
if (sectionTokens.size() > 1 && sectionTokens[0].compare("shortcut", Qt::CaseInsensitive) == 0) {
QVariantMap shortcut;
shortcut["id"] = sectionTokens[1].toInt();
shortcut["name"] = Utils::coreStringToAppString(mConfig->getString(section, "name", ""));
shortcut["link"] = Utils::coreStringToAppString(mConfig->getString(section, "link", ""));
shortcut["icon"] = Utils::coreStringToAppString(mConfig->getString(section, "icon", ""));
shortcuts << shortcut;
}
}
return shortcuts;
}
void SettingsModel::setShortcuts(QVariantList data) {
if (getShortcuts() != data) {
// clean
auto sections = mConfig->getSectionsNamesList();
for (auto section : sections) {
auto sectionTokens = Utils::coreStringToAppString(section).split('_');
if (sectionTokens.size() > 1 && sectionTokens[0].compare("shortcut", Qt::CaseInsensitive) == 0) {
mConfig->cleanSection(section);
}
}
int count = 0;
for (auto shortcut : data) {
auto mShortcut = shortcut.toMap();
auto key = Utils::appStringToCoreString("shortcut_" + QString::number(count++));
mConfig->setString(key, "name", Utils::appStringToCoreString(mShortcut["name"].toString()));
mConfig->setString(key, "link", Utils::appStringToCoreString(mShortcut["link"].toString()));
mConfig->setString(key, "icon", Utils::appStringToCoreString(mShortcut["icon"].toString()));
}
emit shortcutsChanged(data);
}
}
// clang-format off
void SettingsModel::notifyConfigReady(){
DEFINE_NOTIFY_CONFIG_READY(disableChatFeature, DisableChatFeature)
@ -642,6 +683,8 @@ void SettingsModel::notifyConfigReady(){
DEFINE_NOTIFY_CONFIG_READY(syncLdapContacts, SyncLdapContacts)
DEFINE_NOTIFY_CONFIG_READY(configLocale, ConfigLocale)
DEFINE_NOTIFY_CONFIG_READY(downloadFolder, DownloadFolder)
DEFINE_NOTIFY_CONFIG_READY(shortcutCount, ShortcutCount)
DEFINE_NOTIFY_CONFIG_READY(shortcuts, Shortcuts)
}
DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, disableChatFeature, DisableChatFeature, "disable_chat_feature", true)
@ -749,4 +792,11 @@ DEFINE_GETSET_CONFIG_STRING(SettingsModel,
DownloadFolder,
"download_folder",
"")
DEFINE_GETSET_CONFIG(SettingsModel,
int,
Int,
shortcutCount,
ShortcutCount,
"shortcut_count",
0)
// clang-format on

View file

@ -168,6 +168,8 @@ public:
DECLARE_GETSET(bool, ipv6Enabled, Ipv6Enabled)
DECLARE_GETSET(QString, configLocale, ConfigLocale)
DECLARE_GETSET(QString, downloadFolder, DownloadFolder)
DECLARE_GETSET(int, shortcutCount, ShortcutCount)
DECLARE_GETSET(QVariantList, shortcuts, Shortcuts)
signals:
void logsUploadUrlChanged();
@ -198,8 +200,6 @@ signals:
void mediaEncryptionChanged();
void mediaEncryptionMandatoryChanged();
void showAudioCodecsChanged(bool status);
void micVolumeChanged(float volume);
void logsEnabledChanged(bool status);

View file

@ -14,6 +14,12 @@ Control.TabBar {
readonly property alias cornerRadius: bottomLeftCorner.radius
property AccountGui defaultAccount
// Call it after model is ready. If done before, Repeater will not be updated
function initButtons(){
actionsRepeater.model = mainItem.model
}
onDefaultAccountChanged: {
if (defaultAccount) defaultAccount.core?.lRefreshNotifications()
}
@ -77,14 +83,13 @@ Control.TabBar {
height: parent.height/2
}
}
Repeater {
id: actionsRepeater
model: mainItem.model
Control.TabButton {
id: tabButton
width: mainItem.width
height: visible ? undefined : 0
height: visible && buttonIcon.isImageReady ? undefined : 0
bottomInset: 32 * DefaultStyle.dp
topInset: 32 * DefaultStyle.dp
@ -112,10 +117,12 @@ Control.TabBar {
Layout.preferredHeight: buttonSize
Layout.alignment: Qt.AlignHCenter
fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.grey_0
colorizationColor: DefaultStyle.grey_0
useColor: !modelData.colored
}
Text {
id: buttonText
visible: buttonIcon.isImageReady
text: modelData.label
font {
weight: mainItem.currentIndex === index ? 800 * DefaultStyle.dp : 400 * DefaultStyle.dp

View file

@ -17,6 +17,7 @@ Loader {
property int imageHeight: height
property bool useColor: colorizationColor != undefined
property bool shadowEnabled: false
property bool isImageReady: false
asynchronous: true
sourceComponent: Component{Item {
Image {
@ -31,6 +32,7 @@ Loader {
Layout.preferredWidth: mainItem.imageWidth
Layout.preferredHeight: mainItem.imageHeight
anchors.centerIn: parent
onStatusChanged: mainItem.isImageReady = (status == Image.Ready)
}
MultiEffect {
id: effect

View file

@ -11,6 +11,7 @@ import QtQuick.Effects
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
Item {
id: mainItem
@ -116,7 +117,6 @@ Item {
Layout.fillHeight: true
Layout.preferredWidth: 82 * DefaultStyle.dp
defaultAccount: accountProxy.defaultAccount
currentIndex: SettingsCpp.getLastActiveTabIndex()
Binding on currentIndex {
when: mainItem.contextualMenuOpenedComponent != undefined
value: -1
@ -129,7 +129,6 @@ Item {
]
onCurrentIndexChanged: {
if (currentIndex == -1) return
SettingsCpp.setLastActiveTabIndex(currentIndex)
if (currentIndex === 0 && accountProxy.defaultAccount) accountProxy.defaultAccount.core?.lResetMissedCalls()
if (mainItem.contextualMenuOpenedComponent) {
closeContextualMenuComponent()
@ -140,6 +139,16 @@ Item {
mainStackView.currentItem.forceActiveFocus()
}
}
Component.onCompleted:{
if(SettingsCpp.shortcutCount > 0){
var shortcuts = SettingsCpp.shortcuts
shortcuts.forEach((shortcut) => {
model.push({icon: shortcut.icon, selectedIcon: shortcut.icon, label: shortcut.name, colored: true, link:shortcut.link})
});
}
initButtons()
currentIndex= SettingsCpp.getLastActiveTabIndex()
}
}
ColumnLayout {
spacing:0
@ -494,8 +503,17 @@ Item {
StackLayout {
id: mainStackLayout
objectName: "mainStackLayout"
currentIndex: tabbar.currentIndex
property int _currentIndex: tabbar.currentIndex
currentIndex: -1
onActiveFocusChanged: if(activeFocus && currentIndex >= 0) children[currentIndex].forceActiveFocus()
on_CurrentIndexChanged:{
if(count > 0 && _currentIndex >= count && tabbar.model[_currentIndex].link){
Qt.openUrlExternally(tabbar.model[_currentIndex].link)
}else {
currentIndex = _currentIndex
SettingsCpp.setLastActiveTabIndex(currentIndex)
}
}
CallPage {
id: callPage
Connections {