@ -1,16 +1,22 @@
# include "soundsettingspage.h"
# include "sound_manager.h"
# include "../db/db_manager.h"
# include "../transport/gui_bridge.h"
# include "../../lib/mem.h"
extern " C " {
# include "../transport/chat_core.h"
}
# include <QVBoxLayout>
# include <QHBoxLayout>
# include <QCheckBox>
# include <QSlider>
# include <QLabel>
# include <QFile>
# include <QTextStream>
# include <QFrame>
# include <QDebug>
SoundSettingsPage : : SoundSettingsPage ( QWidget * parent )
SoundSettingsPage : : SoundSettingsPage ( DbManager * db , QWidget * parent )
: QWidget ( parent )
, m_db ( db )
{
auto * layout = new QVBoxLayout ( this ) ;
layout - > setContentsMargins ( 0 , 12 , 0 , 0 ) ;
@ -28,8 +34,9 @@ SoundSettingsPage::SoundSettingsPage(QWidget* parent)
m_volumeSlider = new QSlider ( Qt : : Horizontal , this ) ;
m_volumeSlider - > setRange ( 0 , 100 ) ;
m_volumeSlider - > setFixedWidth ( 200 ) ;
m_volumeSlider - > setStyleSheet ( " QSlider::groove:horizontal { height: 6px; border-radius: 3px; background: palette(mid); } "
" QSlider::handle:horizontal { width: 14px; height: 14px; margin: -4px 0; border-radius: 7px; background: #3390EC; } " ) ;
m_volumeSlider - > setStyleSheet (
" QSlider::groove:horizontal { height: 6px; border-radius: 3px; background: palette(mid); } "
" QSlider::handle:horizontal { width: 14px; height: 14px; margin: -4px 0; border-radius: 7px; background: #3390EC; } " ) ;
volLayout - > addWidget ( m_volumeSlider ) ;
m_volumeLabel = new QLabel ( " 80% " , this ) ;
@ -39,82 +46,136 @@ SoundSettingsPage::SoundSettingsPage(QWidget* parent)
volLayout - > addStretch ( ) ;
layout - > addLayout ( volLayout ) ;
auto * sep = new QFrame ( this ) ;
sep - > setFrameShape ( QFrame : : HLine ) ;
sep - > setStyleSheet ( " QFrame { color: palette(mid); } " ) ;
layout - > addWidget ( sep ) ;
auto * header = new QLabel ( " Events " , this ) ;
header - > setStyleSheet ( " font-size: 13px; font-weight: bold; " ) ;
layout - > addWidget ( header ) ;
m_events [ 0 ] = { " msg_incoming " , " Incoming message " , nullptr , nullptr , nullptr } ;
m_events [ 1 ] = { " msg_outgoing " , " Outgoing message " , nullptr , nullptr , nullptr } ;
m_events [ 2 ] = { " connect " , " Peer connected " , nullptr , nullptr , nullptr } ;
m_events [ 3 ] = { " disconnect " , " Peer disconnected " , nullptr , nullptr , nullptr } ;
for ( int i = 0 ; i < 4 ; i + + ) {
auto & e = m_events [ i ] ;
auto * row = new QHBoxLayout ( ) ;
row - > setSpacing ( 8 ) ;
auto * lbl = new QLabel ( e . label , this ) ;
lbl - > setFixedWidth ( 140 ) ;
lbl - > setStyleSheet ( " font-size: 13px; " ) ;
row - > addWidget ( lbl ) ;
e . check = new QCheckBox ( this ) ;
row - > addWidget ( e . check ) ;
e . slider = new QSlider ( Qt : : Horizontal , this ) ;
e . slider - > setRange ( 0 , 100 ) ;
e . slider - > setFixedWidth ( 100 ) ;
e . slider - > setStyleSheet (
" QSlider::groove:horizontal { height: 4px; border-radius: 2px; background: palette(mid); } "
" QSlider::handle:horizontal { width: 10px; height: 10px; margin: -3px 0; border-radius: 5px; background: #3390EC; } " ) ;
row - > addWidget ( e . slider ) ;
e . volLabel = new QLabel ( " 80% " , this ) ;
e . volLabel - > setFixedWidth ( 30 ) ;
e . volLabel - > setStyleSheet ( " font-size: 12px; " ) ;
row - > addWidget ( e . volLabel ) ;
row - > addStretch ( ) ;
layout - > addLayout ( row ) ;
connect ( e . slider , & QSlider : : valueChanged , this , [ this , i ] ( int val ) {
m_events [ i ] . volLabel - > setText ( QString : : number ( val ) + " % " ) ;
} ) ;
}
layout - > addStretch ( ) ;
connect ( m_enabledCheck , & QCheckBox : : stateChanged , this , & SoundSettingsPage : : onEnabledChanged ) ;
connect ( m_enabledCheck , & QCheckBox : : stateChanged , this , [ this ] ( int state ) {
bool on = ( state = = Qt : : Checked ) ;
m_volumeSlider - > setEnabled ( on ) ;
m_volumeLabel - > setEnabled ( on ) ;
} ) ;
connect ( m_volumeSlider , & QSlider : : valueChanged , this , [ this ] ( int val ) {
m_volumeLabel - > setText ( QString : : number ( val ) + " % " ) ;
} ) ;
}
void SoundSettingsPage : : onEnabledChanged ( int state ) {
m_volumeSlider - > setEnabled ( state = = Qt : : Checked ) ;
m_volumeLabel - > setEnabled ( state = = Qt : : Checked ) ;
}
void SoundSettingsPage : : loadFromConfig ( const QString & path ) {
QFile f ( path ) ;
if ( ! f . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) return ;
bool enabled = true ;
int volume = 80 ;
bool inGui = false ;
QTextStream in ( & f ) ;
while ( ! in . atEnd ( ) ) {
QString line = in . readLine ( ) . trimmed ( ) ;
if ( line = = " [gui] " ) { inGui = true ; continue ; }
if ( line . startsWith ( " [ " ) & & line . endsWith ( " ] " ) ) inGui = false ;
if ( ! inGui ) continue ;
if ( line . startsWith ( " sound_enabled= " ) )
enabled = line . mid ( QString ( " sound_enabled= " ) . size ( ) ) . trimmed ( ) ! = " 0 " ;
else if ( line . startsWith ( " sound_volume= " ) )
volume = line . mid ( QString ( " sound_volume= " ) . size ( ) ) . trimmed ( ) . toInt ( ) ;
}
f . close ( ) ;
void SoundSettingsPage : : loadFromDb ( ) {
if ( ! m_db ) return ;
bool enabled = m_db - > getUiStateInt ( " sound_enabled " , 1 ) ;
m_enabledCheck - > setChecked ( enabled ) ;
m_volumeSlider - > setValue ( volume ) ;
int vol = m_db - > getUiStateInt ( " sound_volume " , 80 ) ;
m_volumeSlider - > setValue ( vol ) ;
m_volumeSlider - > setEnabled ( enabled ) ;
m_volumeLabel - > setEnabled ( enabled ) ;
m_volumeLabel - > setText ( QString : : number ( volume ) + " % " ) ;
m_volumeLabel - > setText ( QString : : number ( vol ) + " % " ) ;
for ( int i = 0 ; i < 4 ; i + + ) {
auto & e = m_events [ i ] ;
QString onKey = QStringLiteral ( " sound_%1_on " ) . arg ( e . key ) ;
QString volKey = QStringLiteral ( " sound_%1_vol " ) . arg ( e . key ) ;
bool on = m_db - > getUiStateInt ( onKey , i = = 0 ? 1 : 0 ) ; // only msg_incoming on by default
int ev = m_db - > getUiStateInt ( volKey , 80 ) ;
e . check - > setChecked ( on ) ;
e . slider - > setValue ( ev ) ;
e . volLabel - > setText ( QString : : number ( ev ) + " % " ) ;
}
}
void SoundSettingsPage : : saveToConfig ( const QString & path ) const {
QFile f ( path ) ;
if ( ! f . open ( QIODevice : : ReadOnly | QIODevice : : Text ) ) return ;
QString content = f . readAll ( ) ;
f . close ( ) ;
QStringList lines = content . split ( ' \n ' ) ;
bool inGui = false ;
bool foundEnabled = false , foundVolume = false ;
for ( int i = 0 ; i < lines . size ( ) ; i + + ) {
QString line = lines [ i ] . trimmed ( ) ;
if ( line = = " [gui] " ) { inGui = true ; continue ; }
if ( line . startsWith ( " [ " ) & & line . endsWith ( " ] " ) ) inGui = false ;
if ( ! inGui ) continue ;
if ( line . startsWith ( " sound_enabled= " ) ) {
lines [ i ] = QString ( " sound_enabled=%1 " ) . arg ( m_enabledCheck - > isChecked ( ) ? 1 : 0 ) ;
foundEnabled = true ;
} else if ( line . startsWith ( " sound_volume= " ) ) {
lines [ i ] = QString ( " sound_volume=%1 " ) . arg ( m_volumeSlider - > value ( ) ) ;
foundVolume = true ;
void SoundSettingsPage : : applyAndSave ( ) {
SoundManager * sm = SoundManager : : instance ( ) ;
bool enabled = m_enabledCheck - > isChecked ( ) ;
float masterVol = m_volumeSlider - > value ( ) / 100.0f ;
sm - > setEnabled ( enabled ) ;
sm - > setVolume ( masterVol ) ;
for ( int i = 0 ; i < 4 ; i + + ) {
auto & e = m_events [ i ] ;
bool on = e . check - > isChecked ( ) ;
float ev = e . slider - > value ( ) / 100.0f ;
sm - > setEvent ( e . key , on , ev ) ;
/* async DB persist — key\0value\0 */
QString onKey = QStringLiteral ( " sound_%1_on " ) . arg ( e . key ) ;
QString volKey = QStringLiteral ( " sound_%1_vol " ) . arg ( e . key ) ;
QByteArray onVal = on ? QByteArray ( " 1 " ) : QByteArray ( " 0 " ) ;
QByteArray volVal = QByteArray : : number ( e . slider - > value ( ) ) ;
for ( int j = 0 ; j < 2 ; j + + ) {
const char * k = j = = 0 ? onKey . toUtf8 ( ) . constData ( ) : volKey . toUtf8 ( ) . constData ( ) ;
const char * v = j = = 0 ? onVal . constData ( ) : volVal . constData ( ) ;
size_t klen = strlen ( k ) , vlen = strlen ( v ) ;
size_t total = klen + 1 + vlen + 1 ;
if ( total > 256 ) continue ;
void * arg = u_malloc ( total ) ;
memcpy ( arg , k , klen + 1 ) ;
memcpy ( ( char * ) arg + klen + 1 , v , vlen + 1 ) ;
gui_bridge_post_uasync_fn ( chat_core_save_ui_state_trampoline , arg ) ;
}
}
if ( ! foundEnabled | | ! foundVolume ) {
for ( int i = 0 ; i < lines . size ( ) ; i + + ) {
if ( lines [ i ] . trimmed ( ) = = " [gui] " ) {
if ( ! foundEnabled ) lines . insert ( i + 1 , QString ( " sound_enabled=%1 " ) . arg ( m_enabledCheck - > isChecked ( ) ? 1 : 0 ) ) ;
if ( ! foundVolume ) lines . insert ( i + 1 , QString ( " sound_volume=%1 " ) . arg ( m_volumeSlider - > value ( ) ) ) ;
break ;
}
/* save global settings */
{
const char * keys [ ] = { " sound_enabled " , " sound_volume " } ;
QByteArray vals [ ] = { enabled ? QByteArray ( " 1 " ) : QByteArray ( " 0 " ) ,
QByteArray : : number ( m_volumeSlider - > value ( ) ) } ;
for ( int j = 0 ; j < 2 ; j + + ) {
size_t klen = strlen ( keys [ j ] ) , vlen = vals [ j ] . size ( ) ;
size_t total = klen + 1 + vlen + 1 ;
if ( total > 256 ) continue ;
void * arg = u_malloc ( total ) ;
memcpy ( arg , keys [ j ] , klen + 1 ) ;
memcpy ( ( char * ) arg + klen + 1 , vals [ j ] . constData ( ) , vlen + 1 ) ;
gui_bridge_post_uasync_fn ( chat_core_save_ui_state_trampoline , arg ) ;
}
}
f . open ( QIODevice : : WriteOnly | QIODevice : : Truncate | QIODevice : : Text ) ;
f . write ( lines . join ( ' \n ' ) . toUtf8 ( ) ) ;
f . close ( ) ;
}