feat(Storybook): Possibility to modify Figma links directly from the app
Closes: #8450
This commit is contained in:
parent
4c1370f7ef
commit
cda881af46
|
@ -49,6 +49,10 @@ ListModel {
|
||||||
title: "MembersSelector"
|
title: "MembersSelector"
|
||||||
section: "Components"
|
section: "Components"
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
title: "ImagesGridView"
|
||||||
|
section: "Components"
|
||||||
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
title: "BrowserSettings"
|
title: "BrowserSettings"
|
||||||
section: "Settings"
|
section: "Settings"
|
||||||
|
|
|
@ -1,26 +1,15 @@
|
||||||
{
|
{
|
||||||
"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": [
|
"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=1159%3A114479",
|
||||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1684%3A127762"
|
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1684%3A127762"
|
||||||
],
|
],
|
||||||
"StatusCommunityCard": [
|
"BrowserSettings": [
|
||||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416159",
|
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=448%3A36296",
|
||||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416160"
|
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1573%3A296338"
|
||||||
|
],
|
||||||
|
"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"
|
||||||
],
|
],
|
||||||
"CommunityProfilePopupInviteFriendsPanel": [
|
"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=2927%3A343592",
|
||||||
|
@ -31,13 +20,6 @@
|
||||||
"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=4291%3A385536",
|
||||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=4295%3A385958"
|
"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": [
|
"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%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=2975%3A488256",
|
||||||
|
@ -47,13 +29,31 @@
|
||||||
"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%3A489607",
|
||||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A492910"
|
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2975%3A492910"
|
||||||
],
|
],
|
||||||
"BrowserSettings": [
|
"InviteFriendsToCommunityPopup": [
|
||||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=448%3A36296",
|
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=2927%3A343592",
|
||||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=1573%3A296338"
|
"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"
|
||||||
],
|
],
|
||||||
"LanguageCurrencySettings": [
|
"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=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=1592%3A112840",
|
||||||
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=701%3A75345"
|
"https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?node-id=701%3A75345"
|
||||||
|
],
|
||||||
|
"LoginView": [
|
||||||
|
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=1080%3A313192"
|
||||||
|
],
|
||||||
|
"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"
|
||||||
|
],
|
||||||
|
"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"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QSaveFile>
|
||||||
|
|
||||||
QMap<QString, QStringList> FigmaIO::read(const QString &file)
|
QMap<QString, QStringList> FigmaIO::read(const QString &file)
|
||||||
{
|
{
|
||||||
|
@ -47,3 +48,28 @@ QMap<QString, QStringList> FigmaIO::read(const QString &file)
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FigmaIO::write(const QString &file, const QMap<QString, QStringList> &map)
|
||||||
|
{
|
||||||
|
QJsonObject rootObject;
|
||||||
|
|
||||||
|
std::for_each(map.constKeyValueBegin(), map.constKeyValueEnd(),
|
||||||
|
[&rootObject](auto entry) {
|
||||||
|
const auto& [key, links] = entry;
|
||||||
|
rootObject.insert(key, QJsonArray::fromStringList(links));
|
||||||
|
});
|
||||||
|
|
||||||
|
QSaveFile saveFile(file);
|
||||||
|
if (!saveFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
|
qWarning() << "FigmaIO::write - failed to open file:" << file;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument doc(rootObject);
|
||||||
|
saveFile.write(doc.toJson());
|
||||||
|
|
||||||
|
bool commitResult = saveFile.commit();
|
||||||
|
|
||||||
|
if (!commitResult)
|
||||||
|
qWarning() << "FigmaIO::write - failed to write to file:" << file;
|
||||||
|
}
|
||||||
|
|
|
@ -6,4 +6,5 @@ class FigmaIO
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static QMap<QString, QStringList> read(const QString &file);
|
static QMap<QString, QStringList> read(const QString &file);
|
||||||
|
static void write(const QString &file, const QMap<QString, QStringList> &map);
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,74 @@ FigmaLinks* FigmaLinksSource::getFigmaLinks() const
|
||||||
return m_figmaLinks;
|
return m_figmaLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FigmaLinksSource::remove(const QString &key, const QList<int> &indexes)
|
||||||
|
{
|
||||||
|
if (m_filePath.isEmpty()) {
|
||||||
|
qWarning("FigmaLinksSource::remove - file path is not set!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QStringList> linksMap;
|
||||||
|
|
||||||
|
if (m_figmaLinks)
|
||||||
|
linksMap = m_figmaLinks->getLinksMap();
|
||||||
|
|
||||||
|
auto it = linksMap.find(key);
|
||||||
|
|
||||||
|
if (it == linksMap.end()) {
|
||||||
|
qWarning("FigmaLinksSource::remove - provided key doesn't exist!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexes.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto indexesSorted = indexes;
|
||||||
|
std::sort(indexesSorted.begin(), indexesSorted.end());
|
||||||
|
|
||||||
|
if (std::adjacent_find(indexesSorted.cbegin(), indexesSorted.cend())
|
||||||
|
!= indexesSorted.cend()) {
|
||||||
|
qWarning("FigmaLinksSource::remove - provided indexes list contains duplicates!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& linksList = it.value();
|
||||||
|
|
||||||
|
if (indexesSorted.first() < 0 || indexesSorted.last() >= linksList.size()) {
|
||||||
|
qWarning("FigmaLinksSource::remove - at least one provided index is out of range!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (linksList.size() == indexesSorted.size()) {
|
||||||
|
linksMap.erase(it);
|
||||||
|
} else {
|
||||||
|
std::for_each(std::crbegin(indexesSorted), std::crend(indexesSorted),
|
||||||
|
[&linksList](int idx) {
|
||||||
|
linksList.removeAt(idx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
FigmaIO::write(m_filePath.path(), linksMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FigmaLinksSource::append(const QString &key, const QList<QString> &links)
|
||||||
|
{
|
||||||
|
QMap<QString, QStringList> linksMap;
|
||||||
|
|
||||||
|
|
||||||
|
if (m_filePath.isEmpty()) {
|
||||||
|
qWarning("FigmaLinksSource::append - file path is not set!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_figmaLinks)
|
||||||
|
linksMap = m_figmaLinks->getLinksMap();
|
||||||
|
|
||||||
|
linksMap[key].append(links);
|
||||||
|
|
||||||
|
FigmaIO::write(m_filePath.path(), linksMap);
|
||||||
|
}
|
||||||
|
|
||||||
void FigmaLinksSource::updateFigmaLinks(const QMap<QString, QStringList>& map)
|
void FigmaLinksSource::updateFigmaLinks(const QMap<QString, QStringList>& map)
|
||||||
{
|
{
|
||||||
FigmaLinks *mapping = new FigmaLinks(map, this);
|
FigmaLinks *mapping = new FigmaLinks(map, this);
|
||||||
|
|
|
@ -19,6 +19,9 @@ public:
|
||||||
void setFilePath(const QUrl& path);
|
void setFilePath(const QUrl& path);
|
||||||
FigmaLinks* getFigmaLinks() const;
|
FigmaLinks* getFigmaLinks() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void remove(const QString &key, const QList<int> &indexes);
|
||||||
|
Q_INVOKABLE void append(const QString &key, const QList<QString> &links);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void filePathChanged();
|
void filePathChanged();
|
||||||
void figmaLinksChanged();
|
void figmaLinksChanged();
|
||||||
|
|
|
@ -161,9 +161,9 @@ ApplicationWindow {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const window = figmaWindow.createObject(root, {
|
figmaWindow.createObject(root, {
|
||||||
figmaModel: currentPageModelItem.object.figma,
|
figmaModel: currentPageModelItem.object.figma,
|
||||||
title: currentPageModelItem.object.title + " - Figma"
|
pageTitle: currentPageModelItem.object.title
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,14 +215,20 @@ ApplicationWindow {
|
||||||
id: figmaWindow
|
id: figmaWindow
|
||||||
|
|
||||||
FigmaPreviewWindow {
|
FigmaPreviewWindow {
|
||||||
|
property string pageTitle
|
||||||
property alias figmaModel: figmaImagesProxyModel.sourceModel
|
property alias figmaModel: figmaImagesProxyModel.sourceModel
|
||||||
|
|
||||||
|
title: pageTitle + " - Figma"
|
||||||
|
|
||||||
model: FigmaImagesProxyModel {
|
model: FigmaImagesProxyModel {
|
||||||
id: figmaImagesProxyModel
|
id: figmaImagesProxyModel
|
||||||
|
|
||||||
figmaLinksCache: figmaImageLinksCache
|
figmaLinksCache: figmaImageLinksCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRemoveLinksRequested: figmaLinksSource.remove(pageTitle, indexes)
|
||||||
|
onAppendLinksRequested: figmaLinksSource.append(pageTitle, links)
|
||||||
|
|
||||||
onClosing: Qt.callLater(destroy)
|
onClosing: Qt.callLater(destroy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
|
||||||
|
import Storybook 1.0
|
||||||
|
|
||||||
|
Pane {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: imagesModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Instantiator {
|
||||||
|
model: 20
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
parent: root
|
||||||
|
|
||||||
|
width: 150
|
||||||
|
height: 150
|
||||||
|
|
||||||
|
color: 'whitesmoke'
|
||||||
|
border.width: 1
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Label {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "image " + index
|
||||||
|
font.pixelSize: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: keepUrlAlive
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
imagesModel.append({
|
||||||
|
imageLink: "",
|
||||||
|
rawLink: `raw link ${index}`
|
||||||
|
})
|
||||||
|
|
||||||
|
Qt.callLater(grabToImage, imageResult => {
|
||||||
|
keepUrlAlive.source = imageResult.url
|
||||||
|
imagesModel.setProperty(index, "imageLink",
|
||||||
|
Qt.resolvedUrl(imageResult.url))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: selectableCheckBox
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
|
text: "selectable"
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolSeparator {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: selectionText
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
|
||||||
|
property string selectionAsString: ""
|
||||||
|
|
||||||
|
text: `selected indexes: [${selectionAsString}]`
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: grid.selection
|
||||||
|
|
||||||
|
function onSelectionChanged() {
|
||||||
|
const indexes = grid.selection.selectedIndexes
|
||||||
|
const rows = indexes.map(idx => idx.row)
|
||||||
|
|
||||||
|
selectionText.selectionAsString = rows.join(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Clear selection"
|
||||||
|
|
||||||
|
onClicked: grid.selection.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImagesGridView {
|
||||||
|
id: grid
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
selectable: selectableCheckBox.checked
|
||||||
|
clip: true
|
||||||
|
model: imagesModel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
id: root
|
id: root
|
||||||
|
@ -10,6 +11,13 @@ ApplicationWindow {
|
||||||
|
|
||||||
property var model
|
property var model
|
||||||
|
|
||||||
|
signal removeLinksRequested(var indexes)
|
||||||
|
signal appendLinksRequested(var links)
|
||||||
|
|
||||||
|
readonly property var urlRegex:
|
||||||
|
/^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/
|
||||||
|
|
||||||
|
|
||||||
SwipeView {
|
SwipeView {
|
||||||
id: topSwipeView
|
id: topSwipeView
|
||||||
|
|
||||||
|
@ -18,13 +26,50 @@ ApplicationWindow {
|
||||||
orientation: Qt.Vertical
|
orientation: Qt.Vertical
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
ImagesGridView {
|
Page {
|
||||||
clip: true
|
ImagesGridView {
|
||||||
model: root.model
|
id: grid
|
||||||
|
|
||||||
onClicked: {
|
anchors.fill: parent
|
||||||
imagesSwipeView.setCurrentIndex(index)
|
|
||||||
topSwipeView.incrementCurrentIndex()
|
clip: true
|
||||||
|
model: root.model
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
imagesSwipeView.setCurrentIndex(index)
|
||||||
|
topSwipeView.incrementCurrentIndex()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: ToolBar {
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: removeButton
|
||||||
|
|
||||||
|
readonly property int selectionCount:
|
||||||
|
grid.selection.selectedIndexes.length
|
||||||
|
|
||||||
|
text: "Remove selected"
|
||||||
|
+ (enabled ? ` (${selectionCount})` : "")
|
||||||
|
enabled: grid.selection.hasSelection
|
||||||
|
|
||||||
|
onClicked: removeConfirmDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolSeparator {}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Add new links"
|
||||||
|
|
||||||
|
onClicked: addNewLinksDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,4 +106,81 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: removeConfirmDialog
|
||||||
|
|
||||||
|
readonly property var selected: grid.selection.selectedIndexes
|
||||||
|
|
||||||
|
anchors.centerIn: Overlay.overlay
|
||||||
|
|
||||||
|
title: "Links removal"
|
||||||
|
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: "Are you sure that you want to remove "
|
||||||
|
+ removeButton.selectionCount + " link(s)?"
|
||||||
|
}
|
||||||
|
|
||||||
|
onAccepted: root.removeLinksRequested(selected.map(idx => idx.row))
|
||||||
|
onSelectedChanged: close()
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: addNewLinksDialog
|
||||||
|
|
||||||
|
anchors.centerIn: Overlay.overlay
|
||||||
|
|
||||||
|
title: "Add new Figma links"
|
||||||
|
standardButtons: Dialog.Save | Dialog.Cancel
|
||||||
|
|
||||||
|
width: parent.width * 0.8
|
||||||
|
height: parent.height * 0.4
|
||||||
|
|
||||||
|
GroupBox {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
title: "Figma links, 1 per line"
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: scrollView
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
contentHeight: linksTextEdit.implicitHeight
|
||||||
|
contentWidth: linksTextEdit.implicitWidth
|
||||||
|
|
||||||
|
TextEdit {
|
||||||
|
id: linksTextEdit
|
||||||
|
|
||||||
|
property var links: []
|
||||||
|
|
||||||
|
width: scrollView.width
|
||||||
|
height: scrollView.height
|
||||||
|
|
||||||
|
font.pixelSize: 13
|
||||||
|
selectByMouse: true
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
const allLines = text.split("\n")
|
||||||
|
const nonEmptyLines = allLines.filter(
|
||||||
|
line => line.trim().length > 0)
|
||||||
|
const trimmed = nonEmptyLines.map(line => line.trim())
|
||||||
|
|
||||||
|
links = trimmed.every(line => root.urlRegex.test(line))
|
||||||
|
? trimmed : []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: Qt.callLater(linksTextEdit.clear)
|
||||||
|
onAccepted: root.appendLinksRequested(linksTextEdit.links)
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
standardButton(Dialog.Save).enabled
|
||||||
|
= Qt.binding(() => linksTextEdit.links.length > 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQml.Models 2.14
|
||||||
|
|
||||||
GridView {
|
GridView {
|
||||||
id: root
|
id: root
|
||||||
|
@ -9,6 +10,15 @@ GridView {
|
||||||
|
|
||||||
signal clicked(int index)
|
signal clicked(int index)
|
||||||
|
|
||||||
|
property bool selectable: true
|
||||||
|
readonly property alias selection: selectionModel
|
||||||
|
|
||||||
|
ItemSelectionModel {
|
||||||
|
id: selectionModel
|
||||||
|
|
||||||
|
model: root.model
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
width: root.cellWidth
|
width: root.cellWidth
|
||||||
height: root.cellHeight
|
height: root.cellHeight
|
||||||
|
@ -50,6 +60,21 @@ GridView {
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.text: model.rawLink
|
ToolTip.text: model.rawLink
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
visible: root.selectable
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
checked: {
|
||||||
|
selectionModel.selection
|
||||||
|
return selectionModel.isSelected(root.model.index(index, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
onToggled: selectionModel.select(root.model.index(index, 0),
|
||||||
|
ItemSelectionModel.Toggle)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ ToolBar {
|
||||||
ToolButton {
|
ToolButton {
|
||||||
id: openFigmaButton
|
id: openFigmaButton
|
||||||
|
|
||||||
enabled: root.figmaPagesCount
|
|
||||||
text: `Figma designs (${root.figmaPagesCount})`
|
text: `Figma designs (${root.figmaPagesCount})`
|
||||||
|
|
||||||
onClicked: root.figmaPreviewClicked()
|
onClicked: root.figmaPreviewClicked()
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
|
|
||||||
#include "figmadecoratormodel.h"
|
#include "figmadecoratormodel.h"
|
||||||
|
#include "figmaio.h"
|
||||||
#include "figmalinks.h"
|
#include "figmalinks.h"
|
||||||
#include "figmalinksmodel.h"
|
#include "figmalinksmodel.h"
|
||||||
#include "figmalinkssource.h"
|
#include "figmalinkssource.h"
|
||||||
|
@ -66,6 +67,25 @@ class FigmaDecoratorModelTest: public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void figmaIOTest() {
|
||||||
|
QTemporaryFile file;
|
||||||
|
QVERIFY(file.open());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
const auto readEmpty = FigmaIO::read(file.fileName());
|
||||||
|
QCOMPARE(readEmpty, {});
|
||||||
|
|
||||||
|
const QMap<QString, QStringList> content = {
|
||||||
|
{ "k_1", { "l_1", "l_2"}},
|
||||||
|
{ "k_2", { "l_3", "l_4"}}
|
||||||
|
};
|
||||||
|
|
||||||
|
FigmaIO::write(file.fileName(), content);
|
||||||
|
const auto readContent = FigmaIO::read(file.fileName());
|
||||||
|
|
||||||
|
QCOMPARE(readContent, content);
|
||||||
|
}
|
||||||
|
|
||||||
void readingFigmaFileTest() {
|
void readingFigmaFileTest() {
|
||||||
FigmaLinksSource figmaLinksSource;
|
FigmaLinksSource figmaLinksSource;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue