8#include <QLoggingCategory>
11#if defined(Q_OS_LINUX)
16#include "RemoteFileSystemModel.h"
18static Q_LOGGING_CATEGORY(log,
"RemoteFileSystem.Model")
23 const QString& szPath, TYPES type)
29 , m_Permissions(QFileDevice::Permission::WriteOwner | QFileDevice::Permission::ReadOwner)
34CRemoteFileSystem::~CRemoteFileSystem()
41 m_pParent = file.m_pParent;
42 m_vChild = file.m_vChild;
43 m_szPath = file.m_szPath;
44 m_nSize = file.m_nSize;
46 m_createTime = file.m_createTime;
47 m_lastModifed = file.m_lastModifed;
48 m_Permissions = file.m_Permissions;
49 m_szOwner = file.m_szOwner;
50 m_State = file.m_State;
53#if defined(Q_OS_LINUX)
54void uint32_to_permstr(uint32_t mode,
char *str) {
55 str[0] = S_ISDIR(mode) ?
'd' :
59 S_ISFIFO(mode) ?
'p' :
60 S_ISSOCK(mode) ?
's' :
'-';
63 str[1] = (mode & S_IRUSR) ?
'r' :
'-';
64 str[2] = (mode & S_IWUSR) ?
'w' :
'-';
65 str[3] = (mode & S_IXUSR) ? ((mode & S_ISUID) ?
's' :
'x') : ((mode & S_ISUID) ?
'S' :
'-');
67 str[4] = (mode & S_IRGRP) ?
'r' :
'-';
68 str[5] = (mode & S_IWGRP) ?
'w' :
'-';
69 str[6] = (mode & S_IXGRP) ? ((mode & S_ISGID) ?
's' :
'x') : ((mode & S_ISGID) ?
'S' :
'-');
71 str[7] = (mode & S_IROTH) ?
'r' :
'-';
72 str[8] = (mode & S_IWOTH) ?
'w' :
'-';
73 str[9] = (mode & S_IXOTH) ? ((mode & S_ISVTX) ?
't' :
'x') : ((mode & S_ISVTX) ?
'T' :
'-');
78QVariant CRemoteFileSystem::Data(
int column)
80 switch((ColumnValue)column) {
81 case ColumnValue::Name: {
84 case ColumnValue::Size: {
85 return CStats::Convertbytes(GetSize());
87 case ColumnValue::Type: {
88 if(GetType() & TYPE::FILE)
90 if(GetType() & TYPE::DIR)
92 if(GetType() & TYPE::DRIVE)
94 if(GetType() & TYPE::SYMLINK)
96 if(GetType() & TYPE::SPECIAL)
100 case ColumnValue::LastModified: {
101 return GetLastModified();
103 case ColumnValue::Permission: {
104#if defined(Q_OS_LINUX)
105 quint32 permissions = (quint32)GetPermissions();
107 uint32_to_permstr(permissions, buf);
112 case ColumnValue::Owner:
120QString CRemoteFileSystem::HeaderData(
int section)
122 switch ((ColumnValue)section) {
123 case ColumnValue::Name:
124 return tr(
"File name");
125 case ColumnValue::Size:
126 return tr(
"File size");
127 case ColumnValue::Type:
128 return tr(
"File type");
129 case ColumnValue::LastModified:
130 return tr(
"File last modified time");
131 case ColumnValue::Permission:
132 return tr(
"Permissions");
133 case ColumnValue::Owner:
134 return tr(
"Owner/Group");
141int CRemoteFileSystem::ColumnCount()
144 return (
int)ColumnValue::Permission;
146 return (
int)ColumnValue::End;
150int CRemoteFileSystem::ChildCount()
152 return m_vChild.size();
167 Q_ASSERT_X(pChild->GetType(),
"AppendChild",
"Must set all the properties before call them");
173 if(-1 != IndexOf(pChild->GetPath()))
175 qDebug(log) << pChild->GetName() <<
"is exist";
179 m_vChild.append(pChild);
180 pChild->SetParent(
this);
184int CRemoteFileSystem::RemoveChild(
int index)
186 if(0 > index || m_vChild.size() < index)
188 m_vChild.removeAt(index);
194 if(nIndex < 0 || nIndex >= m_vChild.size())
196 return m_vChild.at(nIndex);
201 return m_vChild.indexOf(pChild);
204int CRemoteFileSystem::IndexOf(
const QString& szPath)
206 for(
int i = 0; i < m_vChild.size(); i++) {
207 auto p = m_vChild[i];
208 if(p && p->GetPath() == szPath)
214int CRemoteFileSystem::IndexOfParent()
218 nIndex= GetParent()->IndexOf(
this);
222QString CRemoteFileSystem::GetPath()
227QString CRemoteFileSystem::GetName()
230 QString szPath = GetPath();
233 int nIndex = szPath.lastIndexOf(
'/');
236 szName = szPath.right(szPath.size() - nIndex - 1);
237 if(GetState() == State::Getting)
238 szName +=
"(" + tr(
"getting") +
" ......)";
242quint64 CRemoteFileSystem::GetSize()
247void CRemoteFileSystem::SetSize(quint64 size)
252bool CRemoteFileSystem::IsDir()
254 return !(GetType() & TYPE::FILE);
257QIcon CRemoteFileSystem::Icon()
259 if(GetType() & TYPE::DRIVE)
260 return QIcon::fromTheme(
"drive-harddisk");
261 if(GetType() & TYPE::DIR)
262 return QIcon::fromTheme(
"folder-remote");
263 if(GetType() & TYPE::FILE || GetType() & TYPE::SPECIAL)
264 return QApplication::style()->standardIcon(QStyle::SP_FileIcon);
265 if(GetType() & TYPE::SYMLINK)
266 return QIcon::fromTheme(
"emblem-symbolic-link");
270CRemoteFileSystem::TYPES CRemoteFileSystem::GetType()
275QDateTime CRemoteFileSystem::GetCreateTime()
280void CRemoteFileSystem::SetCreateTime(
const QDateTime &date)
285QDateTime CRemoteFileSystem::GetLastModified()
287 return m_lastModifed;
290void CRemoteFileSystem::SetLastModified(
const QDateTime &date)
292 m_lastModifed = date;
295QFileDevice::Permissions CRemoteFileSystem::GetPermissions()
297 return m_Permissions;
300void CRemoteFileSystem::SetPermissions(QFileDevice::Permissions privileges)
302 m_Permissions = privileges;
305QString CRemoteFileSystem::GetOwner()
310void CRemoteFileSystem::SetOwner(QString szOwner)
315void CRemoteFileSystem::SetState(State a)
320const CRemoteFileSystem::State CRemoteFileSystem::GetState()
const
325CRemoteFileSystemModel::CRemoteFileSystemModel(
326 QObject *parent, CRemoteFileSystem::TYPES filter)
327 : QAbstractItemModel(parent)
332CRemoteFileSystemModel::~CRemoteFileSystemModel()
334 qDebug(log) << Q_FUNC_INFO;
336 DeleteRemoteFileSystem(m_pRoot);
342 for(
int i = 0; i < p->ChildCount(); i++) {
343 auto pChild = p->GetChild(i);
345 DeleteRemoteFileSystem(pChild);
350QModelIndex CRemoteFileSystemModel::SetRootPath(
const QString &szPath)
352 if(szPath.isEmpty())
return QModelIndex();
353 if(m_pRoot && m_pRoot->GetPath() == szPath)
354 return index(m_pRoot);
358 DeleteRemoteFileSystem(m_pRoot);
362 QModelIndex idx = index(m_pRoot);
364 qDebug(log) <<
"SetRootPath:" <<
this << idx << szPath;
373CRemoteFileSystem* CRemoteFileSystemModel::GetRemoteFileSystemFromIndex(
const QModelIndex &index)
const
380CRemoteFileSystem::TYPES CRemoteFileSystemModel::GetFilter()
385QVariant CRemoteFileSystemModel::headerData(
int section, Qt::Orientation orientation,
int role)
const
387 if(Qt::DisplayRole != role)
389 if(Qt::Vertical == orientation) {
390 return QString::number(section + 1);
392 return CRemoteFileSystem::HeaderData(section);
397int CRemoteFileSystemModel::rowCount(
const QModelIndex &parent)
const
400 if(!parent.isValid())
return 0;
402 pItem = GetRemoteFileSystemFromIndex(parent);
404 return pItem->ChildCount();
408int CRemoteFileSystemModel::columnCount(
const QModelIndex &parent)
const
410 if(!parent.isValid())
return 0;
411 return CRemoteFileSystem::ColumnCount();
414QVariant CRemoteFileSystemModel::data(
const QModelIndex &index,
int role)
const
418 if (!index.isValid())
420 if (role != Qt::DisplayRole && role != Qt::DecorationRole)
426 if(!(pItem->GetType() & m_Filter))
428 if(Qt::DecorationRole == role && index.column() == 0)
429 return pItem->Icon();
430 if(Qt::DisplayRole == role || Qt::EditRole == role)
431 return pItem->Data(index.column());
432 if(Qt::ToolTipRole == role)
433 return pItem->GetPath();
437QModelIndex CRemoteFileSystemModel::index(
const QString& szPath)
const
440 qDebug(log) << Q_FUNC_INFO << szPath;
441 QModelIndex idxParent;
442 QModelIndex idx = index(0, 0);
443 while(idx.isValid()) {
444 idx = index(r++, 0, idxParent);
446 if(!pRemoteFileSystem)
448 QString szDir = pRemoteFileSystem->GetPath();
449 qDebug(log) << szDir << szPath;
452 if(pRemoteFileSystem->GetType() & CRemoteFileSystem::TYPE::FILE) {
453 qDebug(log) << szDir <<
"Is file:";
456 if(szDir.right(1) !=
'/')
458 if(szPath.left(szDir.size()) == szDir) {
459 qDebug(log) <<
"Contain:" << szPath << szDir;
465 return QModelIndex();
468QModelIndex CRemoteFileSystemModel::index(
CRemoteFileSystem* node,
int column)
const
470 if(
nullptr == node)
return QModelIndex();
474 row = node->IndexOfParent();
475 }
else if(node == m_pRoot) {
478 if(0 > row || 0 > column || CRemoteFileSystem::ColumnCount() < column)
479 return QModelIndex();
480 return createIndex(row, column, node);
483QModelIndex CRemoteFileSystemModel::index(
int row,
int column,
const QModelIndex &parent)
const
486 if (!hasIndex(row, column, parent))
487 return QModelIndex();
488 if(!parent.isValid())
489 return index(m_pRoot, column);
491 pItem = GetRemoteFileSystemFromIndex(parent);
493 return QModelIndex();
494 pItem = pItem->GetChild(row);
496 return createIndex(row, column, pItem);
498 return QModelIndex();
501QModelIndex CRemoteFileSystemModel::parent(
const QModelIndex &child)
const
504 if (!child.isValid())
505 return QModelIndex();
508 return QModelIndex();
511 return index(pItemParent);
512 return QModelIndex();
515bool CRemoteFileSystemModel::canFetchMore(
const QModelIndex &parent)
const
517 if(!parent.isValid()) {
518 qDebug(log) <<
"canFetchMore: parent is valid" << parent;
522 if(p && p->GetState() == CRemoteFileSystem::State::No
523 && !(p->GetType() & CRemoteFileSystem::TYPE::FILE)) {
524 qDebug(log) <<
"canFetchMore:" << parent << p->GetPath() <<
"true";
527 qDebug(log) << Q_FUNC_INFO << parent;
531void CRemoteFileSystemModel::fetchMore(
const QModelIndex &parent)
533 qDebug(log) << Q_FUNC_INFO << parent;
534 auto p = GetRemoteFileSystemFromIndex(parent);
537 qCritical(log) <<
"fetchMore:" << parent <<
"The pointer is nullptr";
540 if(p->GetType() & CRemoteFileSystem::TYPE::FILE) {
541 qCritical(log) <<
"fetchMore:" << parent <<
"The node is file";
544 QString szPath = p->GetPath();
545 if(szPath.isEmpty()) {
546 qCritical(log) <<
"fetchMore:" << parent <<
"The path is empty";
549 if(p->GetState() != CRemoteFileSystem::State::No) {
550 qDebug(log) <<
"fetchMore:" << parent << p->GetState() <<
"The state is not NO";
553 if(m_GetFolder.indexOf(p) != -1)
555 m_GetFolder.append(p);
556 p->SetState(CRemoteFileSystem::State::Getting);
558 qDebug(log) <<
"fetchMore:" << parent << p << szPath;
561void CRemoteFileSystemModel::slotGetDir(
563 QVector<QSharedPointer<CRemoteFileSystem> > contents,
567 qCritical(log) <<
"The pointer is nullptr";
570 int nIndex = m_GetFolder.indexOf(p);
572 qDebug(log) <<
"Is not the model";
576 m_GetFolder.removeAt(nIndex);
577 QModelIndex parentIndex;
578 parentIndex = index(p, 0);
579 qDebug(log) <<
"slotGetDir:" << p << p << p->GetPath() << parentIndex << contents.size();
580 p->SetState(CRemoteFileSystem::State::Ok);
581 if(contents.size() > 0) {
583 foreach(
auto c, contents) {
585 if(!(c->GetType() & GetFilter()))
continue;
588 beginInsertRows(parentIndex, 0, nCount);
589 foreach(
auto c, contents) {
591 if(!(c->GetType() & GetFilter()))
continue;
594 pRfs->SetSize(c->GetSize());
595 pRfs->SetPermissions(c->GetPermissions());
596 pRfs->SetLastModified(c->GetLastModified());
597 pRfs->SetCreateTime(c->GetCreateTime());
601 auto topleft = index(0, 0, parentIndex);
602 auto bottomRight = index(p->ChildCount(), p->ColumnCount(), parentIndex);
603 if(topleft.isValid() && bottomRight.isValid())
604 emit dataChanged(topleft, bottomRight);
606 emit dataChanged(parentIndex, parentIndex);
609void CRemoteFileSystemModel::CreateDir(QModelIndex index,
const QString &dir)
611 auto p = GetRemoteFileSystemFromIndex(index);
613 if(p && !p->GetPath().isEmpty()) {
614 QString szPath = p->GetPath() +
"/" + dir;
615 if(p->IndexOf(szPath) > -1) {
616 qCritical(log) <<
"The path is exist:" << szPath;
617 QMessageBox::critical(
nullptr, tr(
"Error"), tr(
"The path is exist: %1").arg(szPath));
620 emit sigMakeDir(szPath);
621 p->SetState(CRemoteFileSystem::State::No);
622 fetchMore(parent(this->index(p)));
626void CRemoteFileSystemModel::RemoveDir(QModelIndex index)
628 auto p = GetRemoteFileSystemFromIndex(index);
629 if(p && !p->GetPath().isEmpty()) {
630 if(QMessageBox::question(
631 nullptr, tr(
"Delete directory"),
632 tr(
"Are you sure you want to delete '%1'?").arg(p->GetPath()),
633 QMessageBox::Yes | QMessageBox::No)
636 if(p->GetType() & CRemoteFileSystem::TYPE::DIR)
637 emit sigRemoveDir(p->GetPath());
639 emit sigRemoveFile(p->GetPath());
641 auto pParent = p->GetParent();
643 int nIdx = pParent->IndexOf(p);
644 beginRemoveRows(index.parent(), nIdx, nIdx);
645 pParent->RemoveChild(nIdx);
646 DeleteRemoteFileSystem(p);
648 pParent->SetState(CRemoteFileSystem::State::No);
649 fetchMore(index.parent());
654bool CRemoteFileSystemModel::setData(
655 const QModelIndex &index,
const QVariant &value,
int role)
657 qDebug(log) << Q_FUNC_INFO << index << value << role;
660 if(Qt::EditRole != role) {
661 return QAbstractItemModel::setData(index, value, role);
665 auto p = GetRemoteFileSystemFromIndex(index);
666 QString szName = value.toString();
667 if(p && !p->GetPath().isEmpty() && p->GetName() != szName) {
668 QFileInfo fi(p->GetPath());
669 szName = fi.path() +
"/" + szName;
670 emit sigRename(p->GetPath(), szName);
671 auto pParent = p->GetParent();
673 Q_ASSERT(pParent == GetRemoteFileSystemFromIndex(index.parent()));
674 int nIdx = pParent->IndexOf(p);
675 beginRemoveRows(index.parent(), nIdx, nIdx);
676 pParent->RemoveChild(nIdx);
677 DeleteRemoteFileSystem(p);
679 pParent->SetState(CRemoteFileSystem::State::No);
680 fetchMore(index.parent());
686Qt::ItemFlags CRemoteFileSystemModel::flags(
const QModelIndex &index)
const
688 Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
689 if (!index.isValid())
692 if (index.column() == (
int)CRemoteFileSystem::ColumnValue::Name)
693 return defaultFlags | Qt::ItemIsEditable;
int AppendChild(CRemoteFileSystem *pChild)
Append child