Resolves 1 conflict (new_docker_build.sh, union of viewer-only + codification options); folds in fixes for pre-existing defects surfaced by the validation runs (KDReports-qt6 wiring, LtsSession RTI linking, LtsFileDialog/WLS/BSM Qt6/RTI API migration, GROUP4 target list, new --cmake_build_flags option); validated with BUILD_RTI=ON BUILD_GRANTLEE=ON in 3 Docker runs (run 3: build green, 6 base-state first-run CTest failures documented).
353 lines
11 KiB
C++
Executable File
353 lines
11 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* from FileManangement - Folder model
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Iuliana Ojog, SLSE, 2017-07-11
|
|
*/
|
|
|
|
#include "lts_dialog_model_folder.h"
|
|
#include <nglwidgets/ngltreeitem.h>
|
|
|
|
#include <FileManagement/flm_translation.h>
|
|
|
|
#include <functional>
|
|
|
|
//#include <QtCore/QDebug>
|
|
|
|
namespace LtsWidgets
|
|
{
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
// DialogModelFolder
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
DialogModelFolder::DialogModelFolder(QObject *parent
|
|
, NGLTreeItem *rootItem
|
|
, const std::shared_ptr<FileManagement::Interface::Dtc> &dtc
|
|
, const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc
|
|
, const QStringList &header)
|
|
: NGLTreeModel(parent, rootItem, header)
|
|
, m_flmDtc(dtc)
|
|
, m_exmDtc(exmDtc)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
QVariant DialogModelFolder::headerData(int section, Qt::Orientation orientation, int role) const
|
|
{
|
|
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
|
|
{
|
|
switch (section)
|
|
{
|
|
case ID:
|
|
return tr("Id");
|
|
case NAME:
|
|
return tr("Folder");
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return NGLTreeModel::headerData(section, orientation, role);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
QVariant DialogModelFolder::data(const QModelIndex &index, int role) const
|
|
{
|
|
if (!index.isValid())
|
|
return {};
|
|
|
|
NGLTreeItem *item = privateData(index);
|
|
if (item->data().canConvert<FileManagement::Folder>())
|
|
{
|
|
FileManagement::Folder folderData = item->data().value<FileManagement::Folder>();
|
|
|
|
switch(role)
|
|
{
|
|
case Qt::DisplayRole:
|
|
{
|
|
switch (index.column())
|
|
{
|
|
case NAME:
|
|
return getFolderName(folderData);
|
|
case ID:
|
|
return folderData.id;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
case Qt::UserRole:
|
|
return folderData.id;
|
|
case Qt::DecorationRole:
|
|
{
|
|
if (folderData.isHidden)
|
|
return item->icon();
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
FileManagement::Folder DialogModelFolder::getFolder(const QModelIndex &idx) const
|
|
{
|
|
return privateData(idx)->data().value<FileManagement::Folder>();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
QString DialogModelFolder::getFolderName(const FileManagement::Folder &folderData) const
|
|
{
|
|
QString folderName = QString::fromStdString(folderData.name);
|
|
if (folderName.startsWith(QStringLiteral("$")))
|
|
{
|
|
folderName.remove(0,1);
|
|
if (folderName.startsWith(QStringLiteral("EX_")))
|
|
{
|
|
int exId = folderName.remove(0,3).toInt();
|
|
return QString::fromStdString(m_exmDtc->exercise(exId).name);
|
|
}
|
|
if (folderName.startsWith(QStringLiteral("PH_")))
|
|
{
|
|
int phId = folderName.remove(0,3).toInt();
|
|
return QString::fromStdString(m_exmDtc->exercisePhase(phId).name);
|
|
}
|
|
}
|
|
return FileManagement::trFolderName(folderName.toStdString());
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
bool DialogModelFolder::isRowRemovable(NGLTreeItem *parentItem) const
|
|
{
|
|
if (!parentItem)
|
|
return false;
|
|
FileManagement::Folder folderData = parentItem->data().value<FileManagement::Folder>();
|
|
return folderData.isEditable;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------------------------------
|
|
bool DialogModelFolder::initModel(int exerciseId, const QVector<FileManagement::MainFolder> &mainFolders)
|
|
{
|
|
NGLTreeModel::resetModel();
|
|
|
|
QMap<qint32,FileManagement::Folder> tmap;
|
|
QHash<int, QModelIndex> parentItemIndexCache;
|
|
QVector<int> idsToExclude;
|
|
|
|
// Dtc per-item callback: return true to stop iteration (iterateUntil), so collect with false.
|
|
// Explicit std::function type disambiguates the void/bool overloads.
|
|
std::function<bool(const FileManagement::Folder &)> cbFolders = [this, exerciseId, &tmap, &idsToExclude, &mainFolders] (const FileManagement::Folder &data)
|
|
{
|
|
if (data.isDeleted)
|
|
return false;
|
|
if (exerciseId > 0)
|
|
{
|
|
QString folderName = QString::fromStdString(data.name);
|
|
if (folderName.startsWith(QStringLiteral("$EX_")))
|
|
{
|
|
int exId = folderName.remove(0, 4).toInt();
|
|
if (exId != exerciseId)
|
|
idsToExclude.append(data.id);
|
|
}
|
|
}
|
|
FileManagement::MainFolder mainFolder = static_cast<FileManagement::MainFolder>(data.path[0]);
|
|
//qCritical() << "Folder = " << data.name << ", mainFolder = " << static_cast<int>(mainFolder);
|
|
if (!mainFolders.contains(mainFolder))
|
|
{
|
|
// qCritical() << "Excluded id = " << data.id;
|
|
idsToExclude.append(data.id);
|
|
}
|
|
|
|
tmap.insert(data.id, data);
|
|
return false;
|
|
};
|
|
m_flmDtc->folders(cbFolders);
|
|
|
|
parentItemIndexCache.insert(0, QModelIndex()); //root
|
|
|
|
for (QMap<qint32, FileManagement::Folder>::const_iterator iter = tmap.constBegin();
|
|
iter != tmap.constEnd(); ++iter)
|
|
{
|
|
int folderId = iter.key();
|
|
int parentId = 0;
|
|
FileManagement::Folder fld = iter.value();
|
|
|
|
if (fld.path.size() > 1)
|
|
{
|
|
parentId = fld.path.at(fld.path.size() - 2);
|
|
int idPos2 = fld.path.at(1);
|
|
if (idsToExclude.contains(idPos2))
|
|
continue;
|
|
}
|
|
else // main Folders
|
|
{
|
|
if (idsToExclude.contains(fld.id))
|
|
continue;
|
|
}
|
|
|
|
QVariant data;
|
|
data.setValue(fld);
|
|
|
|
if (!parentItemIndexCache.contains(parentId))
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
QModelIndex pIndex = parentItemIndexCache.value(parentId);
|
|
int rowPos = -1;
|
|
onInsertRow(rowPos, pIndex, fld);
|
|
parentItemIndexCache.insert(folderId, index(rowPos, 0, pIndex));
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool DialogModelFolder::onInsertRow(int &row, const QModelIndex &parent, const FileManagement::Folder &folderData)
|
|
{
|
|
row = rowCount(parent);
|
|
QVariant data;
|
|
data.setValue(folderData);
|
|
QIcon icon;
|
|
if (folderData.isHidden)
|
|
icon = QIcon(QLatin1String(":/style/lock.svg"));
|
|
NGLTreeItem *item = new NGLTreeItem(data, icon);
|
|
item->setModified(true);
|
|
|
|
return NGLTreeModel::insertRow(row, parent, item);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool DialogModelFolder::onUpdateRow(const QModelIndex &index, const FileManagement::Folder &folderData)
|
|
{
|
|
QVariant data;
|
|
data.setValue(folderData);
|
|
|
|
QIcon icon;
|
|
if (folderData.isHidden)
|
|
icon = QIcon(QLatin1String(":/style/lock.svg"));
|
|
return setItemData(index, data, icon);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool DialogModelFolder::onDeleteRow(const QModelIndex &idx, bool isFirstItem)
|
|
{
|
|
while(rowCount(idx) > 0)
|
|
{
|
|
onDeleteRow(NGLTreeModel::index(0, 0, idx),false);
|
|
}
|
|
if (isFirstItem) //edit mode
|
|
{
|
|
NGLTreeItem *item = privateData(idx);
|
|
FileManagement::Folder data = item->data().value<FileManagement::Folder>();
|
|
data.isDeleted = true;
|
|
}
|
|
removeRow(idx.row(), idx.parent());
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
QModelIndex DialogModelFolder::getIndex(int folderId) const
|
|
{
|
|
QModelIndexList list = match(index(0, 0), Qt::UserRole, QVariant::fromValue(folderId), 1, Qt::MatchRecursive);
|
|
|
|
if (!list.isEmpty())
|
|
return list.first();
|
|
|
|
return {};
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void DialogModelProxyFolder::setSourceModel(QAbstractItemModel *model)
|
|
{
|
|
m_sourceModel = qobject_cast<DialogModelFolder*>(model);
|
|
QSortFilterProxyModel::setSourceModel(model);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool DialogModelProxyFolder::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
|
{
|
|
if (!m_sourceModel || source_left.column() != source_right.column())
|
|
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
|
|
|
const NGLTreeItem *itemLeft = m_sourceModel->privateData(source_left);
|
|
const NGLTreeItem *itemRight = m_sourceModel->privateData(source_right);
|
|
if (!itemLeft || !itemRight)
|
|
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
|
|
|
const FileManagement::Folder folderLeft = itemLeft->data().value<FileManagement::Folder>();
|
|
const FileManagement::Folder folderRight = itemRight->data().value<FileManagement::Folder>();
|
|
|
|
// mainFolder() was part of the legacy Folder API; the generated Folder carries it in path[0]
|
|
const int leftMain = folderLeft.path.empty() ? 0 : static_cast<int>(folderLeft.path[0]);
|
|
const int rightMain = folderRight.path.empty() ? 0 : static_cast<int>(folderRight.path[0]);
|
|
if (leftMain == static_cast<int>(FileManagement::MainFolder::GlobalDocuments) || rightMain == static_cast<int>(FileManagement::MainFolder::GlobalDocuments) ||
|
|
leftMain == static_cast<int>(FileManagement::MainFolder::UserDocuments) || rightMain == static_cast<int>(FileManagement::MainFolder::UserDocuments) ||
|
|
leftMain == static_cast<int>(FileManagement::MainFolder::ExerciseDocuments) || rightMain == static_cast<int>(FileManagement::MainFolder::ExerciseDocuments))
|
|
{
|
|
return leftMain < rightMain;
|
|
}
|
|
|
|
if (folderLeft.name != folderRight.name)
|
|
{
|
|
return (folderLeft.name < folderRight.name);
|
|
}
|
|
|
|
return folderLeft.id < folderRight.id;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void DialogModelProxyFolder::sort(int column, Qt::SortOrder order)
|
|
{
|
|
Qt::SortOrder myOrder = order;
|
|
if (column == 0)
|
|
myOrder = Qt::AscendingOrder;
|
|
QSortFilterProxyModel::sort(column, myOrder);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool DialogModelProxyFolder::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
|
{
|
|
if (!m_sourceModel || !source_parent.isValid())
|
|
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
|
|
|
if (m_operatorId == 0) // no filter for admin
|
|
return true;
|
|
|
|
NGLTreeItem *parent = m_sourceModel->privateData(source_parent);
|
|
if (!parent)
|
|
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
|
|
|
NGLTreeItem *child = parent->child(source_row);
|
|
if (!child)
|
|
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
|
|
|
const FileManagement::Folder data = child->data().value<FileManagement::Folder>();
|
|
if (data.operatorId != m_operatorId)
|
|
{
|
|
// it's user folder -> check if it's in user documents and hide if it's not for the current operator
|
|
for (int p : data.path)
|
|
{
|
|
if (static_cast<FileManagement::MainFolder>(p) == FileManagement::MainFolder::UserDocuments)
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void DialogModelProxyFolder::setOperatorId(int operatorId)
|
|
{
|
|
if (m_operatorId == operatorId)
|
|
return;
|
|
m_operatorId = operatorId;
|
|
beginFilterChange();
|
|
endFilterChange();
|
|
}
|
|
|
|
} // namespace LtsWidgets
|