Use tree widget instead of list widget

This commit is contained in:
Ivan Romanov 2019-05-25 22:45:35 +05:00
parent 6637219751
commit 797a0f2258
No known key found for this signature in database
GPG Key ID: 67DB60255E9BA652
3 changed files with 128 additions and 67 deletions

View File

@ -25,6 +25,11 @@
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QFileDialog> #include <QFileDialog>
#include <QFileInfo>
#define QS(str) QStringLiteral(str)
#define QSU(str) QString::fromUtf8(str)
#define QSL(str) QString::fromLatin1(str)
Dialog::Dialog(QWidget *parent) Dialog::Dialog(QWidget *parent)
: QDialog(parent) : QDialog(parent)
@ -32,7 +37,7 @@ Dialog::Dialog(QWidget *parent)
{ {
ui->setupUi(this); ui->setupUi(this);
connect(ui->lwCursors, &QListWidget::currentTextChanged, this, &Dialog::showCursor); connect(ui->twCursors, &QTreeWidget::currentItemChanged, this, &Dialog::showCursor);
connect(ui->pbOpenFolder, &QPushButton::clicked, this, &Dialog::openFolder); connect(ui->pbOpenFolder, &QPushButton::clicked, this, &Dialog::openFolder);
} }
@ -43,20 +48,26 @@ Dialog::~Dialog()
void Dialog::openFolder() void Dialog::openFolder()
{ {
QString dirPath = QFileDialog::getExistingDirectory(this); QString path = QFileDialog::getExistingDirectory(this);
if (dirPath.isEmpty()) { if (path.isEmpty()) {
return; return;
} }
QDir dir(dirPath); openFolderPath(path);
QStringList fileList = dir.entryList(QDir::Filter::Files); }
_cursorFileList.clear(); void Dialog::openFolderPath(const QString &path)
{
QDir dir(path);
for (const QString &fileName: fileList) { QFileInfoList fileList = dir.entryInfoList(QDir::Filter::Files);
QFile file(dir.absoluteFilePath(fileName));
_cursorFileMap.clear();
for (const QFileInfo &fileInfo: fileList) {
QFile file(fileInfo.absoluteFilePath());
if (!file.open(QIODevice::OpenModeFlag::ReadOnly)) { if (!file.open(QIODevice::OpenModeFlag::ReadOnly)) {
continue; continue;
} }
@ -77,7 +88,14 @@ void Dialog::openFolder()
CursorFile cursorFile; CursorFile cursorFile;
cursorFile.name = fileName; cursorFile.name = fileInfo.fileName();
QFileInfo fi = fileInfo;
while (fi.isSymLink()) {
fi = QFileInfo(fi.symLinkTarget());
}
cursorFile.realName = fi.fileName();
for (quint32 i = 0; i < ntoc; ++i) { for (quint32 i = 0; i < ntoc; ++i) {
quint32 type; quint32 type;
@ -121,7 +139,7 @@ void Dialog::openFolder()
cursor.hotSpot = QPoint(static_cast<int>(imgXhot), static_cast<int>(imgYhot)); cursor.hotSpot = QPoint(static_cast<int>(imgXhot), static_cast<int>(imgYhot));
cursor.size = imgSubtype; cursor.size = imgSubtype;
QString key = QStringLiteral("%1").arg(static_cast<int>(subtype), 3, 10, QLatin1Char('0')); QString key = QS("%1").arg(static_cast<int>(subtype), 3, 10, QLatin1Char('0'));
cursorFile.cursorMap.insertMulti(key, cursor); cursorFile.cursorMap.insertMulti(key, cursor);
file.seek(tocPos); file.seek(tocPos);
@ -152,23 +170,23 @@ void Dialog::openFolder()
switch (subtype) { switch (subtype) {
case 1: case 1:
if (!cursorFile.copyright.isEmpty()) { if (!cursorFile.copyright.isEmpty()) {
cursorFile.copyright += QStringLiteral("\n"); cursorFile.copyright += QS("\n");
} }
cursorFile.copyright += QString::fromUtf8(commData); cursorFile.copyright += QSU(commData);
break; break;
case 2: case 2:
if (!cursorFile.license.isEmpty()) { if (!cursorFile.license.isEmpty()) {
cursorFile.license += QStringLiteral("\n"); cursorFile.license += QS("\n");
} }
cursorFile.license += QString::fromUtf8(commData); cursorFile.license += QSU(commData);
break; break;
case 3: case 3:
if (!cursorFile.other.isEmpty()) { if (!cursorFile.other.isEmpty()) {
cursorFile.other += QStringLiteral("\n"); cursorFile.other += QS("\n");
} }
cursorFile.other += QString::fromUtf8(commData); cursorFile.other += QSU(commData);
break; break;
default: default:
@ -179,59 +197,79 @@ void Dialog::openFolder()
} }
} }
_cursorFileList << cursorFile; _cursorFileMap.insert(cursorFile.name, cursorFile);
} }
ui->lwCursors->clear(); ui->twCursors->clear();
QList<QTreeWidgetItem*> topLevelItems;
QStringList nameList; QStringList nameList;
for (const CursorFile &cursorFile: _cursorFileList) { for (const CursorFile &cursorFile: _cursorFileMap) {
nameList << cursorFile.name; if (cursorFile.realName == cursorFile.name) {
QTreeWidgetItem *item = new QTreeWidgetItem({cursorFile.name});
topLevelItems << item;
}
} }
ui->lwCursors->addItems(nameList); for (const CursorFile &cursorFile: _cursorFileMap) {
if (cursorFile.realName != cursorFile.name) {
for (QTreeWidgetItem *topLevel: topLevelItems) {
if (topLevel->text(0) == cursorFile.realName) {
QTreeWidgetItem *item = new QTreeWidgetItem(topLevel, {cursorFile.name});
topLevelItems << item;
}
}
}
} }
void Dialog::showCursor(const QString &fileName) ui->twCursors->addTopLevelItems(topLevelItems);
}
void Dialog::showCursor(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{ {
CursorFile foundCursorFile; if (!current) {
for (const CursorFile &cursorFile: _cursorFileList) {
if (cursorFile.name == fileName) {
foundCursorFile = cursorFile;
break;
}
}
if(foundCursorFile.name.isEmpty()) {
ui->teCursorInfo->clear(); ui->teCursorInfo->clear();
return; return;
} }
QString msg = "<html><body>"; CursorFile currentCursorFile = _cursorFileMap.value(current->text(0));
CursorFile prevCursorFile = previous ? _cursorFileMap.value(previous->text(0)) : CursorFile();
QStringList keys = foundCursorFile.cursorMap.keys(); if(currentCursorFile.name.isEmpty()) {
ui->teCursorInfo->clear();
return;
}
if (prevCursorFile.realName == currentCursorFile.realName) {
return;
}
if (currentCursorFile.cachedCursors.isEmpty()) {
currentCursorFile.cachedCursors = "<html><body>";
QStringList keys = currentCursorFile.cursorMap.keys();
keys.removeDuplicates(); keys.removeDuplicates();
keys.sort(); keys.sort();
if (!foundCursorFile.copyright.isEmpty()) { if (!currentCursorFile.copyright.isEmpty()) {
msg += QStringLiteral("Copyright: %1<br/>").arg(foundCursorFile.copyright); currentCursorFile.cachedCursors += QS("Copyright: %1<br/>").arg(currentCursorFile.copyright);
} }
if (!foundCursorFile.license.isEmpty()) { if (!currentCursorFile.license.isEmpty()) {
msg += QStringLiteral("License: %1<br/>").arg(foundCursorFile.license); currentCursorFile.cachedCursors += QS("License: %1<br/>").arg(currentCursorFile.license);
} }
if (!foundCursorFile.other.isEmpty()) { if (!currentCursorFile.other.isEmpty()) {
msg += QStringLiteral("Other: %1<br/>").arg(foundCursorFile.other); currentCursorFile.cachedCursors += QS("Other: %1<br/>").arg(currentCursorFile.other);
} }
for (const QString &key: keys) { for (const QString &key: keys) {
QList<Cursor> cursorList = foundCursorFile.cursorMap.values(key); QList<Cursor> cursorList = currentCursorFile.cursorMap.values(key);
msg += "<p>"; currentCursorFile.cachedCursors += "<p>";
Cursor firstCursor = cursorList.first(); Cursor firstCursor = cursorList.first();
msg += QStringLiteral("Nominal size: %1. Image size: %2x%3. Hot spot: %4x%5<br/>").arg(QString::number(firstCursor.size), currentCursorFile.cachedCursors += QS("Nominal size: %1. Image size: %2x%3. Hot spot: %4x%5<br/>").arg(QString::number(firstCursor.size),
QString::number(firstCursor.image.width()), QString::number(firstCursor.image.height()), QString::number(firstCursor.image.width()), QString::number(firstCursor.image.height()),
QString::number(firstCursor.hotSpot.x()), QString::number(firstCursor.hotSpot.y())); QString::number(firstCursor.hotSpot.x()), QString::number(firstCursor.hotSpot.y()));
for (const Cursor &cursor: cursorList) { for (const Cursor &cursor: cursorList) {
@ -241,12 +279,22 @@ void Dialog::showCursor(const QString &fileName)
imgBa = imgBa.toBase64(); imgBa = imgBa.toBase64();
msg += "<img src=\"data:image/png;base64, " + QString::fromLatin1(imgBa) + "\"/>"; currentCursorFile.cachedCursors += "<img src=\"data:image/png;base64, " + QSL(imgBa) + "\"/>";
} }
msg += "</p>"; currentCursorFile.cachedCursors += "</p>";
} }
msg += "</body></html>"; currentCursorFile.cachedCursors += "</body></html>";
ui->teCursorInfo->setHtml(msg); QMutableMapIterator<QString, CursorFile> it = _cursorFileMap;
QString realName = currentCursorFile.realName.isEmpty() ? currentCursorFile.name : currentCursorFile.realName;
while (it.hasNext()) {
CursorFile &cursorFile = it.next().value();
if (cursorFile.realName == currentCursorFile.realName) {
cursorFile.cachedCursors = currentCursorFile.cachedCursors;
}
}
}
ui->teCursorInfo->setHtml(currentCursorFile.cachedCursors);
} }

View File

@ -24,6 +24,7 @@
#include <QList> #include <QList>
#include <QMap> #include <QMap>
#include <QString> #include <QString>
#include <QTreeWidgetItem>
namespace Ui { class Dialog; } namespace Ui { class Dialog; }
@ -37,10 +38,12 @@ struct Cursor
struct CursorFile struct CursorFile
{ {
QString name; QString name;
QString realName;
QString license; QString license;
QString copyright; QString copyright;
QString other; QString other;
QMap<QString, Cursor> cursorMap; QMap<QString, Cursor> cursorMap;
QString cachedCursors;
}; };
class Dialog : public QDialog class Dialog : public QDialog
@ -52,10 +55,11 @@ public:
~Dialog(); ~Dialog();
void openFolder(); void openFolder();
void showCursor(const QString &fileName); void openFolderPath(const QString &path);
void showCursor(QTreeWidgetItem *current, QTreeWidgetItem *previous);
private: private:
Ui::Dialog *ui; Ui::Dialog *ui;
QList<CursorFile> _cursorFileList; QMap<QString, CursorFile> _cursorFileMap;
}; };

View File

@ -63,7 +63,16 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<widget class="QListWidget" name="lwCursors"/> <widget class="QTreeWidget" name="twCursors">
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
<widget class="QTextEdit" name="teCursorInfo"> <widget class="QTextEdit" name="teCursorInfo">
<property name="readOnly"> <property name="readOnly">
<bool>true</bool> <bool>true</bool>