Skip to content

Commit ecc0629

Browse files
committed
refactor: add and and export group-related APIs to QML
添加和暴露组相关 API 给 QML,供后续使用。 Log:
1 parent 75758b2 commit ecc0629

File tree

6 files changed

+256
-18
lines changed

6 files changed

+256
-18
lines changed

applets/dde-apps/amappitemmodel.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,15 @@ AMAppItemModel::AMAppItemModel(QObject *parent)
6161
}
6262
});
6363
}
64-
}
64+
65+
AMAppItem * AMAppItemModel::appItem(const QString &id)
66+
{
67+
for (int i = 0; i < rowCount(); i++) {
68+
auto app = item(i);
69+
if (app->data(AppItemModel::DesktopIdRole).toString() == id)
70+
return static_cast<AMAppItem *>(app);
71+
}
72+
return nullptr;
73+
}
74+
75+
}

applets/dde-apps/amappitemmodel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99

1010
namespace apps
1111
{
12+
class AMAppItem;
1213
class AMAppItemModel : public AppItemModel
1314
{
1415
Q_OBJECT
1516

1617
public:
1718
explicit AMAppItemModel(QObject *parent = nullptr);
1819

20+
AMAppItem * appItem(const QString &id);
21+
1922
private:
2023
ObjectManager *m_manager;
2124
};

applets/dde-apps/appgroup.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ AppGroup::AppGroup(const QString &groupId, const QString &name, const QList<QStr
2020
setItemsPerPage(m_itemsPage->maxItemCountPerPage());
2121
setAppName(m_itemsPage->name());
2222
// folder id is a part of its groupId: "internal/folder/{folderId}"
23-
setFolderId(groupId.section('/', -1).toInt());
23+
setFolderId(parseGroupId(groupId));
2424

2525
for (const QStringList &items : appIDs) {
2626
m_itemsPage->appendPage(items);
@@ -47,6 +47,23 @@ ItemsPage *AppGroup::itemsPage()
4747
return m_itemsPage;
4848
}
4949

50+
bool AppGroup::idIsFolder(const QString & id)
51+
{
52+
return id.startsWith(QStringLiteral("internal/folder/"));
53+
}
54+
55+
QString AppGroup::groupIdFromNumber(int groupId)
56+
{
57+
return QStringLiteral("internal/folder/%1").arg(groupId);
58+
}
59+
60+
int AppGroup::parseGroupId(const QString & id)
61+
{
62+
using namespace std::string_view_literals;
63+
constexpr size_t len = "internal/folder/"sv.size();
64+
return QStringView{id}.mid(len + 1).toInt();
65+
}
66+
5067
void AppGroup::setItemsPerPage(int number)
5168
{
5269
return setData(number, AppGroupManager::GroupItemsPerPageRole);

applets/dde-apps/appgroup.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ class AppGroup : public AppItem
1818
QList<QStringList> pages() const;
1919
ItemsPage * itemsPage();
2020

21+
static bool idIsFolder(const QString & id);
22+
static QString groupIdFromNumber(int groupId);
23+
static int parseGroupId(const QString & id);
24+
2125
private:
2226
void setItemsPerPage(int number);
2327
void setFolderId(int folderId);

applets/dde-apps/appgroupmanager.cpp

Lines changed: 184 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "appgroup.h"
77
#include "itemspage.h"
88
#include "amappitemmodel.h"
9+
#include "amappitem.h"
910

1011
#define TOPLEVEL_FOLDERID 0
1112

@@ -20,6 +21,7 @@ AppGroupManager::AppGroupManager(AMAppItemModel * referenceModel, QObject *paren
2021
m_dumpTimer->setSingleShot(true);
2122
m_dumpTimer->setInterval(1000);
2223

24+
launchpadArrangementConfigMigration();
2325
loadAppGroupInfo();
2426

2527
connect(m_referenceModel, &AMAppItemModel::rowsInserted, this, [this](){
@@ -49,7 +51,7 @@ QVariant AppGroupManager::data(const QModelIndex &index, int role) const
4951
}
5052

5153
// Find the item's location. If folderId is -1, search all folders.
52-
std::tuple<int, int, int> AppGroupManager::findItem(const QString &appId, int folderId)
54+
ItemPosition AppGroupManager::findItem(const QString &appId, int folderId)
5355
{
5456
int page, idx;
5557

@@ -60,11 +62,11 @@ std::tuple<int, int, int> AppGroupManager::findItem(const QString &appId, int fo
6062
}
6163
std::tie(page, idx) = group->itemsPage()->findItem(appId);
6264
if (page != -1) {
63-
return std::make_tuple(group->folderId(), page, idx);
65+
return ItemPosition(group->folderId(), page, idx);
6466
}
6567
}
6668

67-
return std::make_tuple(-1, -1, -1);
69+
return ItemPosition();
6870
}
6971

7072
void AppGroupManager::appendItemToGroup(const QString &appId, int groupId)
@@ -112,6 +114,115 @@ AppGroup * AppGroupManager::group(QModelIndex idx)
112114
return group;
113115
}
114116

117+
ItemsPage * AppGroupManager::groupPages(int groupId)
118+
{
119+
AppGroup * folder = group(groupId);
120+
if (!folder) return nullptr;
121+
return folder->itemsPage();
122+
}
123+
124+
void AppGroupManager::bringToFromt(const QString & id)
125+
{
126+
const ItemPosition origPos = findItem(id);
127+
128+
// can only bring top-level item to front
129+
Q_ASSERT(origPos.group() != TOPLEVEL_FOLDERID);
130+
if (origPos.group() != TOPLEVEL_FOLDERID) {
131+
return;
132+
}
133+
134+
// already at front
135+
if (origPos.page() == 0 && origPos.pos() == 0) {
136+
return;
137+
}
138+
139+
auto * topLevel = groupPages(0);
140+
topLevel->moveItemPosition(origPos.page(), origPos.pos(), 0, 0, false);
141+
142+
saveAppGroupInfo();
143+
144+
// TODO: emit signal to refresh the view
145+
}
146+
147+
void AppGroupManager::commitRearrangeOperation(const QString & dragId, const QString & dropId, DndOperation operation, int pageHint)
148+
{
149+
if (dragId == dropId) return;
150+
151+
const ItemPosition dragOrigPos = findItem(dragId);
152+
const ItemPosition dropOrigPos = findItem(dropId);
153+
154+
Q_ASSERT(dragOrigPos.group() != -1);
155+
if (dragOrigPos.group() == -1) {
156+
qWarning() << "Cannot found" << dragId << "in current item arrangement.";
157+
return;
158+
}
159+
160+
if (operation != DndOperation::DndJoin) {
161+
// move to dropId's front or back
162+
if (dragOrigPos.group() == dropOrigPos.group()) {
163+
// same folder item re-arrangement
164+
ItemsPage * folder = groupPages(dropOrigPos.group());
165+
folder->moveItemPosition(dragOrigPos.page(), dragOrigPos.pos(), dropOrigPos.page(), dropOrigPos.pos(), operation == DndOperation::DndAppend);
166+
} else {
167+
// different folder item arrangement
168+
ItemsPage * srcFolder = groupPages(dragOrigPos.group());
169+
ItemsPage * dstFolder = groupPages(dropOrigPos.group());
170+
srcFolder->removeItem(dragId);
171+
if (srcFolder->pageCount() == 0 && srcFolder != dstFolder) {
172+
removeGroup(dragOrigPos.group());
173+
}
174+
dstFolder->insertItem(dropId, dropOrigPos.page(), dropOrigPos.pos());
175+
}
176+
} else {
177+
if (AppGroup::idIsFolder(dragId) && dropId != "internal/folders/0") return; // cannot drag folder onto something
178+
if (dropOrigPos.group() != TOPLEVEL_FOLDERID && dropId != "internal/folders/0") return; // folder inside folder is not allowed
179+
180+
// the source item will be inside a new folder anyway.
181+
ItemsPage * srcFolder = groupPages(dragOrigPos.group());
182+
183+
if (AppGroup::idIsFolder(dropId)) {
184+
// drop into existing folder
185+
ItemsPage * dstFolder = groupPages(AppGroup::parseGroupId(dropId));
186+
const int fromPage = dragOrigPos.page();
187+
const int toPage = pageHint;
188+
if (srcFolder == dstFolder) {
189+
if (srcFolder->pageCount() == 1 ||
190+
(fromPage == toPage && srcFolder->itemCount(fromPage) == 1)) { // dnd the only item to the same page
191+
return;
192+
}
193+
}
194+
195+
// hold the empty page avoid access out of page range!
196+
srcFolder->removeItem(dragId, false);
197+
if (srcFolder->itemCount() == 0 && srcFolder != dstFolder) {
198+
removeGroup(dragOrigPos.group());
199+
}
200+
dstFolder->insertItemToPage(dragId, toPage);
201+
202+
// clear empty page
203+
srcFolder->removeEmptyPages();
204+
} else {
205+
srcFolder->removeItem(dragId);
206+
// we need the app info for the new folder name...
207+
AMAppItem * item = m_referenceModel->appItem(dropId);
208+
AppItemModel::DDECategories dropCategories = item ? item->ddeCategories() : AppItemModel::Others;
209+
// make a new folder, move two items into the folder
210+
QString dstFolderId = assignGroupId();
211+
appendGroup(dstFolderId, "internal/category/" + QString::number(dropCategories), {{dragId, dropId}});
212+
if (srcFolder->pageCount() == 0 && dragOrigPos.group() != 0) {
213+
removeGroup(dragOrigPos.group());
214+
}
215+
auto * topLevel = groupPages(0);
216+
topLevel->insertItem(dstFolderId, dropOrigPos.page(), dropOrigPos.pos());
217+
topLevel->removeItem(dropId);
218+
}
219+
}
220+
221+
saveAppGroupInfo();
222+
223+
// TODO: emit signal to refresh the view
224+
}
225+
115226
QVariantList AppGroupManager::fromListOfStringList(const QList<QStringList> & list)
116227
{
117228
QVariantList data;
@@ -145,9 +256,8 @@ void AppGroupManager::onReferenceModelChanged()
145256
const QString & desktopId = m_referenceModel->data(m_referenceModel->index(i, 0), AppItemModel::DesktopIdRole).toString();
146257
appSet.insert(desktopId);
147258
// add all existing ones if they are not already in
148-
int folder, page, idx;
149-
std::tie(folder, std::ignore, std::ignore) = findItem(desktopId);
150-
if (folder == -1) {
259+
ItemPosition itemPos = findItem(desktopId);
260+
if (itemPos.group() == -1) {
151261
appendItemToGroup(desktopId, TOPLEVEL_FOLDERID);
152262
}
153263
}
@@ -169,6 +279,52 @@ void AppGroupManager::onReferenceModelChanged()
169279
// TODO: save item arrangement to user data?
170280
}
171281

282+
void AppGroupManager::launchpadArrangementConfigMigration()
283+
{
284+
const QString arrangementSettingBasePath(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
285+
const QString arrangementSettingPath(QDir(arrangementSettingBasePath).absoluteFilePath("deepin/dde-launchpad/item-arrangement.ini"));
286+
if (!QFile::exists(arrangementSettingPath)) return;
287+
QSettings itemArrangementSettings(arrangementSettingPath, QSettings::NativeFormat);
288+
289+
itemArrangementSettings.beginGroup("fullscreen");
290+
const QStringList folderGroups(itemArrangementSettings.childGroups());
291+
292+
QVariantList list;
293+
294+
for (const QString & groupName : folderGroups) {
295+
itemArrangementSettings.beginGroup(groupName);
296+
QString folderName = itemArrangementSettings.value("name", QString()).toString();
297+
int pageCount = itemArrangementSettings.value("pageCount", 0).toInt();
298+
bool isTopLevel = groupName == "toplevel";
299+
300+
QVariantMap valueMap;
301+
valueMap.insert("name", folderName);
302+
valueMap.insert("groupId", groupName.toInt());
303+
304+
QList<QStringList> pages;
305+
for (int i = 0; i < pageCount; i++) {
306+
QStringList items = itemArrangementSettings.value(QString::asprintf("pageItems/%d", i)).toStringList();
307+
// check if items have ".desktop" suffix, and remove the suffix
308+
std::transform(items.begin(), items.end(), items.begin(), [](QString &item) {
309+
if (item.endsWith(".desktop")) {
310+
item.remove(".desktop");
311+
}
312+
return item;
313+
});
314+
pages.append(items);
315+
}
316+
317+
valueMap.insert("appItems", fromListOfStringList(pages));
318+
list.append(valueMap);
319+
320+
itemArrangementSettings.endGroup();
321+
}
322+
323+
m_config->setValue("Groups", list);
324+
325+
// TODO: delete the old configuration file
326+
}
327+
172328
void AppGroupManager::loadAppGroupInfo()
173329
{
174330
auto groups = m_config->value("Groups").toList();
@@ -188,15 +344,13 @@ void AppGroupManager::loadAppGroupInfo()
188344
if (groupId.isEmpty()) {
189345
groupId = assignGroupId();
190346
}
191-
auto p = new AppGroup(groupId, name, items);
192-
appendRow(p);
347+
auto p = appendGroup(groupId, name, items);
193348
}
194349

195350
// always ensure top-level group exists
196351
if (rowCount() == 0) {
197-
auto p = new AppGroup(assignGroupId(), "Top Level", {});
352+
auto p = appendGroup(assignGroupId(), "Top Level", {});
198353
Q_ASSERT(p->folderId() == TOPLEVEL_FOLDERID);
199-
appendRow(p);
200354
}
201355
}
202356

@@ -231,4 +385,24 @@ QString AppGroupManager::assignGroupId() const
231385
return QString("internal/group/%1").arg(idNumber);
232386
}
233387

388+
AppGroup * AppGroupManager::appendGroup(int groupId, QString groupName, const QList<QStringList> &appItemIDs)
389+
{
390+
Q_ASSERT(!groupIndexById(groupId).isValid());
391+
return appendGroup(AppGroup::groupIdFromNumber(groupId), groupName, appItemIDs);
392+
}
393+
394+
AppGroup * AppGroupManager::appendGroup(QString groupId, QString groupName, const QList<QStringList> &appItemIDs)
395+
{
396+
auto p = new AppGroup(groupId, groupName, appItemIDs);
397+
appendRow(p);
398+
return p;
399+
}
400+
401+
void AppGroupManager::removeGroup(int groupId)
402+
{
403+
auto groupIndex = groupIndexById(groupId);
404+
Q_ASSERT(groupIndex.isValid());
405+
removeRow(groupIndex.row());
406+
}
407+
234408
}

0 commit comments

Comments
 (0)