8#include <QLoggingCategory>
11#if defined(Q_OS_LINUX)
15#include "RemoteFileSystemModel.h"
17static Q_LOGGING_CATEGORY(log,
"RemoteFileSystem.Model")
20 const QString& szPath, TYPES type)
26 , m_Permissions(QFileDevice::Permission::WriteOwner | QFileDevice::Permission::ReadOwner)
31CRemoteFileSystem::~CRemoteFileSystem()
36#if defined(Q_OS_LINUX)
37void uint32_to_permstr(uint32_t mode,
char *str) {
38 str[0] = S_ISDIR(mode) ?
'd' :
42 S_ISFIFO(mode) ?
'p' :
43 S_ISSOCK(mode) ?
's' :
'-';
46 str[1] = (mode & S_IRUSR) ?
'r' :
'-';
47 str[2] = (mode & S_IWUSR) ?
'w' :
'-';
48 str[3] = (mode & S_IXUSR) ? ((mode & S_ISUID) ?
's' :
'x') : ((mode & S_ISUID) ?
'S' :
'-');
50 str[4] = (mode & S_IRGRP) ?
'r' :
'-';
51 str[5] = (mode & S_IWGRP) ?
'w' :
'-';
52 str[6] = (mode & S_IXGRP) ? ((mode & S_ISGID) ?
's' :
'x') : ((mode & S_ISGID) ?
'S' :
'-');
54 str[7] = (mode & S_IROTH) ?
'r' :
'-';
55 str[8] = (mode & S_IWOTH) ?
'w' :
'-';
56 str[9] = (mode & S_IXOTH) ? ((mode & S_ISVTX) ?
't' :
'x') : ((mode & S_ISVTX) ?
'T' :
'-');
61QVariant CRemoteFileSystem::Data(
int column)
63 switch((ColumnValue)column) {
64 case ColumnValue::Name: {
67 case ColumnValue::Size: {
68 return CStats::Convertbytes(GetSize());
70 case ColumnValue::Type: {
71 if(GetType() & TYPE::FILE)
73 if(GetType() & TYPE::DIR)
75 if(GetType() & TYPE::DRIVE)
77 if(GetType() & TYPE::SYMLINK)
79 if(GetType() & TYPE::SPECIAL)
83 case ColumnValue::LastModified: {
84 return GetLastModified();
86 case ColumnValue::Permission: {
87#if defined(Q_OS_LINUX)
88 quint32 permissions = (quint32)GetPermissions();
90 uint32_to_permstr(permissions, buf);
95 case ColumnValue::Owner:
103QString CRemoteFileSystem::HeaderData(
int section)
105 switch ((ColumnValue)section) {
106 case ColumnValue::Name:
107 return tr(
"File name");
108 case ColumnValue::Size:
109 return tr(
"File size");
110 case ColumnValue::Type:
111 return tr(
"File type");
112 case ColumnValue::LastModified:
113 return tr(
"File last modified time");
114 case ColumnValue::Permission:
115 return tr(
"Permissions");
116 case ColumnValue::Owner:
117 return tr(
"Owner/Group");
124int CRemoteFileSystem::ColumnCount()
127 return (
int)ColumnValue::Permission;
129 return (
int)ColumnValue::End;
133int CRemoteFileSystem::ChildCount()
135 return m_vChild.size();
150 Q_ASSERT_X(pChild->GetType(),
"AppendChild",
"Must set all the properties before call them");
156 if(-1 != IndexOf(pChild->GetPath()))
158 qDebug(log) << pChild->GetName() <<
"is exist";
162 m_vChild.append(pChild);
163 pChild->SetParent(
this);
167int CRemoteFileSystem::RemoveChild(
int index)
169 if(0 > index || m_vChild.size() < index)
171 m_vChild.removeAt(index);
177 if(nIndex < 0 || nIndex >= m_vChild.size())
179 return m_vChild.at(nIndex);
184 return m_vChild.indexOf(pChild);
187int CRemoteFileSystem::IndexOf(
const QString& szPath)
189 for(
int i = 0; i < m_vChild.size(); i++) {
190 auto p = m_vChild[i];
191 if(p && p->GetPath() == szPath)
197int CRemoteFileSystem::IndexOfParent()
201 nIndex= GetParent()->IndexOf(
this);
205QString CRemoteFileSystem::GetPath()
210QString CRemoteFileSystem::GetName()
213 QString szPath = GetPath();
216 int nIndex = szPath.lastIndexOf(
'/');
219 szName = szPath.right(szPath.size() - nIndex - 1);
220 if(GetState() == State::Getting)
221 szName +=
"(" + tr(
"getting") +
" ......)";
225quint64 CRemoteFileSystem::GetSize()
230void CRemoteFileSystem::SetSize(quint64 size)
235bool CRemoteFileSystem::IsDir()
237 return !(GetType() & TYPE::FILE);
240QIcon CRemoteFileSystem::Icon()
242 if(GetType() & TYPE::DRIVE)
243 return QIcon::fromTheme(
"drive-harddisk");
244 if(GetType() & TYPE::DIR)
245 return QIcon::fromTheme(
"folder-remote");
246 if(GetType() & TYPE::FILE || GetType() & TYPE::SPECIAL)
247 return QApplication::style()->standardIcon(QStyle::SP_FileIcon);
248 if(GetType() & TYPE::SYMLINK)
249 return QIcon::fromTheme(
"emblem-symbolic-link");
253CRemoteFileSystem::TYPES CRemoteFileSystem::GetType()
258QDateTime CRemoteFileSystem::GetCreateTime()
263void CRemoteFileSystem::SetCreateTime(
const QDateTime &date)
268QDateTime CRemoteFileSystem::GetLastModified()
270 return m_lastModifed;
273void CRemoteFileSystem::SetLastModified(
const QDateTime &date)
275 m_lastModifed = date;
278QFileDevice::Permissions CRemoteFileSystem::GetPermissions()
280 return m_Permissions;
283void CRemoteFileSystem::SetPermissions(QFileDevice::Permissions privileges)
285 m_Permissions = privileges;
288QString CRemoteFileSystem::GetOwner()
293void CRemoteFileSystem::SetOwner(QString szOwner)
298void CRemoteFileSystem::SetState(State a)
303const CRemoteFileSystem::State CRemoteFileSystem::GetState()
const
308CRemoteFileSystemModel::CRemoteFileSystemModel(
309 QObject *parent, CRemoteFileSystem::TYPES filter)
310 : QAbstractItemModel(parent)
315CRemoteFileSystemModel::~CRemoteFileSystemModel()
317 qDebug(log) << Q_FUNC_INFO;
319 DeleteRemoteFileSystem(m_pRoot);
325 for(
int i = 0; i < p->ChildCount(); i++) {
326 auto pChild = p->GetChild(i);
328 DeleteRemoteFileSystem(pChild);
333QModelIndex CRemoteFileSystemModel::SetRootPath(
const QString &szPath)
335 if(szPath.isEmpty())
return QModelIndex();
336 if(m_pRoot && m_pRoot->GetPath() == szPath)
return QModelIndex();
340 DeleteRemoteFileSystem(m_pRoot);
345 QModelIndex idx = index(m_pRoot);
346 qDebug(log) << Q_FUNC_INFO <<
this << idx << szPath;
355CRemoteFileSystem* CRemoteFileSystemModel::GetRemoteFileSystemFromIndex(
const QModelIndex &index)
const
362CRemoteFileSystem::TYPES CRemoteFileSystemModel::GetFilter()
367QVariant CRemoteFileSystemModel::headerData(
int section, Qt::Orientation orientation,
int role)
const
369 if(Qt::DisplayRole != role)
371 if(Qt::Vertical == orientation) {
372 return QString::number(section + 1);
374 return CRemoteFileSystem::HeaderData(section);
379int CRemoteFileSystemModel::rowCount(
const QModelIndex &parent)
const
383 pItem = GetRemoteFileSystemFromIndex(parent);
387 return pItem->ChildCount();
391int CRemoteFileSystemModel::columnCount(
const QModelIndex &parent)
const
395 pItem = GetRemoteFileSystemFromIndex(parent);
399 return pItem->ColumnCount();
403QVariant CRemoteFileSystemModel::data(
const QModelIndex &index,
int role)
const
408 if (!index.isValid())
410 if (role != Qt::DisplayRole && role != Qt::DecorationRole)
418 if(!(pItem->GetType() & m_Filter))
420 if(Qt::DecorationRole == role && index.column() == 0)
421 return pItem->Icon();
422 if(Qt::DisplayRole == role)
423 return pItem->Data(index.column());
424 if(Qt::ToolTipRole == role)
425 return pItem->GetPath();
429QModelIndex CRemoteFileSystemModel::index(
const QString& szPath)
const
432 qDebug(log) << Q_FUNC_INFO << szPath;
433 QModelIndex idxParent;
434 QModelIndex idx = index(0, 0);
435 while(idx.isValid()) {
436 idx = index(r++, 0, idxParent);
438 QString szDir = pRemoteFileSystem->GetPath();
439 qDebug(log) << szDir << szPath;
442 if(pRemoteFileSystem->GetType() & CRemoteFileSystem::TYPE::FILE) {
443 qDebug(log) << szDir <<
"Is file:";
446 if(szDir.right(1) !=
'/')
448 if(szPath.left(szDir.size()) == szDir) {
449 qDebug(log) <<
"Contain:" << szPath << szDir;
455 return QModelIndex();
458QModelIndex CRemoteFileSystemModel::index(
CRemoteFileSystem* node,
int column)
const
461 if(node == m_pRoot || !parent)
462 return QModelIndex();
463 int row = node->IndexOfParent();
464 return createIndex(row, column, node);
467QModelIndex CRemoteFileSystemModel::index(
int row,
int column,
const QModelIndex &parent)
const
470 if (!hasIndex(row, column, parent))
471 return QModelIndex();
473 pItem = GetRemoteFileSystemFromIndex(parent);
476 if(!pItem)
return QModelIndex();
477 pItem = pItem->GetChild(row);
479 return createIndex(row, column, pItem);
481 return QModelIndex();
484QModelIndex CRemoteFileSystemModel::parent(
const QModelIndex &child)
const
487 if (!child.isValid())
488 return QModelIndex();
491 return QModelIndex();
494 return index(pItemParent);
495 return QModelIndex();
498bool CRemoteFileSystemModel::canFetchMore(
const QModelIndex &parent)
const
500 if(!parent.isValid()) {
501 qDebug(log) <<
"canFetchMore: true" << parent;
508 qDebug(log) <<
"canFetchMore:" << parent <<
"p is nullptr";
511 if(p->GetState() == CRemoteFileSystem::State::No
512 && !(p->GetType() & CRemoteFileSystem::TYPE::FILE)) {
513 qDebug(log) <<
"canFetchMore:" << parent << p->GetPath() <<
"true";
516 qDebug(log) << Q_FUNC_INFO << parent;
520void CRemoteFileSystemModel::fetchMore(
const QModelIndex &parent)
522 qDebug(log) << Q_FUNC_INFO << parent;
523 auto p = GetRemoteFileSystemFromIndex(parent);
527 qCritical(log) <<
"fetchMore:" << parent <<
"The pointer is nullptr";
530 if(p->GetType() & CRemoteFileSystem::TYPE::FILE) {
531 qCritical(log) <<
"fetchMore:" << parent <<
"The node is file";
534 QString szPath = p->GetPath();
535 if(szPath.isEmpty()) {
536 qCritical(log) <<
"fetchMore:" << parent <<
"The path is empty";
539 if(p->GetState() != CRemoteFileSystem::State::No) {
540 qDebug(log) <<
"fetchMore:" << parent << p->GetState() <<
"The state is not NO";
543 p->SetState(CRemoteFileSystem::State::Getting);
544 if(m_GetFolder.indexOf(p) == -1)
545 m_GetFolder.append(p);
547 qDebug(log) <<
"fetchMore:" << parent << p << szPath;
550void CRemoteFileSystemModel::slotGetDir(
552 QVector<QSharedPointer<CRemoteFileSystem> > contents,
556 int nIndex = m_GetFolder.indexOf(p);
558 qDebug(log) <<
"Is not the model";
563 m_GetFolder.removeAt(nIndex);
564 if(!pRemoteFileSystem) {
565 qDebug(log) <<
"Get nullptr";
568 QModelIndex parentIndex;
569 parentIndex = index(pRemoteFileSystem, 0);
570 qDebug(log) << Q_FUNC_INFO << p << p->GetPath() << parentIndex;
571 pRemoteFileSystem->SetState(CRemoteFileSystem::State::Ok);
572 if(contents.size() > 0) {
573 beginInsertRows(parentIndex, 0, contents.size() - 1);
574 foreach(
auto p, contents) {
576 if(!(p->GetType() & GetFilter()))
continue;
579 pRfs->SetSize(p->GetSize());
580 pRfs->SetPermissions(p->GetPermissions());
581 pRfs->SetLastModified(p->GetLastModified());
582 pRfs->SetCreateTime(p->GetCreateTime());
586 emit dataChanged(index(0, 0, index(pRemoteFileSystem)),
587 index(pRemoteFileSystem->ChildCount(), 0, index(pRemoteFileSystem)));
589 emit dataChanged(parentIndex, parentIndex);
592void CRemoteFileSystemModel::CreateDir(QModelIndex index,
const QString &dir)
594 auto p = GetRemoteFileSystemFromIndex(index);
596 if(p && !p->GetPath().isEmpty()) {
597 QString szPath = p->GetPath() +
"/" + dir;
598 if(p->IndexOf(szPath) > -1) {
599 qCritical(log) <<
"The path is exist:" << szPath;
600 QMessageBox::critical(
nullptr, tr(
"Error"), tr(
"The path is exist: %1").arg(szPath));
603 emit sigMakeDir(szPath);
605 p->SetState(CRemoteFileSystem::State::No);
606 fetchMore(index.parent());
610void CRemoteFileSystemModel::RemoveDir(QModelIndex index)
612 auto p = GetRemoteFileSystemFromIndex(index);
613 if(p && !p->GetPath().isEmpty()) {
614 if(QMessageBox::question(
615 nullptr, tr(
"Delete directory"),
616 tr(
"Are you sure you want to delete '%1'?").arg(p->GetPath()),
617 QMessageBox::Yes | QMessageBox::No)
620 if(p->GetType() == CRemoteFileSystem::TYPE::DIR)
621 emit sigRemoveDir(p->GetPath());
623 emit sigRemoveFile(p->GetPath());
625 auto pParent = p->GetParent();
626 if(!pParent) pParent = m_pRoot;
627 pParent->RemoveChild(pParent->IndexOf(p));
628 pParent->SetState(CRemoteFileSystem::State::No);
629 fetchMore(index.parent());
633bool CRemoteFileSystemModel::setData(
const QModelIndex &index,
const QVariant &value,
int role)
635 qDebug(log) << Q_FUNC_INFO << index << value << role;
638 if(Qt::EditRole != role) {
639 return QAbstractItemModel::setData(index, value, role);
641 auto p = GetRemoteFileSystemFromIndex(index);
642 QString szName = value.toString();
643 if(p && !p->GetPath().isEmpty() && p->GetName() != szName) {
644 QFileInfo fi(p->GetPath());
645 szName = fi.path() +
"/" + szName;
646 emit sigRename(p->GetPath(), szName);
648 auto pParent = p->GetParent();
649 if(!pParent) pParent = m_pRoot;
650 pParent->RemoveChild(pParent->IndexOf(p));
651 pParent->SetState(CRemoteFileSystem::State::No);
652 fetchMore(index.parent());
657Qt::ItemFlags CRemoteFileSystemModel::flags(
const QModelIndex &index)
const
659 Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
660 if (!index.isValid())
663 if (index.column() == (
int)CRemoteFileSystem::ColumnValue::Name)
664 return defaultFlags | Qt::ItemIsEditable;
int AppendChild(CRemoteFileSystem *pChild)
Append child.