feat: 左侧应用区添加批量编辑功能

This commit is contained in:
youdiansaodongxi 2023-12-07 10:59:26 +08:00 committed by hewenfei
parent 1c86a7a981
commit dd31bd9822
17 changed files with 113 additions and 74 deletions

View File

@ -2,6 +2,7 @@ import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.5
import org.ukui.menu.core 1.0
import org.ukui.quick.items 1.0 as UkuiItems
MouseArea {
id: control
@ -11,36 +12,20 @@ MouseArea {
when: control.activeFocus
PropertyChanges {
target: controlBase
borderColor: Palette.Highlight
borderColor: UkuiItems.Theme.Highlight
border.width: 2
}
}
ToolTip {
property bool isVisible: controlBase.isTextTruncated && control.containsMouse
id: tip
x: mouseX + 15
y: mouseY + 15
text: name
visible: controlBase.isTextTruncated && control.containsMouse
delay: 500
}
onPositionChanged: {
if (tip.isVisible) {
if (tip.visible) {
tip.hide();
} else {
tip.show(name);
}
}
}
StyleBackground {
property bool isTextTruncated: content.textTruncated
UkuiItems.StyleBackground {
id: controlBase
anchors.fill: parent
radius: 4
useStyleTransparent: false
paletteRole: Palette.Light
alpha: isSelect ? 1.00 : control.containsPress ? 0.82 : control.containsMouse ? 0.55 : 0.00
useStyleTransparency: false
paletteRole: UkuiItems.Theme.Text
alpha: isSelect ? 1.00 : control.containsPress ? 0.16 : control.containsMouse ? 0.08 : 0.00
ToolTip.visible: content.textTruncated && control.containsMouse
ToolTip.text: name
ToolTip.delay: 500
RowLayout {
anchors.fill: parent
@ -60,36 +45,34 @@ MouseArea {
Loader {
id: tag
property bool recentInsatlled: (recentInstall === undefined) ? false : recentInstall
property bool fixToTop: (toTop !== undefined) && (toTop !== 0)
visible: fixToTop || recentInsatlled
visible: mainWindow.editMode
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Layout.fillWidth: true
Layout.fillHeight: true
Layout.maximumWidth: visible ? 16 : 0
Layout.maximumWidth: visible ? 28 : 0
Layout.maximumHeight: width
Layout.rightMargin: visible ? 25 : 0
Layout.rightMargin: visible ? 4 : 0
Component {
id: tagImage
Image {
source: "image://appicon/ukui-fixed-symbolic"
}
}
id: editImage
UkuiItems.Button {
width: 28
height: 28
icon.width: 16
icon.height: 16
background.paletteRole: UkuiItems.Theme.Light
background.alpha: 1
activeFocusOnTab: false
Component {
id: tagPoint
Item {
StyleBackground {
anchors.centerIn: parent
width: 8; height: width
radius: width / 2
paletteRole: Palette.Highlight
useStyleTransparent: false
onClicked: {
appManager.changeFavoriteState(id, favorite);
}
background.radius: width / 2
icon.source: favorite ? "ukui-cancel-star-symbolic" : "non-starred-symbolic"
}
}
sourceComponent: tag.fixToTop ? tagImage : tag.recentInsatlled ? tagPoint : null
sourceComponent: mainWindow.editMode ? editImage : null
}
}
}

View File

@ -67,8 +67,7 @@ Item {
property string name: model.name
property string icon: model.icon
property string comment: model.comment // label tooltip
property int toTop: model.top
property bool recentInstall: model.recentInstall
property bool favorite: model.favorite
sourceComponent: {
if (type === DataType.Normal) {
return appItemComponent;

View File

@ -35,7 +35,7 @@ public:
Q_SIGNALS:
void appAdded(QList<DataEntity> apps);
void appUpdated(QList<DataEntity> apps);
void appUpdated(QList<DataEntity> apps, bool totalUpdate);
void appDeleted(QStringList idList);
void favoriteAppChanged();
void appDataBaseOpenFailed();
@ -56,7 +56,7 @@ public Q_SLOTS:
private:
void updateFavoriteApps();
void removeApps(QStringList& appIdList, QStringList &removedIdList);
void updateApps(const UkuiSearch::ApplicationInfoMap &infos, QList<DataEntity> &apps);
bool updateApps(const UkuiSearch::ApplicationInfoMap &infos, QList<DataEntity> &apps);
void updateAppsAll(const QStringList &infos, QList<DataEntity> &apps);
void appendApps(const QStringList &infos, QList<DataEntity> &apps);
void addInfoToApp(const UkuiSearch::ApplicationPropertyMap &info, DataEntity &app);
@ -211,11 +211,11 @@ void AppDataWorker::onAppUpdated(const UkuiSearch::ApplicationInfoMap &infos)
}
QList<DataEntity> apps;
updateApps(infos, apps);
bool totalUpdate = updateApps(infos, apps);
if (apps.isEmpty()) {
return;
}
Q_EMIT appUpdated(apps);
Q_EMIT appUpdated(apps, totalUpdate);
updateFavoriteApps();
}
@ -231,18 +231,18 @@ void AppDataWorker::onAppUpdatedAll(const QStringList &infos)
if (apps.isEmpty()) {
return;
}
Q_EMIT appUpdated(apps);
Q_EMIT appUpdated(apps, true);
updateFavoriteApps();
}
void AppDataWorker::updateApps(const UkuiSearch::ApplicationInfoMap &infos, QList<DataEntity> &apps)
bool AppDataWorker::updateApps(const UkuiSearch::ApplicationInfoMap &infos, QList<DataEntity> &apps)
{
QMutexLocker locker(&m_appManager->m_mutex);
if (infos.isEmpty()) {
return;
return false;
}
bool totalUpdate = false;
for (const QString &info : infos.keys()) {
if (m_appManager->m_normalApps.contains(info)) {
DataEntity &app = m_appManager->m_normalApps[info];
@ -271,9 +271,11 @@ void AppDataWorker::updateApps(const UkuiSearch::ApplicationInfoMap &infos, QLis
break;
case UkuiSearch::ApplicationProperty::Property::Category:
app.setCategory(infos.value(info).value(UkuiSearch::ApplicationProperty::Property::Category).toString());
totalUpdate = true;
break;
case UkuiSearch::ApplicationProperty::Property::FirstLetterAll:
app.setFirstLetter(infos.value(info).value(UkuiSearch::ApplicationProperty::Property::FirstLetterAll).toString());
totalUpdate = true;
break;
case UkuiSearch::ApplicationProperty::Property::InsertTime:
app.setInsertTime(infos.value(info).value(UkuiSearch::ApplicationProperty::Property::InsertTime).toString());
@ -288,6 +290,7 @@ void AppDataWorker::updateApps(const UkuiSearch::ApplicationInfoMap &infos, QLis
apps.append(app);
}
}
return totalUpdate;
}
void AppDataWorker::updateAppsAll(const QStringList &infos, QList<DataEntity> &apps)

View File

@ -52,7 +52,7 @@ public:
Q_SIGNALS:
void appAdded(QList<DataEntity> apps);
void appUpdated(QList<DataEntity> apps);
void appUpdated(QList<DataEntity> apps, bool totalUpdate);
void appDeleted(QStringList idList);
void appDataChanged();
void favoriteAppChanged();

View File

@ -49,7 +49,8 @@ public:
Reset = 0,
Append,
Prepend,
Insert
Insert,
Update
};
Q_ENUM(Mode)
};

View File

@ -52,6 +52,7 @@ AppCategoryPlugin::AppCategoryPlugin() : d(new AppCategoryPluginPrivate)
connect(AppDataManager::instance(), &AppDataManager::appAdded, this, &AppCategoryPlugin::onAppAdded);
connect(AppDataManager::instance(), &AppDataManager::appDeleted, this, &AppCategoryPlugin::onAppDeleted);
connect(AppDataManager::instance(), &AppDataManager::appUpdated, this, &AppCategoryPlugin::onAppUpdated);
}
AppCategoryPlugin::~AppCategoryPlugin()
@ -238,4 +239,14 @@ void AppCategoryPlugin::onAppDeleted(const QStringList& idList)
Q_EMIT labelChanged();
}
void AppCategoryPlugin::onAppUpdated(const QList<DataEntity> &apps, bool totalUpdate)
{
if (totalUpdate) {
reLoadApps();
updateData();
} else {
Q_EMIT dataChanged(apps.toVector(), DataUpdateMode::Update);
}
}
} // UkuiMenu

View File

@ -45,6 +45,7 @@ public:
private Q_SLOTS:
void onAppAdded(const QList<DataEntity>& apps);
void onAppDeleted(const QStringList& idList);
void onAppUpdated(const QList<DataEntity>& apps, bool totalUpdate);
private:
void reLoadApps();

View File

@ -88,10 +88,13 @@ void AppLetterSortPlugin::onAppDeleted(QStringList idList)
updateAppData();
}
void AppLetterSortPlugin::onAppUpdated(const QList<DataEntity> &apps)
void AppLetterSortPlugin::onAppUpdated(const QList<DataEntity> &apps, bool totalUpdate)
{
Q_UNUSED(apps);
updateAppData();
if (totalUpdate) {
updateAppData();
} else {
Q_EMIT dataChanged(apps.toVector(), DataUpdateMode::Update);
}
}
void AppLetterSortPlugin::updateAppData()

View File

@ -42,7 +42,7 @@ public:
private Q_SLOTS:
void onAppAdded(const QList<DataEntity>& apps);
void onAppDeleted(QStringList idList);
void onAppUpdated(const QList<DataEntity>& apps);
void onAppUpdated(const QList<DataEntity>& apps, bool totalUpdate);
private:
void updateAppData();

View File

@ -222,8 +222,7 @@ QHash<int, QByteArray> DataEntity::AppRoleNames()
names.insert(DataEntity::Name, "name");
names.insert(DataEntity::Comment, "comment");
names.insert(DataEntity::ExtraData, "extraData");
names.insert(DataEntity::Top, "top");
names.insert(DataEntity::RecentInstall, "recentInstall");
names.insert(DataEntity::Favorite, "favorite");
return names;
}

View File

@ -58,8 +58,7 @@ public:
Name,
Comment,
ExtraData,
Top,
RecentInstall
Favorite
};
DataEntity();
DataEntity(DataType::Type type, const QString& name, const QString& icon, const QString& comment, const QString& extraData);

View File

@ -60,16 +60,8 @@ QVariant AppModel::data(const QModelIndex &index, int role) const
return m_apps.at(i).comment();
case DataEntity::ExtraData:
return m_apps.at(i).extraData();
case DataEntity::Top:
if (DataProviderManager::instance()->activatedProvider() == "all") {
return m_apps.at(i).top();
}
return 0;
case DataEntity::RecentInstall:
if (DataProviderManager::instance()->activatedProvider() == "all") {
return m_apps.at(i).isRecentInstall();
}
return false;
case DataEntity::Favorite:
return m_apps.at(i).favorite() == 0 ? false : true;
default:
break;
}
@ -156,6 +148,10 @@ void AppModel::onPluginDataChanged(QVector<DataEntity> data, DataUpdateMode::Mod
insertData(data, static_cast<int>(index));
break;
}
case DataUpdateMode::Update: {
updateData(data);
break;
}
}
}
@ -197,6 +193,19 @@ void AppModel::insertData(QVector<DataEntity> &data, int index)
Q_EMIT endInsertRows();
}
void AppModel::updateData(QVector<DataEntity> &data)
{
for (const DataEntity &item : data) {
for (int i = 0; i < m_apps.length(); i++) {
if (item.id() == m_apps.at(i).id()) {
m_apps.replace(i, item);
Q_EMIT dataChanged(index(i, 0), index(i, 0));
break;
}
}
}
}
void AppModel::openMenu(const int &index, MenuInfo::Location location)
{
if (index < 0 || index >= m_apps.size()) {

View File

@ -61,6 +61,7 @@ private:
void appendData(QVector<DataEntity> &data);
void prependData(QVector<DataEntity> &data);
void insertData(QVector<DataEntity> &data, int index);
void updateData(QVector<DataEntity> &data);
private:
QVector<DataEntity> m_apps;

View File

@ -113,6 +113,15 @@ void AppManager::launchAppWithArguments(const QString &desktopFile, const QStrin
});
}
void AppManager::changeFavoriteState(const QString &desktopFilePath, bool isFavorite)
{
if (isFavorite) {
Q_EMIT AppDataManager::instance()->fixToFavoriteSignal(desktopFilePath, 0);
} else {
Q_EMIT AppDataManager::instance()->fixToFavoriteSignal(desktopFilePath, 1);
}
}
QString AppManager::parseDesktopFile(const QString &desktopFilePath)
{
// TODO: try QSettings?

View File

@ -36,6 +36,7 @@ public:
Q_INVOKABLE void launchApp(const QString &desktopFilePath);
Q_INVOKABLE void launchBinaryApp(const QString &app, const QString &args = QString());
Q_INVOKABLE void launchAppWithArguments(const QString &desktopFile, const QStringList &args, const QString &applicationName);
Q_INVOKABLE void changeFavoriteState(const QString &desktopFilePath, bool isFavorite);
private:
explicit AppManager(QObject *parent = nullptr);

View File

@ -550,4 +550,19 @@ int MenuWindow::panelPos() const
return m_geometryHelper->getPanelPos();
}
bool MenuWindow::editMode() const
{
return m_editMode;
}
void MenuWindow::setEditMode(bool mode)
{
if (mode == m_editMode) {
return;
}
m_editMode = mode;
Q_EMIT editModeChanged();
}
} // UkuiMenu

View File

@ -107,6 +107,7 @@ class MenuWindow : public QQuickView
Q_OBJECT
Q_PROPERTY(bool isFullScreen READ isFullScreen WRITE setFullScreen NOTIFY fullScreenChanged)
Q_PROPERTY(bool effectEnabled READ effectEnabled NOTIFY effectEnabledChanged)
Q_PROPERTY(bool editMode READ editMode WRITE setEditMode NOTIFY editModeChanged)
Q_PROPERTY(double transparency READ transparency NOTIFY transparencyChanged)
Q_PROPERTY(int panelPos READ panelPos NOTIFY panelPosChanged)
@ -119,6 +120,8 @@ public:
double transparency() const;
void setFullScreen(bool isFullScreen);
int panelPos() const;
bool editMode() const;
void setEditMode(bool mode);
Q_INVOKABLE void changeWindowBlurRegion(int x, int y, int width, int height);
Q_INVOKABLE QRect normalScreenSize();
@ -132,6 +135,7 @@ Q_SIGNALS:
void beforeFullScreenChanged();
void beforeFullScreenExited();
void panelPosChanged();
void editModeChanged();
protected:
void exposeEvent(QExposeEvent *event) override;
@ -144,6 +148,7 @@ private:
void updateGeometry();
private:
bool m_editMode {false};
bool m_isFullScreen{false};
WindowGeometryHelper *m_geometryHelper{nullptr};
};