summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-12-10 13:09:44 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2020-02-04 03:33:16 -0500
commita4624f239fe5d152ec8797c1a3f8c2b2aeaef1ba (patch)
tree1371a463d11f9f7f66eae07daf898b4c1b7cc0c9
parente8027bfeaae9382c99b7e0a0503ec5eae774934f (diff)
split FileTreeModel, initial implementation, some stuff is broken
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/datatab.cpp173
-rw-r--r--src/datatab.h4
-rw-r--r--src/filetree.cpp396
-rw-r--r--src/filetree.h110
-rw-r--r--src/mainwindow.ui14
6 files changed, 540 insertions, 160 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0658da31..ad791e79 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -145,6 +145,7 @@ SET(organizer_SRCS
lootdialog.cpp
filterlist.cpp
datatab.cpp
+ filetree.cpp
shared/windows_error.cpp
shared/error_report.cpp
@@ -270,6 +271,7 @@ SET(organizer_HDRS
json.h
filterlist.h
datatab.h
+ filetree.h
shared/windows_error.h
shared/error_report.h
@@ -401,6 +403,7 @@ set(loot
set(mainwindow
datatab
+ filetree
filterlist
mainwindow
statusbar
diff --git a/src/datatab.cpp b/src/datatab.cpp
index fb42a904..bc0ff455 100644
--- a/src/datatab.cpp
+++ b/src/datatab.cpp
@@ -4,6 +4,7 @@
#include "organizercore.h"
#include "directoryentry.h"
#include "messagedialog.h"
+#include "filetree.h"
#include <log.h>
#include <report.h>
@@ -18,21 +19,24 @@ DataTab::DataTab(
OrganizerCore& core, PluginContainer& pc,
QWidget* parent, Ui::MainWindow* mwui) :
m_core(core), m_pluginContainer(pc), m_archives(false), m_parent(parent),
+ m_model(new FileTreeModel(core)),
ui{
mwui->btnRefreshData, mwui->dataTree,
mwui->conflictsCheckBox, mwui->showArchiveDataCheckBox}
{
+ ui.tree->setModel(m_model);
+
connect(
ui.refresh, &QPushButton::clicked,
[&]{ onRefresh(); });
- connect(
- ui.tree, &QTreeWidget::itemExpanded,
- [&](auto* item){ onItemExpanded(item); });
-
- connect(
- ui.tree, &QTreeWidget::itemActivated,
- [&](auto* item, int col){ onItemActivated(item, col); });
+ //connect(
+ // ui.tree, &QTreeWidget::itemExpanded,
+ // [&](auto* item){ onItemExpanded(item); });
+ //
+ //connect(
+ // ui.tree, &QTreeWidget::itemActivated,
+ // [&](auto* item, int col){ onItemActivated(item, col); });
connect(
ui.tree, &QTreeWidget::customContextMenuRequested,
@@ -64,12 +68,13 @@ void DataTab::activated()
QTreeWidgetItem* DataTab::singleSelection()
{
- const auto sel = ui.tree->selectedItems();
- if (sel.count() != 1) {
- return nullptr;
- }
-
- return sel[0];
+ //const auto sel = ui.tree->selectedItems();
+ //if (sel.count() != 1) {
+ // return nullptr;
+ //}
+ //
+ //return sel[0];
+ return nullptr;
}
void DataTab::openSelection()
@@ -144,21 +149,16 @@ void DataTab::onRefresh()
void DataTab::refreshDataTree()
{
- QIcon folderIcon = (new QFileIconProvider())->icon(QFileIconProvider::Folder);
- QIcon fileIcon = (new QFileIconProvider())->icon(QFileIconProvider::File);
- ui.tree->clear();
- QStringList columns("data");
- columns.append("");
- QTreeWidgetItem *subTree = new QTreeWidgetItem(columns);
- subTree->setData(0, Qt::DecorationRole, (new QFileIconProvider())->icon(QFileIconProvider::Folder));
- updateTo(subTree, L"", *m_core.directoryStructure(), ui.conflicts->isChecked(), &fileIcon, &folderIcon);
- ui.tree->insertTopLevelItem(0, subTree);
- subTree->setExpanded(true);
+ m_model->refresh();
+ ui.tree->expand(m_model->index(0, 0));
}
void DataTab::refreshDataTreeKeepExpandedNodes()
{
- QIcon folderIcon = (new QFileIconProvider())->icon(QFileIconProvider::Folder);
+ //m_model->refreshKeepExpandedNodes();
+ m_model->refresh(); // temp
+
+ /*QIcon folderIcon = (new QFileIconProvider())->icon(QFileIconProvider::Folder);
QIcon fileIcon = (new QFileIconProvider())->icon(QFileIconProvider::File);
QStringList expandedNodes;
QTreeWidgetItemIterator it1(ui.tree, QTreeWidgetItemIterator::NotHidden | QTreeWidgetItemIterator::HasChildren);
@@ -185,7 +185,7 @@ void DataTab::refreshDataTreeKeepExpandedNodes()
current->setExpanded(true);
}
++it2;
- }
+ }*/
}
void DataTab::updateTo(
@@ -193,127 +193,6 @@ void DataTab::updateTo(
const DirectoryEntry &directoryEntry, bool conflictsOnly,
QIcon *fileIcon, QIcon *folderIcon)
{
- bool isDirectory = true;
- //QIcon folderIcon = (new QFileIconProvider())->icon(QFileIconProvider::Folder);
- //QIcon fileIcon = (new QFileIconProvider())->icon(QFileIconProvider::File);
-
- std::wostringstream temp;
- temp << directorySoFar << "\\" << directoryEntry.getName();
- {
- std::vector<DirectoryEntry*>::const_iterator current, end;
- directoryEntry.getSubDirectories(current, end);
- for (; current != end; ++current) {
- QString pathName = QString::fromStdWString((*current)->getName());
- QStringList columns(pathName);
- columns.append("");
- if (!(*current)->isEmpty()) {
- QTreeWidgetItem *directoryChild = new QTreeWidgetItem(columns);
- directoryChild->setData(0, Qt::DecorationRole, *folderIcon);
- directoryChild->setData(0, Qt::UserRole + 3, isDirectory);
-
- if (conflictsOnly || !m_archives) {
- updateTo(directoryChild, temp.str(), **current, conflictsOnly, fileIcon, folderIcon);
- if (directoryChild->childCount() != 0) {
- subTree->addChild(directoryChild);
- }
- else {
- delete directoryChild;
- }
- }
- else {
- QTreeWidgetItem *onDemandLoad = new QTreeWidgetItem(QStringList());
- onDemandLoad->setData(0, Qt::UserRole + 0, "__loaded_on_demand__");
- onDemandLoad->setData(0, Qt::UserRole + 1, QString::fromStdWString(temp.str()));
- onDemandLoad->setData(0, Qt::UserRole + 2, conflictsOnly);
- directoryChild->addChild(onDemandLoad);
- subTree->addChild(directoryChild);
- }
- }
- else {
- QTreeWidgetItem *directoryChild = new QTreeWidgetItem(columns);
- directoryChild->setData(0, Qt::DecorationRole, *folderIcon);
- directoryChild->setData(0, Qt::UserRole + 3, isDirectory);
- subTree->addChild(directoryChild);
- }
- }
- }
-
-
- isDirectory = false;
- {
- for (const FileEntry::Ptr current : directoryEntry.getFiles()) {
- if (conflictsOnly && (current->getAlternatives().size() == 0)) {
- continue;
- }
-
- bool isArchive = false;
- int originID = current->getOrigin(isArchive);
- if (!m_archives && isArchive) {
- continue;
- }
-
- QString fileName = QString::fromStdWString(current->getName());
- QStringList columns(fileName);
- FilesOrigin origin = m_core.directoryStructure()->getOriginByID(originID);
-
- QString source;
- const unsigned int modIndex = ModInfo::getIndex(
- QString::fromStdWString(origin.getName()));
-
- if (modIndex == UINT_MAX) {
- source = UnmanagedModName();
- } else {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
- source = modInfo->name();
- }
-
- std::pair<std::wstring, int> archive = current->getArchive();
- if (archive.first.length() != 0) {
- source.append(" (").append(QString::fromStdWString(archive.first)).append(")");
- }
- columns.append(source);
- QTreeWidgetItem *fileChild = new QTreeWidgetItem(columns);
- if (isArchive) {
- QFont font = fileChild->font(0);
- font.setItalic(true);
- fileChild->setFont(0, font);
- fileChild->setFont(1, font);
- } else if (fileName.endsWith(ModInfo::s_HiddenExt)) {
- QFont font = fileChild->font(0);
- font.setStrikeOut(true);
- fileChild->setFont(0, font);
- fileChild->setFont(1, font);
- }
- fileChild->setData(0, Qt::UserRole, QString::fromStdWString(current->getFullPath()));
- fileChild->setData(0, Qt::DecorationRole, *fileIcon);
- fileChild->setData(0, Qt::UserRole + 3, isDirectory);
- fileChild->setData(0, Qt::UserRole + 1, isArchive);
- fileChild->setData(1, Qt::UserRole, source);
- fileChild->setData(1, Qt::UserRole + 1, originID);
-
- std::vector<std::pair<int, std::pair<std::wstring, int>>> alternatives = current->getAlternatives();
-
- if (!alternatives.empty()) {
- std::wostringstream altString;
- altString << tr("Also in: <br>").toStdWString();
- for (std::vector<std::pair<int, std::pair<std::wstring, int>>>::iterator altIter = alternatives.begin();
- altIter != alternatives.end(); ++altIter) {
- if (altIter != alternatives.begin()) {
- altString << " , ";
- }
- altString << "<span style=\"white-space: nowrap;\"><i>" << m_core.directoryStructure()->getOriginByID(altIter->first).getName() << "</font></span>";
- }
- fileChild->setToolTip(1, QString("%1").arg(QString::fromStdWString(altString.str())));
- fileChild->setForeground(1, QBrush(Qt::red));
- } else {
- fileChild->setToolTip(1, tr("No conflict"));
- }
- subTree->addChild(fileChild);
- }
- }
-
-
- //subTree->sortChildren(0, Qt::AscendingOrder);
}
void DataTab::onItemExpanded(QTreeWidgetItem* item)
@@ -369,7 +248,7 @@ void DataTab::onItemActivated(QTreeWidgetItem *item, int column)
void DataTab::onContextMenu(const QPoint &pos)
{
- auto* item = ui.tree->itemAt(pos.x(), pos.y());
+ QTreeWidgetItem* item = nullptr;//ui.tree->itemAt(pos.x(), pos.y());
QMenu menu;
if ((item != nullptr) && (item->childCount() == 0)
diff --git a/src/datatab.h b/src/datatab.h
index 27d36936..8754c12d 100644
--- a/src/datatab.h
+++ b/src/datatab.h
@@ -8,6 +8,7 @@ namespace Ui { class MainWindow; }
class OrganizerCore;
class Settings;
class PluginContainer;
+class FileTreeModel;
namespace MOShared { class DirectoryEntry; }
@@ -36,7 +37,7 @@ private:
struct DataTabUi
{
QPushButton* refresh;
- QTreeWidget* tree;
+ QTreeView* tree;
QCheckBox* conflicts;
QCheckBox* archives;
};
@@ -45,6 +46,7 @@ private:
PluginContainer& m_pluginContainer;
bool m_archives;
QWidget* m_parent;
+ FileTreeModel* m_model;
DataTabUi ui;
std::vector<QTreeWidgetItem*> m_removeLater;
diff --git a/src/filetree.cpp b/src/filetree.cpp
new file mode 100644
index 00000000..cfc73de0
--- /dev/null
+++ b/src/filetree.cpp
@@ -0,0 +1,396 @@
+#include "filetree.h"
+#include "organizercore.h"
+
+using namespace MOShared;
+
+// in mainwindow.cpp
+QString UnmanagedModName();
+
+
+FileTreeItem::FileTreeItem()
+ : m_flags(NoFlags), m_loaded(false)
+{
+}
+
+FileTreeItem::FileTreeItem(
+ FileTreeItem* parent,
+ std::wstring virtualParentPath, std::wstring realPath, Flags flags,
+ std::wstring file, std::wstring mod) :
+ m_parent(parent),
+ m_virtualParentPath(QString::fromStdWString(virtualParentPath)),
+ m_realPath(QString::fromStdWString(realPath)),
+ m_flags(flags),
+ m_file(QString::fromStdWString(file)),
+ m_mod(QString::fromStdWString(mod)),
+ m_loaded(false)
+{
+}
+
+void FileTreeItem::add(std::unique_ptr<FileTreeItem> child)
+{
+ m_children.push_back(std::move(child));
+}
+
+const std::vector<std::unique_ptr<FileTreeItem>>& FileTreeItem::children() const
+{
+ return m_children;
+}
+
+FileTreeItem* FileTreeItem::parent()
+{
+ return m_parent;
+}
+
+const QString& FileTreeItem::filename() const
+{
+ return m_file;
+}
+
+const QString& FileTreeItem::mod() const
+{
+ return m_mod;
+}
+
+bool FileTreeItem::isFromArchive() const
+{
+ return (m_flags & FromArchive);
+}
+
+bool FileTreeItem::isHidden() const
+{
+ return m_file.endsWith(ModInfo::s_HiddenExt);
+}
+
+bool FileTreeItem::isConflicted() const
+{
+ return (m_flags & Conflicted);
+}
+
+QFileIconProvider::IconType FileTreeItem::icon() const
+{
+ if (m_flags & Directory) {
+ return QFileIconProvider::Folder;
+ } else {
+ return QFileIconProvider::File;
+ }
+}
+
+void FileTreeItem::setLoaded(bool b)
+{
+ m_loaded = b;
+}
+
+
+
+FileTreeModel::FileTreeModel(OrganizerCore& core, QObject* parent)
+ : QAbstractItemModel(parent), m_core(core), m_flags(NoFlags)
+{
+ QFileIconProvider provider;
+ m_fileIcon = provider.icon(QFileIconProvider::File);
+ m_directoryIcon = provider.icon(QFileIconProvider::Folder);
+}
+
+void FileTreeModel::setFlags(Flags f)
+{
+ m_flags = f;
+}
+
+bool FileTreeModel::showConflicts() const
+{
+ return (m_flags & Conflicts);
+}
+
+bool FileTreeModel::showArchives() const
+{
+ return (m_flags & Archives);
+}
+
+void FileTreeModel::refresh()
+{
+ m_root = {nullptr, L"", L"", FileTreeItem::Directory, L"Data", L""};
+
+ fill(m_root, *m_core.directoryStructure(), L"");
+ m_root.setLoaded(true);
+}
+
+void FileTreeModel::fill(
+ FileTreeItem& parentItem, const MOShared::DirectoryEntry& parentEntry,
+ const std::wstring& parentPath)
+{
+ const std::wstring path = parentPath + L"\\" + parentEntry.getName();
+ bool isDirectory = true;
+
+
+ {
+ std::vector<DirectoryEntry*>::const_iterator begin, end;
+ parentEntry.getSubDirectories(begin, end);
+ fillDirectories(parentItem, path, begin, end);
+ }
+
+ {
+ fillFiles(parentItem, path, parentEntry.getFiles());
+ }
+}
+
+void FileTreeModel::fillDirectories(
+ FileTreeItem& parentItem, const std::wstring& path,
+ DirectoryIterator begin, DirectoryIterator end)
+{
+ const bool isDirectory = true;
+
+ for (auto itor=begin; itor!=end; ++itor) {
+ const auto& dir = **itor;
+
+ auto child = std::make_unique<FileTreeItem>(
+ &parentItem, path, L"", FileTreeItem::Directory, dir.getName(), L"");
+
+ if (dir.isEmpty()) {
+ child->setLoaded(true);
+ } else if (showConflicts() || !showArchives()) {
+ fill(*child, dir, path);
+ }
+
+ parentItem.add(std::move(child));
+ }
+}
+
+void FileTreeModel::fillFiles(
+ FileTreeItem& parentItem, const std::wstring& path,
+ const std::vector<FileEntry::Ptr>& files)
+{
+ const bool isDirectory = false;
+
+ for (auto&& file : files) {
+ if (showConflicts() && (file->getAlternatives().size() == 0)) {
+ continue;
+ }
+
+ bool isArchive = false;
+ int originID = file->getOrigin(isArchive);
+ if (!showArchives() && isArchive) {
+ continue;
+ }
+
+ FileTreeItem::Flags flags = FileTreeItem::NoFlags;
+
+ if (isArchive) {
+ flags |= FileTreeItem::FromArchive;
+ }
+
+ if (!file->getAlternatives().empty()) {
+ flags |= FileTreeItem::Conflicted;
+ }
+
+ parentItem.add(std::make_unique<FileTreeItem>(
+ &parentItem, path, file->getFullPath(), flags, file->getName(),
+ makeModName(*file, originID)));
+ }
+}
+
+std::wstring FileTreeModel::makeModName(const FileEntry& file, int originID) const
+{
+ const auto origin = m_core.directoryStructure()->getOriginByID(originID);
+ return origin.getName();
+
+ //const auto index = ModInfo::getIndex(QString::fromStdWString(origin.getName()));
+ //if (index == UINT_MAX) {
+ // return UnmanagedModName();
+ //}
+ //
+ //std::wstring name = ModInfo::getByIndex(index)->name();
+ //
+ //std::pair<std::wstring, int> archive = file.getArchive();
+ //if (archive.first.length() != 0) {
+ // name += L" (" + archive.first + L")";
+ //}
+ //
+ //return name;
+}
+
+FileTreeItem* FileTreeModel::itemFromIndex(const QModelIndex& index) const
+{
+ auto* data = index.internalPointer();
+ if (!data) {
+ return nullptr;
+ }
+
+ return static_cast<FileTreeItem*>(data);
+}
+
+QModelIndex FileTreeModel::index(int row, int col, const QModelIndex& parentIndex) const
+{
+ FileTreeItem* parent = nullptr;
+
+ if (!parentIndex.isValid()) {
+ parent = &m_root;
+ } else {
+ parent = itemFromIndex(parentIndex);
+ }
+
+ if (!parent) {
+ return {};
+ }
+
+ if (static_cast<std::size_t>(row) >= parent->children().size()) {
+ return {};
+ }
+
+ if (col >= columnCount({})) {
+ return {};
+ }
+
+ auto* item = parent->children()[static_cast<std::size_t>(row)].get();
+ return createIndex(row, col, item);
+}
+
+QModelIndex FileTreeModel::parent(const QModelIndex& index) const
+{
+ if (!index.isValid()) {
+ return {};
+ }
+
+ auto* item = itemFromIndex(index);
+ if (!item) {
+ return {};
+ }
+
+ auto* parent = item->parent();
+ if (!parent) {
+ return {};
+ }
+
+ int row = 0;
+ for (auto&& child : parent->children()) {
+ if (child.get() == item) {
+ return createIndex(row, 0, parent);
+ }
+
+ ++row;
+ }
+
+ return {};
+}
+
+int FileTreeModel::rowCount(const QModelIndex& parent) const
+{
+ if (!parent.isValid()) {
+ return static_cast<int>(m_root.children().size());
+ } else {
+ if (auto* item=itemFromIndex(parent)) {
+ return static_cast<int>(item->children().size());
+ }
+ }
+
+ return 0;
+}
+
+int FileTreeModel::columnCount(const QModelIndex&) const
+{
+ return 2;
+}
+
+QVariant FileTreeModel::data(const QModelIndex& index, int role) const
+{
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ {
+ if (auto* item=itemFromIndex(index)) {
+ if (index.column() == 0) {
+ return item->filename();
+ } else if (index.column() == 1) {
+ return item->mod();
+ }
+ }
+
+ break;
+ }
+
+ case Qt::FontRole:
+ {
+ if (auto* item=itemFromIndex(index)) {
+ QFont f;
+
+ if (item->isFromArchive()) {
+ f.setItalic(true);
+ } else if (item->isHidden()) {
+ f.setStrikeOut(true);
+ }
+
+ return f;
+ }
+
+ break;
+ }
+
+ case Qt::ToolTipRole:
+ {
+ /*
+ const auto alternatives = file->getAlternatives();
+
+ if (!alternatives.empty()) {
+ std::wostringstream altString;
+ altString << tr("Also in: <br>").toStdWString();
+ for (std::vector<std::pair<int, std::pair<std::wstring, int>>>::iterator altIter = alternatives.begin();
+ altIter != alternatives.end(); ++altIter) {
+ if (altIter != alternatives.begin()) {
+ altString << " , ";
+ }
+ altString << "<span style=\"white-space: nowrap;\"><i>" << m_core.directoryStructure()->getOriginByID(altIter->first).getName() << "</font></span>";
+ }
+ fileChild->setToolTip(1, QString("%1").arg(QString::fromStdWString(altString.str())));
+ fileChild->setForeground(1, QBrush(Qt::red));
+ } else {
+ fileChild->setToolTip(1, tr("No conflict"));
+ }
+ */
+
+ break;
+ }
+
+ case Qt::ForegroundRole:
+ {
+ if (index.column() == 1) {
+ if (auto* item=itemFromIndex(index)) {
+ if (item->isConflicted()) {
+ return QBrush(Qt::red);
+ }
+ }
+ }
+
+ break;
+ }
+
+ case Qt::DecorationRole:
+ {
+ if (index.column() == 0) {
+ if (auto* item=itemFromIndex(index)) {
+ const auto iconType = item->icon();
+
+ if (iconType == QFileIconProvider::File) {
+ return m_fileIcon;
+ } else if (iconType == QFileIconProvider::Folder) {
+ return m_directoryIcon;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+
+ return {};
+}
+
+QVariant FileTreeModel::headerData(int i, Qt::Orientation ori, int role) const
+{
+ if (role == Qt::DisplayRole) {
+ if (i == 0) {
+ return tr("File");
+ } else if (i == 1) {
+ return tr("Mod");
+ }
+ }
+
+ return {};
+}
diff --git a/src/filetree.h b/src/filetree.h
new file mode 100644
index 00000000..a9eac64e
--- /dev/null
+++ b/src/filetree.h
@@ -0,0 +1,110 @@
+#include "directoryentry.h"
+#include <QAbstractItemModel>
+#include <QFileIconProvider>
+
+class OrganizerCore;
+
+class FileTreeItem
+{
+public:
+ enum Flag
+ {
+ NoFlags = 0x00,
+ Directory = 0x01,
+ FromArchive = 0x02,
+ Conflicted = 0x04
+ };
+
+ Q_DECLARE_FLAGS(Flags, Flag);
+
+ FileTreeItem();
+ FileTreeItem(
+ FileTreeItem* parent,
+ std::wstring virtualParentPath, std::wstring realPath, Flags flags,
+ std::wstring file, std::wstring mod);
+
+ FileTreeItem(const FileTreeItem&) = delete;
+ FileTreeItem& operator=(const FileTreeItem&) = delete;
+ FileTreeItem(FileTreeItem&&) = default;
+ FileTreeItem& operator=(FileTreeItem&&) = default;
+
+ void add(std::unique_ptr<FileTreeItem> child);
+ const std::vector<std::unique_ptr<FileTreeItem>>& children() const;
+
+ FileTreeItem* parent();
+ const QString& filename() const;
+ const QString& mod() const;
+ bool isFromArchive() const;
+ bool isHidden() const;
+ bool isConflicted() const;;
+ QFileIconProvider::IconType icon() const;
+
+ void setLoaded(bool b);
+
+private:
+ FileTreeItem* m_parent;
+ QString m_virtualParentPath;
+ QString m_realPath;
+ Flags m_flags;
+ QString m_file;
+ QString m_mod;
+ bool m_loaded;
+ std::vector<std::unique_ptr<FileTreeItem>> m_children;
+};
+
+
+class FileTreeModel : public QAbstractItemModel
+{
+ Q_OBJECT;
+
+public:
+ enum Flag
+ {
+ NoFlags = 0x00,
+ Conflicts = 0x01,
+ Archives = 0x02
+ };
+
+ Q_DECLARE_FLAGS(Flags, Flag);
+
+ FileTreeModel(OrganizerCore& core, QObject* parent=nullptr);
+
+ void setFlags(Flags f);
+ void refresh();
+
+ QModelIndex index(int row, int col, const QModelIndex& parent={}) const override;
+ QModelIndex parent(const QModelIndex& index) const override;
+ int rowCount(const QModelIndex& parent={}) const override;
+ int columnCount(const QModelIndex& parent={}) const override;
+ QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const override;
+ QVariant headerData(int i, Qt::Orientation ori, int role=Qt::DisplayRole) const override;
+
+private:
+ using DirectoryIterator = std::vector<MOShared::DirectoryEntry*>::const_iterator;
+ OrganizerCore& m_core;
+ mutable FileTreeItem m_root;
+ Flags m_flags;
+ QIcon m_fileIcon, m_directoryIcon;
+
+ bool showConflicts() const;
+ bool showArchives() const;
+
+ void fill(
+ FileTreeItem& parentItem, const MOShared::DirectoryEntry& parentEntry,
+ const std::wstring& parentPath);
+
+ void fillDirectories(
+ FileTreeItem& parentItem, const std::wstring& path,
+ DirectoryIterator begin, DirectoryIterator end);
+
+ void fillFiles(
+ FileTreeItem& parentItem, const std::wstring& path,
+ const std::vector<MOShared::FileEntry::Ptr>& files);
+
+ std::wstring makeModName(const MOShared::FileEntry& file, int originID) const;
+
+ FileTreeItem* itemFromIndex(const QModelIndex& index) const;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(FileTreeModel::Flags);
+Q_DECLARE_OPERATORS_FOR_FLAGS(FileTreeItem::Flags);
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index d0daafc0..b27122ef 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -1075,7 +1075,7 @@ p, li { white-space: pre-wrap; }
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
- <widget class="QTreeWidget" name="dataTree">
+ <widget class="QTreeView" name="dataTree">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
@@ -1088,19 +1088,9 @@ p, li { white-space: pre-wrap; }
<property name="uniformRowHeights">
<bool>true</bool>
</property>
- <attribute name="headerDefaultSectionSize">
+ <attribute name="headerMinimumSectionSize">
<number>400</number>
</attribute>
- <column>
- <property name="text">
- <string>File</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Mod</string>
- </property>
- </column>
</widget>
</item>
</layout>