Feature: custom shortcuts on main page.
#LINQT-1506
This commit is contained in:
parent
6833dd10d2
commit
d5f8c1af0a
7 changed files with 100 additions and 13 deletions
|
|
@ -110,6 +110,9 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
|
||||||
INIT_CORE_MEMBER(Ipv6Enabled, settingsModel)
|
INIT_CORE_MEMBER(Ipv6Enabled, settingsModel)
|
||||||
INIT_CORE_MEMBER(ConfigLocale, settingsModel)
|
INIT_CORE_MEMBER(ConfigLocale, settingsModel)
|
||||||
INIT_CORE_MEMBER(DownloadFolder, settingsModel)
|
INIT_CORE_MEMBER(DownloadFolder, settingsModel)
|
||||||
|
|
||||||
|
INIT_CORE_MEMBER(ShortcutCount, settingsModel)
|
||||||
|
INIT_CORE_MEMBER(Shortcuts, settingsModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
|
SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
|
||||||
|
|
@ -178,6 +181,8 @@ SettingsCore::SettingsCore(const SettingsCore &settingsCore) {
|
||||||
mIpv6Enabled = settingsCore.mIpv6Enabled;
|
mIpv6Enabled = settingsCore.mIpv6Enabled;
|
||||||
mConfigLocale = settingsCore.mConfigLocale;
|
mConfigLocale = settingsCore.mConfigLocale;
|
||||||
mDownloadFolder = settingsCore.mDownloadFolder;
|
mDownloadFolder = settingsCore.mDownloadFolder;
|
||||||
|
mShortcutCount = settingsCore.mShortcutCount;
|
||||||
|
mShortcuts = settingsCore.mShortcuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCore::~SettingsCore() {
|
SettingsCore::~SettingsCore() {
|
||||||
|
|
@ -339,6 +344,10 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
||||||
configLocale, ConfigLocale)
|
configLocale, ConfigLocale)
|
||||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
|
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, QString,
|
||||||
downloadFolder, DownloadFolder)
|
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>>(
|
auto coreModelConnection = QSharedPointer<SafeConnection<SettingsCore, CoreModel>>(
|
||||||
new SafeConnection<SettingsCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
|
new SafeConnection<SettingsCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
|
||||||
|
|
|
||||||
|
|
@ -212,10 +212,11 @@ public:
|
||||||
DECLARE_CORE_GETSET(bool, exitOnClose, ExitOnClose)
|
DECLARE_CORE_GETSET(bool, exitOnClose, ExitOnClose)
|
||||||
DECLARE_CORE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
|
DECLARE_CORE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
|
||||||
DECLARE_CORE_GETSET_MEMBER(bool, ipv6Enabled, Ipv6Enabled)
|
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, configLocale, ConfigLocale)
|
||||||
DECLARE_CORE_GETSET(QString, downloadFolder, DownloadFolder)
|
DECLARE_CORE_GETSET(QString, downloadFolder, DownloadFolder)
|
||||||
|
// Read-only
|
||||||
|
DECLARE_CORE_MEMBER(int, shortcutCount, ShortcutCount)
|
||||||
|
DECLARE_CORE_MEMBER(QVariantList, shortcuts, Shortcuts)
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -620,6 +620,47 @@ bool SettingsModel::getShowChats() const {
|
||||||
return mConfig->getBool(UiSection, "disable_chat_feature", false);
|
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
|
// clang-format off
|
||||||
void SettingsModel::notifyConfigReady(){
|
void SettingsModel::notifyConfigReady(){
|
||||||
DEFINE_NOTIFY_CONFIG_READY(disableChatFeature, DisableChatFeature)
|
DEFINE_NOTIFY_CONFIG_READY(disableChatFeature, DisableChatFeature)
|
||||||
|
|
@ -642,6 +683,8 @@ void SettingsModel::notifyConfigReady(){
|
||||||
DEFINE_NOTIFY_CONFIG_READY(syncLdapContacts, SyncLdapContacts)
|
DEFINE_NOTIFY_CONFIG_READY(syncLdapContacts, SyncLdapContacts)
|
||||||
DEFINE_NOTIFY_CONFIG_READY(configLocale, ConfigLocale)
|
DEFINE_NOTIFY_CONFIG_READY(configLocale, ConfigLocale)
|
||||||
DEFINE_NOTIFY_CONFIG_READY(downloadFolder, DownloadFolder)
|
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)
|
DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, disableChatFeature, DisableChatFeature, "disable_chat_feature", true)
|
||||||
|
|
@ -749,4 +792,11 @@ DEFINE_GETSET_CONFIG_STRING(SettingsModel,
|
||||||
DownloadFolder,
|
DownloadFolder,
|
||||||
"download_folder",
|
"download_folder",
|
||||||
"")
|
"")
|
||||||
|
DEFINE_GETSET_CONFIG(SettingsModel,
|
||||||
|
int,
|
||||||
|
Int,
|
||||||
|
shortcutCount,
|
||||||
|
ShortcutCount,
|
||||||
|
"shortcut_count",
|
||||||
|
0)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,8 @@ public:
|
||||||
DECLARE_GETSET(bool, ipv6Enabled, Ipv6Enabled)
|
DECLARE_GETSET(bool, ipv6Enabled, Ipv6Enabled)
|
||||||
DECLARE_GETSET(QString, configLocale, ConfigLocale)
|
DECLARE_GETSET(QString, configLocale, ConfigLocale)
|
||||||
DECLARE_GETSET(QString, downloadFolder, DownloadFolder)
|
DECLARE_GETSET(QString, downloadFolder, DownloadFolder)
|
||||||
|
DECLARE_GETSET(int, shortcutCount, ShortcutCount)
|
||||||
|
DECLARE_GETSET(QVariantList, shortcuts, Shortcuts)
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void logsUploadUrlChanged();
|
void logsUploadUrlChanged();
|
||||||
|
|
@ -198,8 +200,6 @@ signals:
|
||||||
void mediaEncryptionChanged();
|
void mediaEncryptionChanged();
|
||||||
void mediaEncryptionMandatoryChanged();
|
void mediaEncryptionMandatoryChanged();
|
||||||
|
|
||||||
void showAudioCodecsChanged(bool status);
|
|
||||||
|
|
||||||
void micVolumeChanged(float volume);
|
void micVolumeChanged(float volume);
|
||||||
|
|
||||||
void logsEnabledChanged(bool status);
|
void logsEnabledChanged(bool status);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,12 @@ Control.TabBar {
|
||||||
readonly property alias cornerRadius: bottomLeftCorner.radius
|
readonly property alias cornerRadius: bottomLeftCorner.radius
|
||||||
|
|
||||||
property AccountGui defaultAccount
|
property AccountGui defaultAccount
|
||||||
|
|
||||||
|
// Call it after model is ready. If done before, Repeater will not be updated
|
||||||
|
function initButtons(){
|
||||||
|
actionsRepeater.model = mainItem.model
|
||||||
|
}
|
||||||
|
|
||||||
onDefaultAccountChanged: {
|
onDefaultAccountChanged: {
|
||||||
if (defaultAccount) defaultAccount.core?.lRefreshNotifications()
|
if (defaultAccount) defaultAccount.core?.lRefreshNotifications()
|
||||||
}
|
}
|
||||||
|
|
@ -80,11 +86,10 @@ Control.TabBar {
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: actionsRepeater
|
id: actionsRepeater
|
||||||
model: mainItem.model
|
|
||||||
Control.TabButton {
|
Control.TabButton {
|
||||||
id: tabButton
|
id: tabButton
|
||||||
width: mainItem.width
|
width: mainItem.width
|
||||||
height: visible ? undefined : 0
|
height: visible && buttonIcon.isImageReady ? undefined : 0
|
||||||
bottomInset: 32 * DefaultStyle.dp
|
bottomInset: 32 * DefaultStyle.dp
|
||||||
topInset: 32 * DefaultStyle.dp
|
topInset: 32 * DefaultStyle.dp
|
||||||
|
|
||||||
|
|
@ -113,9 +118,11 @@ Control.TabBar {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
colorizationColor: DefaultStyle.grey_0
|
colorizationColor: DefaultStyle.grey_0
|
||||||
|
useColor: !modelData.colored
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
id: buttonText
|
id: buttonText
|
||||||
|
visible: buttonIcon.isImageReady
|
||||||
text: modelData.label
|
text: modelData.label
|
||||||
font {
|
font {
|
||||||
weight: mainItem.currentIndex === index ? 800 * DefaultStyle.dp : 400 * DefaultStyle.dp
|
weight: mainItem.currentIndex === index ? 800 * DefaultStyle.dp : 400 * DefaultStyle.dp
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ Loader {
|
||||||
property int imageHeight: height
|
property int imageHeight: height
|
||||||
property bool useColor: colorizationColor != undefined
|
property bool useColor: colorizationColor != undefined
|
||||||
property bool shadowEnabled: false
|
property bool shadowEnabled: false
|
||||||
|
property bool isImageReady: false
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
sourceComponent: Component{Item {
|
sourceComponent: Component{Item {
|
||||||
Image {
|
Image {
|
||||||
|
|
@ -31,6 +32,7 @@ Loader {
|
||||||
Layout.preferredWidth: mainItem.imageWidth
|
Layout.preferredWidth: mainItem.imageWidth
|
||||||
Layout.preferredHeight: mainItem.imageHeight
|
Layout.preferredHeight: mainItem.imageHeight
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
onStatusChanged: mainItem.isImageReady = (status == Image.Ready)
|
||||||
}
|
}
|
||||||
MultiEffect {
|
MultiEffect {
|
||||||
id: effect
|
id: effect
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import QtQuick.Effects
|
||||||
import Linphone
|
import Linphone
|
||||||
import UtilsCpp
|
import UtilsCpp
|
||||||
import SettingsCpp
|
import SettingsCpp
|
||||||
|
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
|
|
@ -116,7 +117,6 @@ Item {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.preferredWidth: 82 * DefaultStyle.dp
|
Layout.preferredWidth: 82 * DefaultStyle.dp
|
||||||
defaultAccount: accountProxy.defaultAccount
|
defaultAccount: accountProxy.defaultAccount
|
||||||
currentIndex: SettingsCpp.getLastActiveTabIndex()
|
|
||||||
Binding on currentIndex {
|
Binding on currentIndex {
|
||||||
when: mainItem.contextualMenuOpenedComponent != undefined
|
when: mainItem.contextualMenuOpenedComponent != undefined
|
||||||
value: -1
|
value: -1
|
||||||
|
|
@ -129,7 +129,6 @@ Item {
|
||||||
]
|
]
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
if (currentIndex == -1) return
|
if (currentIndex == -1) return
|
||||||
SettingsCpp.setLastActiveTabIndex(currentIndex)
|
|
||||||
if (currentIndex === 0 && accountProxy.defaultAccount) accountProxy.defaultAccount.core?.lResetMissedCalls()
|
if (currentIndex === 0 && accountProxy.defaultAccount) accountProxy.defaultAccount.core?.lResetMissedCalls()
|
||||||
if (mainItem.contextualMenuOpenedComponent) {
|
if (mainItem.contextualMenuOpenedComponent) {
|
||||||
closeContextualMenuComponent()
|
closeContextualMenuComponent()
|
||||||
|
|
@ -140,6 +139,16 @@ Item {
|
||||||
mainStackView.currentItem.forceActiveFocus()
|
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 {
|
ColumnLayout {
|
||||||
spacing:0
|
spacing:0
|
||||||
|
|
@ -494,8 +503,17 @@ Item {
|
||||||
StackLayout {
|
StackLayout {
|
||||||
id: mainStackLayout
|
id: mainStackLayout
|
||||||
objectName: "mainStackLayout"
|
objectName: "mainStackLayout"
|
||||||
currentIndex: tabbar.currentIndex
|
property int _currentIndex: tabbar.currentIndex
|
||||||
|
currentIndex: -1
|
||||||
onActiveFocusChanged: if(activeFocus && currentIndex >= 0) children[currentIndex].forceActiveFocus()
|
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 {
|
CallPage {
|
||||||
id: callPage
|
id: callPage
|
||||||
Connections {
|
Connections {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue