parent
10684c22a0
commit
8e39d761dc
|
@ -28,21 +28,34 @@ add_executable(
|
|||
main.cpp
|
||||
cachecleaner.cpp cachecleaner.h
|
||||
directorieswatcher.cpp directorieswatcher.h
|
||||
figmadecoratormodel.cpp figmadecoratormodel.h
|
||||
figmaio.cpp figmaio.h
|
||||
figmalinks.cpp figmalinks.h
|
||||
figmalinksmodel.cpp figmalinksmodel.h
|
||||
figmalinkssource.cpp figmalinkssource.h
|
||||
modelutils.cpp modelutils.h
|
||||
sectionsdecoratormodel.cpp sectionsdecoratormodel.h
|
||||
${QML_FILES} main.qml PagesModel.qml
|
||||
${JS_FILES}
|
||||
figma.json
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE QML_IMPORT_ROOT="${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick Qt5::QuickControls2 SortFilterProxyModel)
|
||||
|
||||
enable_testing()
|
||||
add_executable(SectionsDecoratorModelTest tests/tst_SectionsDecoratorModel.cpp sectionsdecoratormodel.cpp)
|
||||
add_executable(SectionsDecoratorModelTest tests/tst_SectionsDecoratorModel.cpp sectionsdecoratormodel.cpp modelutils.cpp)
|
||||
add_test(NAME SectionsDecoratorModelTest COMMAND SectionsDecoratorModelTest)
|
||||
target_link_libraries(SectionsDecoratorModelTest PRIVATE Qt5::Test)
|
||||
|
||||
add_executable(FigmaDecoratorModelTest tests/tst_FigmaDecoratorModel.cpp figmadecoratormodel.cpp figmalinkssource.cpp
|
||||
figmalinks.cpp figmaio.cpp modelutils.cpp figmalinksmodel.cpp)
|
||||
add_test(NAME FigmaModelTest COMMAND FigmaModelTest)
|
||||
target_link_libraries(FigmaDecoratorModelTest PRIVATE Qt5::Test Qt5::Qml)
|
||||
|
||||
list(APPEND QML_DIRS "${CMAKE_SOURCE_DIR}/../ui/StatusQ/src")
|
||||
list(APPEND QML_DIRS "${CMAKE_SOURCE_DIR}/../ui/app")
|
||||
list(APPEND QML_DIRS "${CMAKE_SOURCE_DIR}/../ui/imports")
|
||||
|
|
|
@ -3,39 +3,10 @@ import QtQuick 2.14
|
|||
ListModel {
|
||||
ListElement {
|
||||
title: "ProfileDialogView"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=733%3A12552"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A15078"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17655"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17087"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23525"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23932"
|
||||
}
|
||||
]
|
||||
section: "Views"
|
||||
}
|
||||
ListElement {
|
||||
title: "CommunitiesPortalLayout"
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A415655"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A415935"
|
||||
}
|
||||
]
|
||||
section: "Views"
|
||||
}
|
||||
ListElement {
|
||||
|
@ -44,67 +15,22 @@ ListModel {
|
|||
}
|
||||
ListElement {
|
||||
title: "LoginView"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=1080%3A313192"
|
||||
}
|
||||
]
|
||||
section: "Views"
|
||||
}
|
||||
ListElement {
|
||||
title: "AboutView"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1159%3A114479"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1684%3A127762"
|
||||
}
|
||||
]
|
||||
section: "Views"
|
||||
}
|
||||
ListElement {
|
||||
title: "StatusCommunityCard"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416159"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416160"
|
||||
}
|
||||
]
|
||||
section: "Panels"
|
||||
}
|
||||
ListElement {
|
||||
title: "CommunityProfilePopupInviteFriendsPanel"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A343592"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2990%3A353179"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A344073"
|
||||
}
|
||||
]
|
||||
section: "Panels"
|
||||
}
|
||||
ListElement {
|
||||
title: "CommunityProfilePopupInviteMessagePanel"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4291%3A385536"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4295%3A385958"
|
||||
}
|
||||
]
|
||||
section: "Panels"
|
||||
}
|
||||
ListElement {
|
||||
|
@ -113,86 +39,22 @@ ListModel {
|
|||
}
|
||||
ListElement {
|
||||
title: "InviteFriendsToCommunityPopup"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A343592"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2990%3A353179"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A344073"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4291%3A385536"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4295%3A385958"
|
||||
}
|
||||
]
|
||||
section: "Popups"
|
||||
}
|
||||
ListElement {
|
||||
title: "CreateChannelPopup"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A488608"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A488256"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2903%3A348301"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A488848"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A489237"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A489607"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A492910"
|
||||
}
|
||||
]
|
||||
section: "Popups"
|
||||
}
|
||||
|
||||
ListElement {
|
||||
title: "MembersSelector"
|
||||
section: "Components"
|
||||
}
|
||||
ListElement {
|
||||
title: "BrowserSettings"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=448%3A36296"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1573%3A296338"
|
||||
}
|
||||
]
|
||||
section: "Settings"
|
||||
}
|
||||
ListElement {
|
||||
title: "LanguageCurrencySettings"
|
||||
|
||||
figma: [
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=701%3A74776"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1592%3A112840"
|
||||
},
|
||||
ListElement {
|
||||
link: "https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=701%3A75345"
|
||||
}
|
||||
]
|
||||
section: "Settings"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"ProfileDialogView": [
|
||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=733%3A12552",
|
||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A15078",
|
||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17655",
|
||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17087",
|
||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23525",
|
||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23932"
|
||||
],
|
||||
"CommunitiesPortalLayout": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A415655",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A415935"
|
||||
],
|
||||
"LoginView": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=1080%3A313192"
|
||||
],
|
||||
"AboutView": [
|
||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1159%3A114479",
|
||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1684%3A127762"
|
||||
],
|
||||
"StatusCommunityCard": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416159",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416160"
|
||||
],
|
||||
"CommunityProfilePopupInviteFriendsPanel": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A343592",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2990%3A353179",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A344073"
|
||||
],
|
||||
"CommunityProfilePopupInviteMessagePanel": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4291%3A385536",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4295%3A385958"
|
||||
],
|
||||
"InviteFriendsToCommunityPopup": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A343592",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2990%3A353179",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A344073",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4291%3A385536",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4295%3A385958"
|
||||
],
|
||||
"CreateChannelPopup": [
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A488608",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A488256",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2903%3A348301",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A488848",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A489237",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A489607",
|
||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A492910"
|
||||
],
|
||||
"BrowserSettings": [
|
||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=448%3A36296",
|
||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1573%3A296338"
|
||||
],
|
||||
"LanguageCurrencySettings": [
|
||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=701%3A74776",
|
||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1592%3A112840",
|
||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=701%3A75345"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
#include "figmadecoratormodel.h"
|
||||
|
||||
#include "figmalinks.h"
|
||||
#include "figmalinksmodel.h"
|
||||
#include "modelutils.h"
|
||||
|
||||
FigmaDecoratorModel::FigmaDecoratorModel(QObject *parent)
|
||||
: QIdentityProxyModel{parent}
|
||||
{
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> FigmaDecoratorModel::roleNames() const
|
||||
{
|
||||
auto roles = QIdentityProxyModel::roleNames();
|
||||
roles.insert(FigmaRole, QByteArrayLiteral("figma"));
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant FigmaDecoratorModel::data(const QModelIndex &proxyIndex, int role) const
|
||||
{
|
||||
if (!checkIndex(proxyIndex, CheckIndexOption::IndexIsValid))
|
||||
return {};
|
||||
|
||||
if (role == FigmaRole) {
|
||||
static FigmaLinksModel empty({});
|
||||
|
||||
if (!m_titleRole)
|
||||
return QVariant::fromValue(&empty);
|
||||
|
||||
const auto title = data(proxyIndex, m_titleRole.value()).toString();
|
||||
auto it = m_submodels.find(title);
|
||||
|
||||
if (it == m_submodels.end()) {
|
||||
QStringList links;
|
||||
|
||||
if (m_figmaLinks)
|
||||
links = m_figmaLinks->getLinksMap().value(title, {});
|
||||
|
||||
auto linksModel = new FigmaLinksModel(
|
||||
links, const_cast<FigmaDecoratorModel*>(this));
|
||||
it = m_submodels.insert(title, linksModel);
|
||||
}
|
||||
|
||||
return QVariant::fromValue(it.value());
|
||||
}
|
||||
|
||||
return QIdentityProxyModel::data(proxyIndex, role);
|
||||
}
|
||||
|
||||
FigmaLinks* FigmaDecoratorModel::getFigmaLinks() const
|
||||
{
|
||||
return m_figmaLinks;
|
||||
}
|
||||
|
||||
void FigmaDecoratorModel::setFigmaLinks(FigmaLinks *figmaLinks)
|
||||
{
|
||||
if (figmaLinks == m_figmaLinks)
|
||||
return;
|
||||
|
||||
m_figmaLinks = figmaLinks;
|
||||
const auto& linksMap = m_figmaLinks
|
||||
? m_figmaLinks->getLinksMap()
|
||||
: QMap<QString, QStringList>{};
|
||||
|
||||
auto linksIt = linksMap.constBegin();
|
||||
while (linksIt != linksMap.constEnd()) {
|
||||
if (m_submodels.contains(linksIt.key()))
|
||||
m_submodels.value(linksIt.key())->setContent(linksIt.value());
|
||||
++linksIt;
|
||||
}
|
||||
|
||||
auto submodelsIt = m_submodels.constBegin();
|
||||
while (submodelsIt != m_submodels.constEnd()) {
|
||||
if (!linksMap.contains(submodelsIt.key()))
|
||||
submodelsIt.value()->setContent({});
|
||||
++submodelsIt;
|
||||
}
|
||||
|
||||
emit figmaLinksChanged();
|
||||
}
|
||||
|
||||
void FigmaDecoratorModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
qDeleteAll(m_submodels);
|
||||
m_submodels.clear();
|
||||
|
||||
m_titleRole = ModelUtils::findRole(QByteArrayLiteral("title"), sourceModel);
|
||||
|
||||
if(!m_titleRole)
|
||||
qWarning("The source model is missing title role!");
|
||||
|
||||
QIdentityProxyModel::setSourceModel(sourceModel);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <QIdentityProxyModel>
|
||||
|
||||
class FigmaLinks;
|
||||
class FigmaLinksModel;
|
||||
|
||||
class FigmaDecoratorModel : public QIdentityProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(FigmaLinks* figmaLinks READ getFigmaLinks
|
||||
WRITE setFigmaLinks NOTIFY figmaLinksChanged)
|
||||
public:
|
||||
static constexpr auto FigmaRole = Qt::UserRole + 100;
|
||||
|
||||
explicit FigmaDecoratorModel(QObject *parent = nullptr);
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
QVariant data(const QModelIndex &proxyIndex, int role) const override;
|
||||
|
||||
FigmaLinks* getFigmaLinks() const;
|
||||
void setFigmaLinks(FigmaLinks *figmaLinks);
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
signals:
|
||||
void figmaLinksChanged();
|
||||
|
||||
private:
|
||||
std::optional<int> m_titleRole;
|
||||
FigmaLinks* m_figmaLinks = nullptr;
|
||||
mutable QMap<QString, FigmaLinksModel*> m_submodels;
|
||||
};
|
|
@ -0,0 +1,49 @@
|
|||
#include "figmaio.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
QMap<QString, QStringList> FigmaIO::read(const QString &file)
|
||||
{
|
||||
QFile f(file);
|
||||
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qWarning() << "FigmaIO::read - failed to open file:" << file;
|
||||
return {};
|
||||
}
|
||||
|
||||
QJsonParseError error;
|
||||
auto jsonDoc = QJsonDocument::fromJson(f.readAll(), &error);
|
||||
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qWarning() << "FigmaIO::read - error parsing json file:" << file
|
||||
<< "->" << error.errorString();
|
||||
return {};
|
||||
}
|
||||
|
||||
QMap<QString, QStringList> mapping;
|
||||
|
||||
if (jsonDoc.isObject()) {
|
||||
auto rootObject = jsonDoc.object();
|
||||
|
||||
auto i = rootObject.constBegin();
|
||||
while (i != rootObject.constEnd()) {
|
||||
QJsonValue val = i.value();
|
||||
QJsonArray links = val.toArray();
|
||||
|
||||
QStringList linksList;
|
||||
linksList.reserve(links.size());
|
||||
|
||||
for (const QJsonValue &link : qAsConst(links))
|
||||
if (link.isString())
|
||||
linksList << link.toString();
|
||||
|
||||
mapping.insert(i.key(), linksList);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <QMap>
|
||||
|
||||
class FigmaIO
|
||||
{
|
||||
public:
|
||||
static QMap<QString, QStringList> read(const QString &file);
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
#include "figmalinks.h"
|
||||
|
||||
FigmaLinks::FigmaLinks(const QMap<QString, QStringList>& linksMap, QObject *parent)
|
||||
: m_linksMap{linksMap}, QObject{parent}
|
||||
{
|
||||
}
|
||||
|
||||
const QMap<QString, QStringList>& FigmaLinks::getLinksMap() const
|
||||
{
|
||||
return m_linksMap;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
class FigmaLinks : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FigmaLinks(const QMap<QString, QStringList>& mapping,
|
||||
QObject *parent = nullptr);
|
||||
const QMap<QString, QStringList>& getLinksMap() const;
|
||||
|
||||
private:
|
||||
QMap<QString, QStringList> m_linksMap;
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
#include "figmalinksmodel.h"
|
||||
|
||||
FigmaLinksModel::FigmaLinksModel(const QStringList &links, QObject *parent)
|
||||
: QAbstractListModel{parent}, m_links{links}
|
||||
{
|
||||
}
|
||||
|
||||
int FigmaLinksModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_links.size();
|
||||
}
|
||||
|
||||
QVariant FigmaLinksModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
||||
return {};
|
||||
|
||||
const int row = index.row();
|
||||
return m_links.at(row);
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> FigmaLinksModel::roleNames() const
|
||||
{
|
||||
static QHash<int, QByteArray> roles(
|
||||
{{LinkRole, QByteArrayLiteral("link")}});
|
||||
return roles;
|
||||
}
|
||||
|
||||
void FigmaLinksModel::setContent(const QStringList &links)
|
||||
{
|
||||
if (m_links == links)
|
||||
return;
|
||||
|
||||
const auto oldCount = m_links.size();
|
||||
|
||||
beginResetModel();
|
||||
m_links = links;
|
||||
endResetModel();
|
||||
|
||||
if (m_links.size() != oldCount)
|
||||
emit countChanged();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
class FigmaLinksModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
|
||||
public:
|
||||
static constexpr auto LinkRole = 0;
|
||||
|
||||
explicit FigmaLinksModel(const QStringList &links,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
void setContent(const QStringList &links);
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
private:
|
||||
QStringList m_links;
|
||||
};
|
|
@ -0,0 +1,71 @@
|
|||
#include "figmalinkssource.h"
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include "figmaio.h"
|
||||
#include "figmalinks.h"
|
||||
|
||||
FigmaLinksSource::FigmaLinksSource(QObject *parent)
|
||||
: QObject{parent}
|
||||
{
|
||||
connect(&m_watcher, &QFileSystemWatcher::fileChanged,
|
||||
this, [this](const QString &path) {
|
||||
this->readFile();
|
||||
|
||||
if (!this->m_watcher.files().contains(path))
|
||||
this->m_watcher.addPath(path);
|
||||
});
|
||||
}
|
||||
|
||||
const QUrl& FigmaLinksSource::getFilePath() const
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
void FigmaLinksSource::setFilePath(const QUrl& path)
|
||||
{
|
||||
if (path == m_filePath)
|
||||
return;
|
||||
|
||||
m_filePath = path;
|
||||
readFile();
|
||||
setupWatcher();
|
||||
emit filePathChanged();
|
||||
}
|
||||
|
||||
FigmaLinks* FigmaLinksSource::getFigmaLinks() const
|
||||
{
|
||||
return m_figmaLinks;
|
||||
}
|
||||
|
||||
void FigmaLinksSource::updateFigmaLinks(const QMap<QString, QStringList>& map)
|
||||
{
|
||||
FigmaLinks *mapping = new FigmaLinks(map, this);
|
||||
|
||||
if (m_figmaLinks && qjsEngine(m_figmaLinks)) {
|
||||
m_figmaLinks->setParent(nullptr);
|
||||
QQmlEngine::setObjectOwnership(m_figmaLinks, QQmlEngine::JavaScriptOwnership);
|
||||
}
|
||||
|
||||
m_figmaLinks = mapping;
|
||||
emit figmaLinksChanged();
|
||||
}
|
||||
|
||||
void FigmaLinksSource::readFile()
|
||||
{
|
||||
QMap<QString, QStringList> figmaLinks = FigmaIO::read(m_filePath.path());
|
||||
updateFigmaLinks(figmaLinks);
|
||||
}
|
||||
|
||||
void FigmaLinksSource::setupWatcher()
|
||||
{
|
||||
auto currentlyWatched = m_watcher.files();
|
||||
|
||||
if (!currentlyWatched.isEmpty())
|
||||
m_watcher.removePaths(currentlyWatched);
|
||||
|
||||
if (m_filePath.isEmpty())
|
||||
return;
|
||||
|
||||
m_watcher.addPath(m_filePath.path());
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QUrl>
|
||||
|
||||
class FigmaLinks;
|
||||
|
||||
class FigmaLinksSource : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUrl filePath READ getFilePath WRITE setFilePath NOTIFY filePathChanged)
|
||||
Q_PROPERTY(FigmaLinks* figmaLinks READ getFigmaLinks NOTIFY figmaLinksChanged)
|
||||
|
||||
public:
|
||||
explicit FigmaLinksSource(QObject *parent = nullptr);
|
||||
|
||||
const QUrl& getFilePath() const;
|
||||
void setFilePath(const QUrl& path);
|
||||
FigmaLinks* getFigmaLinks() const;
|
||||
|
||||
signals:
|
||||
void filePathChanged();
|
||||
void figmaLinksChanged();
|
||||
|
||||
private:
|
||||
void updateFigmaLinks(const QMap<QString, QStringList>& map);
|
||||
void readFile();
|
||||
void setupWatcher();
|
||||
|
||||
FigmaLinks *m_figmaLinks = nullptr;
|
||||
QUrl m_filePath;
|
||||
QFileSystemWatcher m_watcher;
|
||||
};
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
#include "cachecleaner.h"
|
||||
#include "directorieswatcher.h"
|
||||
#include "figmadecoratormodel.h"
|
||||
#include "figmalinks.h"
|
||||
#include "figmalinkssource.h"
|
||||
#include "sectionsdecoratormodel.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -35,6 +38,9 @@ int main(int argc, char *argv[])
|
|||
engine.addImportPath(path);
|
||||
|
||||
qmlRegisterType<SectionsDecoratorModel>("Storybook", 1, 0, "SectionsDecoratorModel");
|
||||
qmlRegisterType<FigmaDecoratorModel>("Storybook", 1, 0, "FigmaDecoratorModel");
|
||||
qmlRegisterType<FigmaLinksSource>("Storybook", 1, 0, "FigmaLinksSource");
|
||||
qmlRegisterUncreatableType<FigmaLinks>("Storybook", 1, 0, "FigmaLinks", "");
|
||||
|
||||
auto watcherFactory = [additionalImportPaths](QQmlEngine*, QJSEngine*) {
|
||||
auto watcher = new DirectoriesWatcher();
|
||||
|
|
|
@ -18,6 +18,23 @@ ApplicationWindow {
|
|||
|
||||
font.pixelSize: 13
|
||||
|
||||
PagesModel {
|
||||
id: pagesModel
|
||||
}
|
||||
|
||||
FigmaLinksSource {
|
||||
id: figmaLinksSource
|
||||
|
||||
filePath: "figma.json"
|
||||
}
|
||||
|
||||
FigmaDecoratorModel {
|
||||
id: figmaModel
|
||||
|
||||
sourceModel: pagesModel
|
||||
figmaLinks: figmaLinksSource.figmaLinks
|
||||
}
|
||||
|
||||
HotReloader {
|
||||
id: reloader
|
||||
|
||||
|
@ -26,10 +43,6 @@ ApplicationWindow {
|
|||
onReloaded: hotReloaderControls.notifyReload()
|
||||
}
|
||||
|
||||
PagesModel {
|
||||
id: pagesModel
|
||||
}
|
||||
|
||||
SplitView {
|
||||
anchors.fill: parent
|
||||
|
||||
|
@ -125,13 +138,13 @@ ApplicationWindow {
|
|||
|
||||
title: `pages/${root.currentPage}Page.qml`
|
||||
figmaPagesCount: currentPageModelItem.object
|
||||
? currentPageModelItem.object.figmaCount : 0
|
||||
? currentPageModelItem.object.figma.count : 0
|
||||
|
||||
Instantiator {
|
||||
id: currentPageModelItem
|
||||
|
||||
model: SingleItemProxyModel {
|
||||
sourceModel: pagesModel
|
||||
sourceModel: figmaModel
|
||||
roleName: "title"
|
||||
value: root.currentPage
|
||||
}
|
||||
|
@ -139,7 +152,6 @@ ApplicationWindow {
|
|||
delegate: QtObject {
|
||||
readonly property string title: model.title
|
||||
readonly property var figma: model.figma
|
||||
readonly property int figmaCount: figma ? figma.count : 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#include "modelutils.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
std::optional<int> ModelUtils::findRole(const QByteArray &role,
|
||||
const QAbstractItemModel *model)
|
||||
{
|
||||
if (model == nullptr)
|
||||
return std::nullopt;
|
||||
|
||||
const auto roleNames = model->roleNames();
|
||||
|
||||
auto it = std::find_if(roleNames.constKeyValueBegin(),
|
||||
roleNames.constKeyValueEnd(), [&role](auto entry) {
|
||||
return entry.second == role;
|
||||
});
|
||||
|
||||
return it == roleNames.constKeyValueEnd()
|
||||
? std::nullopt : std::make_optional((*it).first);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QAbstractItemModel;
|
||||
|
||||
struct ModelUtils
|
||||
{
|
||||
static std::optional<int> findRole(const QByteArray &role,
|
||||
const QAbstractItemModel *model);
|
||||
};
|
|
@ -1,5 +1,7 @@
|
|||
#include "sectionsdecoratormodel.h"
|
||||
|
||||
#include "modelutils.h"
|
||||
|
||||
#include <QScopeGuard>
|
||||
|
||||
SectionsDecoratorModel::SectionsDecoratorModel(QObject *parent)
|
||||
|
@ -121,20 +123,6 @@ void SectionsDecoratorModel::calculateOffsets()
|
|||
});
|
||||
}
|
||||
|
||||
std::optional<int> SectionsDecoratorModel::findSectionRole() const
|
||||
{
|
||||
const auto roleNames = m_sourceModel->roleNames();
|
||||
auto i = roleNames.constBegin();
|
||||
|
||||
while (i != roleNames.constEnd()) {
|
||||
if (i.value() == QStringLiteral("section"))
|
||||
return i.key();
|
||||
++i;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void SectionsDecoratorModel::initialize()
|
||||
{
|
||||
beginResetModel();
|
||||
|
@ -142,7 +130,8 @@ void SectionsDecoratorModel::initialize()
|
|||
|
||||
m_rowsMetadata.clear();
|
||||
|
||||
const auto sectionRoleOpt = findSectionRole();
|
||||
const auto sectionRoleOpt = ModelUtils::findRole(
|
||||
QByteArrayLiteral("section"), m_sourceModel);
|
||||
|
||||
if (!sectionRoleOpt) {
|
||||
qWarning("Section role not found!");
|
||||
|
|
|
@ -36,7 +36,6 @@ private:
|
|||
int count = 0;
|
||||
};
|
||||
|
||||
std::optional<int> findSectionRole() const;
|
||||
void initialize();
|
||||
void calculateOffsets();
|
||||
|
||||
|
|
|
@ -1,30 +1,47 @@
|
|||
import QtQuick 2.14
|
||||
|
||||
ListModel {
|
||||
id: root
|
||||
|
||||
/* required */ property FigmaLinksCache figmaLinksCache
|
||||
property alias sourceModel: d.model
|
||||
|
||||
readonly property Instantiator _d: Instantiator {
|
||||
id: d
|
||||
|
||||
property int idCounter: 0
|
||||
|
||||
model: 0
|
||||
|
||||
delegate: QtObject {
|
||||
id: delegate
|
||||
|
||||
property int uniqueId
|
||||
|
||||
Component.onCompleted: {
|
||||
append({
|
||||
rawLink: model.link,
|
||||
imageLink: ""
|
||||
imageLink: "",
|
||||
uniqueId: d.idCounter
|
||||
})
|
||||
|
||||
uniqueId = d.idCounter
|
||||
d.idCounter++
|
||||
|
||||
figmaLinksCache.getImageUrl(model.link, link => {
|
||||
if (delegate)
|
||||
setProperty(model.index, "imageLink", link)
|
||||
root.setProperty(model.index, "imageLink", link)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onObjectRemoved: console.warn("FigmaImagesProxyModel: removing items from the source model is not supported!")
|
||||
onObjectRemoved: {
|
||||
for (let i = 0; i < root.count; i++) {
|
||||
if (root.get(i).uniqueId === object.uniqueId) {
|
||||
root.remove(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ ColumnLayout {
|
|||
|
||||
RoundButton {
|
||||
text: "⬅"
|
||||
enabled: root.currentIndex !== 0
|
||||
enabled: root.currentIndex !== 0 && root.currentIndex !== -1
|
||||
onClicked: root.left()
|
||||
}
|
||||
RoundButton {
|
||||
|
|
|
@ -0,0 +1,321 @@
|
|||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
#include <QTemporaryFile>
|
||||
#include <QStringListModel>
|
||||
|
||||
#include "figmadecoratormodel.h"
|
||||
#include "figmalinks.h"
|
||||
#include "figmalinksmodel.h"
|
||||
#include "figmalinkssource.h"
|
||||
|
||||
namespace {
|
||||
|
||||
auto constexpr sampleJson1 = R"(
|
||||
{
|
||||
"Component_1": [
|
||||
"link_1", "link_2"
|
||||
],
|
||||
"Component_2": [
|
||||
"link_3", "link_4"
|
||||
]
|
||||
}
|
||||
)";
|
||||
|
||||
auto constexpr sampleJson2 = R"(
|
||||
{
|
||||
"Component_1": [
|
||||
"link_1"
|
||||
],
|
||||
"Component_2": [
|
||||
"link_3", "link_5"
|
||||
]
|
||||
}
|
||||
)";
|
||||
|
||||
class TestSourceModel : public QAbstractListModel {
|
||||
|
||||
public:
|
||||
static constexpr auto TitleRole = 0;
|
||||
|
||||
TestSourceModel(int count = 1) : m_count(count) {}
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
|
||||
return m_count;
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override {
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
|
||||
return QString("title_%1").arg(index.row());
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles.insert(TitleRole, QByteArrayLiteral("title"));
|
||||
return roles;
|
||||
}
|
||||
|
||||
int m_count;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
class FigmaDecoratorModelTest: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void readingFigmaFileTest() {
|
||||
FigmaLinksSource figmaLinksSource;
|
||||
|
||||
QSignalSpy spy(&figmaLinksSource, &FigmaLinksSource::figmaLinksChanged);
|
||||
|
||||
QCOMPARE(figmaLinksSource.getFigmaLinks(), nullptr);
|
||||
|
||||
QTemporaryFile file;
|
||||
if (file.open()) {
|
||||
QTextStream stream(&file);
|
||||
stream << sampleJson1;
|
||||
}
|
||||
|
||||
figmaLinksSource.setFilePath(file.fileName());
|
||||
|
||||
QVERIFY(figmaLinksSource.getFigmaLinks() != nullptr);
|
||||
|
||||
const FigmaLinks *links = figmaLinksSource.getFigmaLinks();
|
||||
|
||||
QCOMPARE(links->getLinksMap(), (QMap<QString, QStringList> {
|
||||
{{"Component_1"}, {"link_1", "link_2"}},
|
||||
{{"Component_2"}, {"link_3", "link_4"}}}));
|
||||
QCOMPARE(spy.count(), 1);
|
||||
|
||||
QTemporaryFile file2;
|
||||
if (file2.open()) {
|
||||
QTextStream stream(&file2);
|
||||
stream << sampleJson2;
|
||||
}
|
||||
|
||||
figmaLinksSource.setFilePath(file2.fileName());
|
||||
|
||||
QVERIFY(figmaLinksSource.getFigmaLinks() != nullptr);
|
||||
|
||||
const FigmaLinks *links2 = figmaLinksSource.getFigmaLinks();
|
||||
|
||||
QCOMPARE(links2->getLinksMap(), (QMap<QString, QStringList> {
|
||||
{{"Component_1"}, {"link_1"}},
|
||||
{{"Component_2"}, {"link_3", "link_5"}}}));
|
||||
QCOMPARE(spy.count(), 2);
|
||||
}
|
||||
|
||||
void readingAfterFigmaFileChangedTest() {
|
||||
|
||||
FigmaLinksSource figmaLinksSource;
|
||||
|
||||
QSignalSpy spy(&figmaLinksSource, &FigmaLinksSource::figmaLinksChanged);
|
||||
|
||||
QCOMPARE(figmaLinksSource.getFigmaLinks(), nullptr);
|
||||
|
||||
QTemporaryFile file;
|
||||
if (file.open()) {
|
||||
QTextStream stream(&file);
|
||||
stream << sampleJson1;
|
||||
}
|
||||
|
||||
figmaLinksSource.setFilePath(file.fileName());
|
||||
|
||||
QVERIFY(figmaLinksSource.getFigmaLinks() != nullptr);
|
||||
|
||||
const FigmaLinks *links = figmaLinksSource.getFigmaLinks();
|
||||
|
||||
QCOMPARE(links->getLinksMap(), (QMap<QString, QStringList> {
|
||||
{{"Component_1"}, {"link_1", "link_2"}},
|
||||
{{"Component_2"}, {"link_3", "link_4"}}}));
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
|
||||
if (QFile f(file.fileName());
|
||||
f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
QTextStream stream(&f);
|
||||
stream << sampleJson2;
|
||||
}
|
||||
|
||||
QVERIFY(spy.wait());
|
||||
QCOMPARE(spy.count(), 2);
|
||||
|
||||
const FigmaLinks *links2 = figmaLinksSource.getFigmaLinks();
|
||||
|
||||
QCOMPARE(links2->getLinksMap(), (QMap<QString, QStringList> {
|
||||
{{"Component_1"}, {"link_1"}},
|
||||
{{"Component_2"}, {"link_3", "link_5"}}}));
|
||||
|
||||
|
||||
if (QFile f(file.fileName());
|
||||
f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
QTextStream stream(&f);
|
||||
stream << sampleJson1;
|
||||
}
|
||||
|
||||
QVERIFY(spy.wait());
|
||||
QCOMPARE(spy.count(), 3);
|
||||
|
||||
const FigmaLinks *links3 = figmaLinksSource.getFigmaLinks();
|
||||
|
||||
QCOMPARE(links3->getLinksMap(), (QMap<QString, QStringList> {
|
||||
{{"Component_1"}, {"link_1", "link_2"}},
|
||||
{{"Component_2"}, {"link_3", "link_4"}}}));
|
||||
}
|
||||
|
||||
void emptyFigmaModelTest() {
|
||||
FigmaDecoratorModel model;
|
||||
QCOMPARE(model.rowCount(), 0);
|
||||
QVERIFY(model.roleNames().contains(FigmaDecoratorModel::FigmaRole));
|
||||
QCOMPARE(model.roleNames().value(
|
||||
FigmaDecoratorModel::FigmaRole), QStringLiteral("figma"));
|
||||
}
|
||||
|
||||
void figmaModelWithoutSourceModel() {
|
||||
FigmaLinks links({
|
||||
{{"Component_1"}, {"link_1", "link_2"}},
|
||||
{{"Component_2"}, {"link_3", "link_4"}}
|
||||
});
|
||||
|
||||
FigmaDecoratorModel model;
|
||||
model.setFigmaLinks(&links);
|
||||
|
||||
QCOMPARE(model.rowCount(), 0);
|
||||
QVERIFY(model.roleNames().contains(FigmaDecoratorModel::FigmaRole));
|
||||
QCOMPARE(model.roleNames().value(
|
||||
FigmaDecoratorModel::FigmaRole), QStringLiteral("figma"));
|
||||
}
|
||||
|
||||
void figmaModelWithIncompatibleSourceModel() {
|
||||
QStringListModel stringsModel({"s1", "s2"});
|
||||
FigmaDecoratorModel model;
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"The source model is missing title role!");
|
||||
model.setSourceModel(&stringsModel);
|
||||
|
||||
QCOMPARE(model.rowCount(), 2);
|
||||
QVERIFY(model.roleNames().contains(FigmaDecoratorModel::FigmaRole));
|
||||
QCOMPARE(model.roleNames().value(
|
||||
FigmaDecoratorModel::FigmaRole), QStringLiteral("figma"));
|
||||
|
||||
QCOMPARE(model.data(
|
||||
model.index(0, 0),
|
||||
FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>()->rowCount(), 0);
|
||||
}
|
||||
|
||||
void figmaModelWithoutLinksTest() {
|
||||
TestSourceModel sourceModel;
|
||||
FigmaDecoratorModel model;
|
||||
|
||||
model.setSourceModel(&sourceModel);
|
||||
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.roleNames().count(), 2);
|
||||
QVERIFY(model.roleNames().contains(FigmaDecoratorModel::FigmaRole));
|
||||
QCOMPARE(model.roleNames().value(
|
||||
FigmaDecoratorModel::FigmaRole), QStringLiteral("figma"));
|
||||
|
||||
QCOMPARE(model.data(
|
||||
model.index(0, 0),
|
||||
FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>()->rowCount(), 0);
|
||||
}
|
||||
|
||||
void figmaModelTest() {
|
||||
TestSourceModel sourceModel{2};
|
||||
FigmaLinks links({
|
||||
{{"title_0"}, {"link_1", "link_2"}},
|
||||
{{"title_x"}, {"link_3", "link_4"}}
|
||||
});
|
||||
|
||||
FigmaDecoratorModel model;
|
||||
|
||||
QSignalSpy spy(&model, &FigmaDecoratorModel::dataChanged);
|
||||
|
||||
model.setSourceModel(&sourceModel);
|
||||
|
||||
QCOMPARE(spy.size(), 0);
|
||||
|
||||
QCOMPARE(model.rowCount(), 2);
|
||||
QCOMPARE(model.roleNames().count(), 2);
|
||||
QVERIFY(model.roleNames().contains(FigmaDecoratorModel::FigmaRole));
|
||||
QVERIFY(model.roleNames().contains(TestSourceModel::TitleRole));
|
||||
|
||||
QCOMPARE(model.roleNames().value(
|
||||
FigmaDecoratorModel::FigmaRole), QStringLiteral("figma"));
|
||||
QCOMPARE(model.roleNames().value(
|
||||
TestSourceModel::TitleRole), QStringLiteral("title"));
|
||||
|
||||
QCOMPARE(model.data(model.index(0, 0),
|
||||
TestSourceModel::TitleRole).toString(), "title_0");
|
||||
QCOMPARE(model.data(model.index(1, 0),
|
||||
TestSourceModel::TitleRole).toString(), "title_1");
|
||||
|
||||
auto figmaLinksModel1 = model.data(model.index(0, 0), FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>();
|
||||
|
||||
QVERIFY(figmaLinksModel1 != nullptr);
|
||||
QCOMPARE(figmaLinksModel1->rowCount(), 0);
|
||||
|
||||
auto figmaLinksModel2 = model.data(model.index(1, 0), FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>();
|
||||
|
||||
QVERIFY(figmaLinksModel2 != nullptr);
|
||||
QCOMPARE(figmaLinksModel2->rowCount(), 0);
|
||||
|
||||
QSignalSpy linksModelspy1(figmaLinksModel1,
|
||||
&QAbstractItemModel::modelReset);
|
||||
QSignalSpy linksModelspy2(figmaLinksModel2,
|
||||
&QAbstractItemModel::modelReset);
|
||||
|
||||
model.setFigmaLinks(&links);
|
||||
|
||||
QCOMPARE(spy.size(), 0);
|
||||
|
||||
QCOMPARE(linksModelspy1.size(), 1);
|
||||
QCOMPARE(linksModelspy2.size(), 0);
|
||||
|
||||
QCOMPARE(model.data(model.index(0, 0), FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>(), figmaLinksModel1);
|
||||
QCOMPARE(model.data(model.index(1, 0), FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>(), figmaLinksModel2);
|
||||
|
||||
QCOMPARE(figmaLinksModel1->rowCount(), 2);
|
||||
QCOMPARE(figmaLinksModel2->rowCount(), 0);
|
||||
|
||||
QCOMPARE(model.data(model.index(0, 0),
|
||||
TestSourceModel::TitleRole).toString(), "title_0");
|
||||
QCOMPARE(model.data(model.index(1, 0),
|
||||
TestSourceModel::TitleRole).toString(), "title_1");
|
||||
|
||||
QCOMPARE(figmaLinksModel1->roleNames().size(), 1);
|
||||
QCOMPARE(figmaLinksModel2->roleNames().size(), 1);
|
||||
|
||||
QCOMPARE(figmaLinksModel1->data(figmaLinksModel1->index(0, 0),
|
||||
FigmaLinksModel::LinkRole).toString(), "link_1");
|
||||
QCOMPARE(figmaLinksModel1->data(figmaLinksModel1->index(1, 0),
|
||||
FigmaLinksModel::LinkRole).toString(), "link_2");
|
||||
|
||||
model.setFigmaLinks(nullptr);
|
||||
|
||||
QCOMPARE(spy.size(), 0);
|
||||
QCOMPARE(linksModelspy1.size(), 2);
|
||||
QCOMPARE(linksModelspy2.size(), 0);
|
||||
|
||||
QCOMPARE(model.data(model.index(0, 0), FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>(), figmaLinksModel1);
|
||||
QCOMPARE(model.data(model.index(1, 0), FigmaDecoratorModel::FigmaRole)
|
||||
.value<QAbstractItemModel*>(), figmaLinksModel2);
|
||||
|
||||
QCOMPARE(figmaLinksModel1->rowCount(), 0);
|
||||
QCOMPARE(figmaLinksModel2->rowCount(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(FigmaDecoratorModelTest)
|
||||
#include "tst_FigmaDecoratorModel.moc"
|
Loading…
Reference in New Issue