77#include < QFile>
88#include < QTextStream>
99#include < QProcess>
10+ #include < QScrollArea>
11+ #include < QWidget>
1012
1113SettingsWidget::SettingsWidget (QWidget* parent)
1214 : QWidget(parent)
@@ -18,6 +20,9 @@ SettingsWidget::SettingsWidget(QWidget* parent)
1820 , m_chaoticAurGroup(nullptr )
1921 , m_setupChaoticButton(nullptr )
2022 , m_removeChaoticButton(nullptr )
23+ , m_maintenanceGroup(nullptr )
24+ , m_removeLockButton(nullptr )
25+ , m_syncReposButton(nullptr )
2126 , m_applyButton(nullptr )
2227 , m_revertButton(nullptr )
2328 , m_statusLabel(nullptr )
@@ -31,11 +36,25 @@ SettingsWidget::SettingsWidget(QWidget* parent)
3136}
3237
3338void SettingsWidget::setupUi () {
34- auto * mainLayout = new QVBoxLayout (this );
39+ // Create main layout for the widget
40+ auto * outerLayout = new QVBoxLayout (this );
41+ outerLayout->setContentsMargins (0 , 0 , 0 , 0 );
42+
43+ // Create scroll area
44+ auto * scrollArea = new QScrollArea (this );
45+ scrollArea->setWidgetResizable (true );
46+ scrollArea->setFrameShape (QFrame::NoFrame);
47+ scrollArea->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
48+ scrollArea->setVerticalScrollBarPolicy (Qt::ScrollBarAsNeeded);
49+
50+ // Create content widget that will be scrollable
51+ auto * contentWidget = new QWidget ();
52+ auto * mainLayout = new QVBoxLayout (contentWidget);
3553 mainLayout->setSpacing (20 );
54+ mainLayout->setContentsMargins (10 , 10 , 10 , 10 );
3655
3756 // Title
38- auto * titleLabel = new QLabel (" Settings" , this );
57+ auto * titleLabel = new QLabel (" Settings" , contentWidget );
3958 auto titleFont = titleLabel->font ();
4059 titleFont.setPointSize (24 );
4160 titleFont.setBold (true );
@@ -55,7 +74,7 @@ void SettingsWidget::setupUi() {
5574 mainLayout->addWidget (m_maintenanceGroup);
5675
5776 // Status label
58- m_statusLabel = new QLabel (this );
77+ m_statusLabel = new QLabel (contentWidget );
5978 m_statusLabel->setAlignment (Qt::AlignCenter);
6079 m_statusLabel->setStyleSheet (" QLabel { color: #0066cc; padding: 10px; }" );
6180 m_statusLabel->hide ();
@@ -65,13 +84,13 @@ void SettingsWidget::setupUi() {
6584 auto * buttonLayout = new QHBoxLayout ();
6685 buttonLayout->addStretch ();
6786
68- m_revertButton = new QPushButton (" Revert" , this );
87+ m_revertButton = new QPushButton (" Revert" , contentWidget );
6988 m_revertButton->setMinimumWidth (100 );
7089 m_revertButton->setEnabled (false );
7190 connect (m_revertButton, &QPushButton::clicked, this , &SettingsWidget::onRevertClicked);
7291 buttonLayout->addWidget (m_revertButton);
7392
74- m_applyButton = new QPushButton (" Apply" , this );
93+ m_applyButton = new QPushButton (" Apply" , contentWidget );
7594 m_applyButton->setMinimumWidth (100 );
7695 m_applyButton->setEnabled (false );
7796 connect (m_applyButton, &QPushButton::clicked, this , &SettingsWidget::onApplyClicked);
@@ -82,7 +101,13 @@ void SettingsWidget::setupUi() {
82101 // Add stretch at the bottom
83102 mainLayout->addStretch ();
84103
85- setLayout (mainLayout);
104+ // Set the content widget to the scroll area
105+ scrollArea->setWidget (contentWidget);
106+
107+ // Add scroll area to the outer layout
108+ outerLayout->addWidget (scrollArea);
109+
110+ setLayout (outerLayout);
86111}
87112
88113void SettingsWidget::createRepositorySettings () {
@@ -258,6 +283,39 @@ void SettingsWidget::createMaintenanceSettings() {
258283 lockInfoLabel->setStyleSheet (" QLabel { color: #888; font-size: 11px; margin-top: 5px; margin-left: 10px; }" );
259284 maintenanceLayout->addWidget (lockInfoLabel);
260285
286+ // Spacer
287+ maintenanceLayout->addSpacing (15 );
288+
289+ // Sync repositories section
290+ auto * syncReposLayout = new QHBoxLayout ();
291+
292+ auto * syncReposLabel = new QLabel (
293+ " Synchronize Repositories:" ,
294+ this );
295+ syncReposLabel->setStyleSheet (" QLabel { font-weight: bold; }" );
296+ syncReposLayout->addWidget (syncReposLabel);
297+
298+ syncReposLayout->addStretch ();
299+
300+ m_syncReposButton = new QPushButton (" Sync Repositories" , this );
301+ m_syncReposButton->setMinimumWidth (150 );
302+ m_syncReposButton->setToolTip (
303+ " Manually synchronize package databases (pacman -Sy).\n "
304+ " This updates the list of available packages from all enabled repositories." );
305+ connect (m_syncReposButton, &QPushButton::clicked, this , &SettingsWidget::onSyncReposClicked);
306+ syncReposLayout->addWidget (m_syncReposButton);
307+
308+ maintenanceLayout->addLayout (syncReposLayout);
309+
310+ // Sync info
311+ auto * syncInfoLabel = new QLabel (
312+ " Use this to manually update your package database. This is useful after enabling/disabling repositories\n "
313+ " or when you want to ensure you have the latest package information." ,
314+ this );
315+ syncInfoLabel->setWordWrap (true );
316+ syncInfoLabel->setStyleSheet (" QLabel { color: #888; font-size: 11px; margin-top: 5px; margin-left: 10px; }" );
317+ maintenanceLayout->addWidget (syncInfoLabel);
318+
261319 m_maintenanceGroup->setLayout (maintenanceLayout);
262320}
263321
@@ -969,3 +1027,59 @@ void SettingsWidget::onRemoveChaoticClicked() {
9691027 process->start (" pkexec" , QStringList () << " pacman" << " -Rns" << " --noconfirm"
9701028 << " chaotic-keyring" << " chaotic-mirrorlist" );
9711029}
1030+
1031+ void SettingsWidget::onSyncReposClicked () {
1032+ QMessageBox msgBox (this );
1033+ msgBox.setIcon (QMessageBox::Question);
1034+ msgBox.setWindowTitle (" Sync Repositories" );
1035+ msgBox.setText (" Synchronize package databases?" );
1036+ msgBox.setInformativeText (
1037+ " This will run: pacman -Sy\n\n "
1038+ " This updates the list of available packages from all enabled repositories.\n "
1039+ " This is useful after enabling/disabling repositories or when you want to "
1040+ " ensure you have the latest package information." );
1041+ msgBox.setStandardButtons (QMessageBox::Yes | QMessageBox::No);
1042+ msgBox.setDefaultButton (QMessageBox::Yes);
1043+
1044+ if (msgBox.exec () != QMessageBox::Yes) {
1045+ return ;
1046+ }
1047+
1048+ m_statusLabel->setText (" Synchronizing repositories..." );
1049+ m_statusLabel->setStyleSheet (" QLabel { color: #0066cc; padding: 10px; }" );
1050+ m_statusLabel->show ();
1051+ m_syncReposButton->setEnabled (false );
1052+
1053+ // Run pacman -Sy with pkexec
1054+ QProcess* process = new QProcess (this );
1055+ connect (process, QOverload<int , QProcess::ExitStatus>::of (&QProcess::finished),
1056+ this , [this , process](int exitCode, QProcess::ExitStatus exitStatus) {
1057+ process->deleteLater ();
1058+ m_syncReposButton->setEnabled (true );
1059+
1060+ if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
1061+ m_statusLabel->setText (" Repositories synchronized successfully!" );
1062+ m_statusLabel->setStyleSheet (" QLabel { color: #00aa00; padding: 10px; font-weight: bold; }" );
1063+ m_statusLabel->show ();
1064+ Logger::info (" Repositories synchronized successfully" );
1065+
1066+ // Refresh ALPM databases
1067+ AlpmWrapper::instance ().refreshDatabases ();
1068+
1069+ QMessageBox::information (this , " Success" ,
1070+ " Package databases synchronized successfully!\n\n "
1071+ " The package list has been updated with the latest available packages." );
1072+ } else {
1073+ m_statusLabel->setText (" Failed to synchronize repositories." );
1074+ m_statusLabel->setStyleSheet (" QLabel { color: #aa0000; padding: 10px; }" );
1075+ m_statusLabel->show ();
1076+ Logger::error (" Failed to synchronize repositories" );
1077+
1078+ QMessageBox::critical (this , " Error" ,
1079+ " Failed to synchronize package databases.\n "
1080+ " Please check your internet connection and try again." );
1081+ }
1082+ });
1083+
1084+ process->start (" pkexec" , QStringList () << " pacman" << " -Sy" );
1085+ }
0 commit comments