- Add ComboBox for ringtone selection in Call Settings - Convert MKV ringtones to WAV format (Linphone only supports WAV) - Fix ComboSetting to support dialPlan type for international prefix - Disable account devices feature to prevent API errors - Disable automatic update check on startup - Add ringtone fallback to default when custom file not found - Fix ringtone dropdown to not override setting on initialization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
119 lines
3.2 KiB
QML
Executable file
119 lines
3.2 KiB
QML
Executable file
import QtQuick
|
|
import QtQuick.Controls.Basic
|
|
import QtQuick.Layouts
|
|
import QtQml.Models
|
|
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
|
|
|
|
// =============================================================================
|
|
ColumnLayout {
|
|
id: mainLayout
|
|
property alias delegateModel: grid.model
|
|
property alias cellHeight: grid.cellHeight
|
|
property alias cellWidth: grid.cellWidth
|
|
property alias margins: grid.margin
|
|
|
|
function appendItem(item){
|
|
mainLayout.delegateModel.model.append(item)
|
|
}
|
|
|
|
function add(item){
|
|
if( !grid.isLayoutWillChanged())
|
|
appendItem(item)
|
|
else
|
|
bufferModels.append(item)
|
|
}
|
|
|
|
function remove(index){
|
|
if(mainLayout.delegateModel.model.count > index)
|
|
mainLayout.delegateModel.model.remove( index, 1)
|
|
}
|
|
|
|
function get(index){
|
|
return mainLayout.delegateModel.model.get(index)
|
|
}
|
|
|
|
function tryToAdd(item){
|
|
if( !grid.isLayoutWillChanged()) {
|
|
appendItem(item)
|
|
return true
|
|
}else
|
|
return false
|
|
}
|
|
|
|
function clear(){
|
|
if(mainLayout.delegateModel.model.clear) {
|
|
mainLayout.delegateModel.model.clear()
|
|
bufferModels.clear()
|
|
}
|
|
}
|
|
|
|
|
|
property int transitionCount : 0
|
|
property var bufferModels : ListModel{}
|
|
|
|
onWidthChanged: grid.updateLayout()
|
|
onHeightChanged: grid.updateLayout()
|
|
spacing: 0
|
|
|
|
GridView{
|
|
id: grid
|
|
property real margin: Utils.getSizeWithScreenRatio(10)
|
|
property int itemCount: model.count ? model.count :( model.length ? model.length : 0)
|
|
property int columns: 1
|
|
property int rows: 1
|
|
|
|
function getBestLayout(itemCount){
|
|
var availableW = mainLayout.width - grid.margin
|
|
var availableH = mainLayout.height - grid.margin
|
|
var bestSize = 0
|
|
var bestC = 1, bestR = 1
|
|
for(var R = 1 ; R <= itemCount ; ++R){
|
|
for(var C = itemCount ; C >= 1 ; --C){
|
|
if( R * C >= itemCount){// This is a good layout candidate
|
|
var estimatedSize = Math.min(availableW / C, availableH / R)
|
|
if(estimatedSize > bestSize // Size is better
|
|
|| (estimatedSize == bestSize && Math.abs(bestR-bestC) > Math.abs(R - C) )){// Stickers are more homogenized
|
|
bestSize = estimatedSize
|
|
bestC = C
|
|
bestR = R
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return [bestR, bestC]
|
|
}
|
|
|
|
function updateLayout(){
|
|
var bestLayout = getBestLayout(itemCount)
|
|
if( rows != bestLayout[0])
|
|
rows = bestLayout[0]
|
|
if( columns != bestLayout[1])
|
|
columns = bestLayout[1]
|
|
}
|
|
function updateCells(){
|
|
cellWidth = Math.min(computedWidth, computedHeight)
|
|
cellHeight = Math.min(computedWidth, computedHeight)
|
|
}
|
|
onItemCountChanged: updateLayout()
|
|
property real computedWidth: (mainLayout.width - grid.margin ) / columns
|
|
property real computedHeight: (mainLayout.height - grid.margin ) / rows
|
|
onComputedHeightChanged: Qt.callLater(updateCells)
|
|
onComputedWidthChanged: Qt.callLater(updateCells)
|
|
cellWidth: Math.min(computedWidth, computedHeight)
|
|
cellHeight: Math.min(computedWidth, computedHeight)
|
|
|
|
function isLayoutWillChanged(){
|
|
var bestLayout = getBestLayout(itemCount+1)
|
|
return rows !== bestLayout[0] || columns !== bestLayout[1]
|
|
}
|
|
|
|
Layout.preferredWidth: cellWidth * columns
|
|
Layout.preferredHeight: cellHeight * rows
|
|
Layout.alignment: Qt.AlignCenter
|
|
|
|
interactive: false
|
|
model: DelegateModel{}
|
|
|
|
onCountChanged: grid.updateLayout()
|
|
}
|
|
}
|