diff --git a/gui/page/spkpagesettings.cpp b/gui/page/spkpagesettings.cpp
index a7ef719..1e48aa7 100644
--- a/gui/page/spkpagesettings.cpp
+++ b/gui/page/spkpagesettings.cpp
@@ -19,6 +19,9 @@ namespace SpkUi
mMainArea->setWidget(mSettingsWidget);
mMainArea->setWidgetResizable(true);
+ CFG->BindField("url/repo", &this->mRepoListUrl,
+ "https://d.store.deepinos.org.cn/store/server.list");
+
SetupUi();
}
@@ -50,20 +53,21 @@ namespace SpkUi
ui->edtDownloadPath->setText(CFG->ReadField("dirs/download", "").toString());
ui->edtDownloadServers->setPlainText(CFG->ReadField("download/servers", "").toString());
ui->edtQssPath->setText(CFG->ReadField("internal/qss_path", "").toString());
+ ui->edtRepoListUrl->setText(CFG->ReadField("url/repo", "").toString());
}
void SpkPageSettings::SaveConfiguration()
{
auto ui = mSettingsUi;
- auto settings = CFG;
CFG->SetSettings("resource/concurrent", ui->spnConcurrentResDownloads->value());
- assert(CFG->SetField("url/api", ui->edtApiUrl->text()));
- assert(CFG->SetField("url/res", ui->edtResourceUrl->text()));
+ CFG->SetField("url/api", ui->edtApiUrl->text());
+ CFG->SetField("url/res", ui->edtResourceUrl->text());
CFG->SetSettings("dirs/cache", ui->edtResourceCachePath->text());
- assert(CFG->SetField("dirs/download", ui->edtDownloadPath->text()));
- assert(CFG->SetField("download/servers", ui->edtDownloadServers->toPlainText()));
+ CFG->SetField("dirs/download", ui->edtDownloadPath->text());
+ CFG->SetField("download/servers", ui->edtDownloadServers->toPlainText());
CFG->SetSettings("internal/qss_path", ui->edtQssPath->text());
+ CFG->SetField("url/repo", ui->edtRepoListUrl->text());
}
void SpkPageSettings::Activated()
diff --git a/gui/page/spkpageuitest.cpp b/gui/page/spkpageuitest.cpp
index be8554e..12db872 100644
--- a/gui/page/spkpageuitest.cpp
+++ b/gui/page/spkpageuitest.cpp
@@ -83,7 +83,7 @@ SpkUi::SpkPageUiTest::SpkPageUiTest(QWidget *parent) : QSplitter(parent)
ShowPkgmgr = new QPushButton(this);
ShowPkgmgr->setText("Show Install Menu");
- connect(ShowPkgmgr, &QPushButton::clicked, [](){ SpkPkgMgrBase::Instance()->ExecuteInstallation("", 0); });
+ connect(ShowPkgmgr, &QPushButton::clicked, [=](){ SpkPkgMgrBase::Instance()->ExecuteInstallation(PopupText->text(), 0); });
SlideV = new QSlider(this);
SlideV->setObjectName("spk_pg_qsstest_slider_v");
diff --git a/gui/page/ui/settings.ui b/gui/page/ui/settings.ui
index 6aa46d2..725e4da 100644
--- a/gui/page/ui/settings.ui
+++ b/gui/page/ui/settings.ui
@@ -6,8 +6,8 @@
0
0
- 501
- 699
+ 581
+ 896
@@ -61,41 +61,17 @@
-
-
-
-
-
-
- 0
- 0
-
-
-
-
- 0
- 80
-
-
-
-
- 16777215
- 150
-
-
-
-
- 100
- 100
-
-
-
- download/servers
+
-
+
+
+ Store API URL
- -
-
+
-
+
- Light/dark theme
+ Store resource URL
@@ -106,75 +82,6 @@
- -
-
-
- true
-
-
- gui/theme
-
-
-
-
- Auto
-
-
- -
-
- Always Light
-
-
- -
-
- Always Dark
-
-
-
-
- -
-
-
- Store API URL
-
-
-
- -
-
-
- APT Repository
-
-
-
- -
-
-
- url/api
-
-
-
- -
-
-
- Server addresses are separated with two semicolons (;;).
-
-
- 1
-
-
- Download servers
-
-
- Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
-
-
-
- -
-
-
- dirs/cache
-
-
-
-
@@ -182,23 +89,10 @@
- -
-
-
-
-
-
- -1
-
+
-
+
- Download path
-
-
-
- -
-
-
- Store resource URL
+ APT Repository
@@ -255,6 +149,122 @@
+ -
+
+
+ Light/dark theme
+
+
+
+ -
+
+
+ dirs/cache
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 80
+
+
+
+
+ 16777215
+ 150
+
+
+
+
+ 100
+ 100
+
+
+
+ download/servers
+
+
+
+ -
+
+
+ true
+
+
+ gui/theme
+
+
-
+
+ Auto
+
+
+ -
+
+ Always Light
+
+
+ -
+
+ Always Dark
+
+
+
+
+ -
+
+
+
+
+
+ -1
+
+
+ Download path
+
+
+
+ -
+
+
+ Server addresses are separated with two semicolons (;;).
+
+
+ 1
+
+
+ Download servers
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
+
+
+
+ -
+
+
+ url/api
+
+
+
+ -
+
+
+ APT Repository Source
+
+
+
+ -
+
+
-
diff --git a/inc/page/spkpagesettings.h b/inc/page/spkpagesettings.h
index 7485e46..af67861 100644
--- a/inc/page/spkpagesettings.h
+++ b/inc/page/spkpagesettings.h
@@ -22,11 +22,15 @@ namespace SpkUi
virtual void Activated() override;
+ private slots:
+
private:
QScrollArea *mMainArea;
QVBoxLayout *mMainLay;
QWidget *mSettingsWidget;
Ui::SpkUiSettings *mSettingsUi;
+ QString mRepoListUrl;
+
};
}
diff --git a/inc/pkgs/spkpkgmgrapt.h b/inc/pkgs/spkpkgmgrapt.h
index d5576e8..68d16a2 100644
--- a/inc/pkgs/spkpkgmgrapt.h
+++ b/inc/pkgs/spkpkgmgrapt.h
@@ -2,8 +2,9 @@
#pragma once
#include "spkpkgmgrbase.h"
+#include
-class SpkPkgMgrApt : public SpkPkgMgrBase
+class SpkPkgMgrApt final : public SpkPkgMgrBase
{
Q_OBJECT
@@ -21,10 +22,15 @@ class SpkPkgMgrApt : public SpkPkgMgrBase
private:
void CheckInstallerAvailability();
+ private slots:
+ void InstallerExited(int, QProcess::ExitStatus);
+
private:
QAction *mActAptitudeTerm,
*mActAptTerm,
*mActGdebi,
*mActDeepinPkgInst;
+ QProcess mInstaller;
+
};
diff --git a/inc/pkgs/spkpkgmgrbase.h b/inc/pkgs/spkpkgmgrbase.h
index 71d263d..d688cb7 100644
--- a/inc/pkgs/spkpkgmgrbase.h
+++ b/inc/pkgs/spkpkgmgrbase.h
@@ -20,8 +20,10 @@ class SpkPkgMgrBase : public QObject
Q_ASSERT(mInstance == nullptr);
mInstance = this;
+ mActOpen = new QAction(tr("Open package"), this);
mActOpenDir = new QAction(tr("Open containing directory"), this);
mMenu = new QMenu(tr("Package Actions"));
+ mMenu->addAction(mActOpen);
mMenu->addAction(mActOpenDir);
mMenu->setAttribute(Qt::WA_TranslucentBackground);
mMenu->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint);
@@ -47,9 +49,12 @@ class SpkPkgMgrBase : public QObject
*/
virtual PkgInstallResult ExecuteInstallation(QString pkgPath, int entryId)
{
+ Q_UNUSED(entryId);
auto item = mMenu->exec(QCursor::pos());
if(item == mActOpenDir)
QDesktopServices::openUrl(QUrl(SpkUtils::CutPath(pkgPath)));
+ else if(item == mActOpen)
+ QDesktopServices::openUrl(QUrl(pkgPath));
return Ignored;
}
@@ -60,7 +65,11 @@ class SpkPkgMgrBase : public QObject
*/
virtual PkgInstallResult CliInstall(QString pkgPath)
{
- // TODO: print message
+ qInfo() << tr("Spark Store cannot install your package because no supported "
+ "packaging system has been found. You shall decide what you "
+ "want to do with the downloaded package.\n\n"
+ "File path:")
+ << pkgPath;
return Ignored;
}
@@ -68,15 +77,15 @@ class SpkPkgMgrBase : public QObject
static SpkPkgMgrBase *Instance() { return mInstance; }
protected:
- QAction *mActOpenDir, *mActDesc;
+ QAction *mActOpenDir, *mActOpen, *mActDesc;
QMenu *mMenu;
+ int mCurrentItemId; ///< ID of currently installing download item
private:
static SpkPkgMgrBase *mInstance;
signals:
- void InstallationEnded(int entryId,
- SpkPkgMgrBase::PkgInstallResult success,
- QString message);
-
+ void ReportInstallResult(int entryId,
+ SpkPkgMgrBase::PkgInstallResult result,
+ int exitCode);
};
diff --git a/inc/pkgs/spkpkgmgrpacman.h b/inc/pkgs/spkpkgmgrpacman.h
index 3bc689d..e648daf 100644
--- a/inc/pkgs/spkpkgmgrpacman.h
+++ b/inc/pkgs/spkpkgmgrpacman.h
@@ -3,7 +3,7 @@
#include "spkpkgmgrbase.h"
-class SpkPkgMgrPacman : public SpkPkgMgrBase
+class SpkPkgMgrPacman final : public SpkPkgMgrBase
{
Q_OBJECT
diff --git a/inc/spkutils.h b/inc/spkutils.h
index ef6c3cd..c18bb81 100644
--- a/inc/spkutils.h
+++ b/inc/spkutils.h
@@ -29,5 +29,7 @@ namespace SpkUtils
QString BytesToSize(size_t s, int prec = 2);
bool EnsureDirExists(QString path);
- void FillWidget(QWidget* widget, QVariant val);
+ bool FindViableTerminal();
+
+ extern QPair AvailableTerminal;
}
diff --git a/resource/default_config b/resource/default_config
index 3406ffb..4422b74 100644
--- a/resource/default_config
+++ b/resource/default_config
@@ -2,6 +2,7 @@
[url]
api=https://store.deepinos.org/api/
res=http://img.store.deepinos.org.cn/
+repo=https://d.store.deepinos.org.cn/store/server.list
[dirs]
cache="*/.cache/spark-store/res/"
diff --git a/src/pkgs/spkpkgmgrapt.cpp b/src/pkgs/spkpkgmgrapt.cpp
index a2d648e..85d05d7 100644
--- a/src/pkgs/spkpkgmgrapt.cpp
+++ b/src/pkgs/spkpkgmgrapt.cpp
@@ -13,12 +13,16 @@ SpkPkgMgrApt::SpkPkgMgrApt(QObject *parent) :
mActGdebi = new QAction(tr("GDebi"), this);
mActDeepinPkgInst = new QAction(tr("Deepin Package Installer"), this);
- mMenu->addAction(mActAptTerm);
- mMenu->addAction(mActAptitudeTerm);
- mMenu->addAction(mActGdebi);
- mMenu->addAction(mActDeepinPkgInst);
+ mMenu->insertAction(mActOpen, mActAptTerm);
+ mMenu->insertAction(mActOpen, mActAptitudeTerm);
+ mMenu->insertAction(mActOpen, mActGdebi);
+ mMenu->insertAction(mActOpen, mActDeepinPkgInst);
+ mMenu->insertSeparator(mActOpen);
mMenu->addSeparator();
mMenu->addAction(mActDesc);
+
+ connect(&mInstaller, QOverload::of(&QProcess::finished),
+ this, &SpkPkgMgrApt::InstallerExited);
}
bool SpkPkgMgrApt::DetectRequirements()
@@ -30,8 +34,63 @@ bool SpkPkgMgrApt::DetectRequirements()
SpkPkgMgrBase::PkgInstallResult
SpkPkgMgrApt::ExecuteInstallation(QString pkgPath, int entryId)
{
+ static auto prompt = tr("\n\n================================\n"
+ "Press Enter to continue.");
+
+ if(mInstaller.state() == QProcess::Running)
+ {
+ sNotify(tr("Please wait till the current installation finishes."));
+ return Ignored;
+ }
+ mCurrentItemId = entryId;
CheckInstallerAvailability();
- return SpkPkgMgrBase::ExecuteInstallation(pkgPath, entryId);
+ auto item = mMenu->exec(QCursor::pos());
+ if(item == mActOpenDir)
+ {
+ QDesktopServices::openUrl(QUrl(SpkUtils::CutPath(pkgPath)));
+ return Ignored;
+ }
+ else if(item == mActOpen)
+ {
+ QDesktopServices::openUrl(QUrl(pkgPath));
+ return Ignored;
+ }
+ else if(item == mActAptTerm)
+ {
+ mInstaller.setProgram(SpkUtils::AvailableTerminal.first);
+ mInstaller.setArguments({ SpkUtils::AvailableTerminal.second, "pkexec",
+ "bash", "-c",
+ QString("apt install '%1'; R=$?; read -p '%2'; exit $R")
+ .arg(pkgPath, prompt)});
+ mInstaller.start();
+ }
+ else if(item == mActAptitudeTerm)
+ {
+ mInstaller.setProgram(SpkUtils::AvailableTerminal.first);
+ mInstaller.setArguments({ SpkUtils::AvailableTerminal.second, "pkexec",
+ "bash", "-c",
+ QString("aptitude install '%1'; R=$?; read -p '%2'; exit $R")
+ .arg(pkgPath, prompt)});
+ mInstaller.start();
+ }
+ else if(item == mActGdebi)
+ {
+ mInstaller.setProgram("pkexec");
+ mInstaller.setArguments({ "gdebi", "-n", pkgPath });
+ mInstaller.start();
+ }
+ else if(item == mActDeepinPkgInst)
+ {
+ mInstaller.setProgram("deepin-deb-installer");
+ mInstaller.setArguments({ pkgPath });
+ mInstaller.start();
+ }
+ else
+ return Ignored;
+
+ // Startup is very quick and we can risk blocking here a bit
+ mInstaller.waitForStarted();
+ return mInstaller.state() == QProcess::Running ? Succeeded : Failed;
}
void SpkPkgMgrApt::CheckInstallerAvailability()
@@ -41,4 +100,12 @@ void SpkPkgMgrApt::CheckInstallerAvailability()
mActDeepinPkgInst->setEnabled(QFile::exists("/usr/bin/deepin-deb-installer"));
}
+void SpkPkgMgrApt::InstallerExited(int exitCode, QProcess::ExitStatus status)
+{
+ if(status == QProcess::NormalExit)
+ emit ReportInstallResult(mCurrentItemId, Succeeded, exitCode);
+ else
+ emit ReportInstallResult(mCurrentItemId, Failed, exitCode);
+}
+
diff --git a/src/spkstore.cpp b/src/spkstore.cpp
index 677b843..95cb9f3 100644
--- a/src/spkstore.cpp
+++ b/src/spkstore.cpp
@@ -8,6 +8,7 @@
#include "dtk/spkdtkplugin.h"
#include "gitver.h"
#include "spkmainwindow.h"
+#include "spkmsgbox.h"
#include "spkpopup.h"
#include "spkstore.h"
#include "spkutils.h"
@@ -75,6 +76,13 @@ SpkStore::SpkStore(bool aCli, QString &aLogPath)
mMainWindow = new SpkMainWindow;
SpkUi::Popup = new SpkUi::SpkPopup(mMainWindow);
+ if(!SpkUtils::FindViableTerminal())
+ SpkMsgBox::StaticExec(tr("Cannot find a terminal emulator on the system.\n"
+ "You will have to specify it in settings later in order\n"
+ "to use terminal for program output."),
+ tr("No Terminals Found"),
+ QMessageBox::Warning);
+
mMainWindow->show();
}
diff --git a/src/spkutils.cpp b/src/spkutils.cpp
index 47849d4..e877147 100644
--- a/src/spkutils.cpp
+++ b/src/spkutils.cpp
@@ -4,8 +4,11 @@
#include
#include
#include
+#include
#include "spkutils.h"
+QPair SpkUtils::AvailableTerminal = {"", ""};
+
void SpkUtils::VerifySingleRequest(QPointer aReply)
{
if(aReply.isNull())
@@ -112,7 +115,41 @@ bool SpkUtils::EnsureDirExists(QString path)
return true;
}
-void SpkUtils::FillWidget(QWidget *widget, QVariant val)
-{
+// From https://github.com/qt-creator/qt-creator/blob/18f1be58e7937af4f538fc0c47f660cf8c60bda2/src/libs/utils/consoleprocess.cpp
+using StrStrPair = QPair;
+Q_GLOBAL_STATIC_WITH_ARGS(QList, KnownTerminals,
+ ({
+ {"x-terminal-emulator", "-e"},
+ {"xdg-terminal ", ""},
+ {"xterm", "-e"},
+ {"aterm", "-e"},
+ {"Eterm", "-e"},
+ {"rxvt", "-e"},
+ {"urxvt", "-e"},
+ {"xfce4-terminal", "-x"},
+ {"konsole", "-e "},
+ {"gnome-terminal", "--"}
+ }));
+bool SpkUtils::FindViableTerminal()
+{
+ auto dirs = qgetenv("PATH").split(':');
+ QList searchDirs;
+
+ for(auto &i : dirs)
+ searchDirs.append(QDir(i));
+
+ for(auto &i : *KnownTerminals)
+ {
+ for(auto &j : searchDirs)
+ {
+ if(j.exists(i.first))
+ {
+ AvailableTerminal = i;
+ return true;
+ }
+ }
+ }
+
+ return false;
}