8#include <QLoggingCategory>
11#if defined(Q_OS_LINUX)
15#include "RemoteFileSystemModel.h"
17static Q_LOGGING_CATEGORY(log,
"RemoteFileSystem.Model")
22 const QString& szPath, TYPES type)
28 , m_Permissions(QFileDevice::Permission::WriteOwner | QFileDevice::Permission::ReadOwner)
33CRemoteFileSystem::~CRemoteFileSystem()
40 m_pParent = file.m_pParent;
41 m_vChild = file.m_vChild;
42 m_szPath = file.m_szPath;
43 m_nSize = file.m_nSize;
45 m_createTime = file.m_createTime;
46 m_lastModifed = file.m_lastModifed;
47 m_Permissions = file.m_Permissions;
48 m_szOwner = file.m_szOwner;
49 m_State = file.m_State;
52#if defined(Q_OS_LINUX)
53void uint32_to_permstr(uint32_t mode,
char *str) {
54 str[0] = S_ISDIR(mode) ?
'd' :
58 S_ISFIFO(mode) ?
'p' :
59 S_ISSOCK(mode) ?
's' :
'-';
62 str[1] = (mode & S_IRUSR) ?
'r' :
'-';
63 str[2] = (mode & S_IWUSR) ?
'w' :
'-';
64 str[3] = (mode & S_IXUSR) ? ((mode & S_ISUID) ?
's' :
'x') : ((mode & S_ISUID) ?
'S' :
'-');
66 str[4] = (mode & S_IRGRP) ?
'r' :
'-';
67 str[5] = (mode & S_IWGRP) ?
'w' :
'-';
68 str[6] = (mode & S_IXGRP) ? ((mode & S_ISGID) ?
's' :
'x') : ((mode & S_ISGID) ?
'S' :
'-');
70 str[7] = (mode & S_IROTH) ?
'r' :
'-';
71 str[8] = (mode & S_IWOTH) ?
'w' :
'-';
72 str[9] = (mode & S_IXOTH) ? ((mode & S_ISVTX) ?
't' :
'x') : ((mode & S_ISVTX) ?
'T' :
'-');
77QVariant CRemoteFileSystem::Data(
int column)
79 switch((ColumnValue)column) {
80 case ColumnValue::Name: {
83 case ColumnValue::Size: {
84 return CStats::Convertbytes(GetSize());
86 case ColumnValue::Type: {
87 if(GetType() & TYPE::FILE)
89 if(GetType() & TYPE::DIR)
91 if(GetType() & TYPE::DRIVE)
93 if(GetType() & TYPE::SYMLINK)
95 if(GetType() & TYPE::SPECIAL)
99 case ColumnValue::LastModified: {
100 return GetLastModified();
102 case ColumnValue::Permission: {
103#if defined(Q_OS_LINUX)
104 quint32 permissions = (quint32)GetPermissions();
106 uint32_to_permstr(permissions, buf);
111 case ColumnValue::Owner:
119QString CRemoteFileSystem::HeaderData(
int section)
121 switch ((ColumnValue)section) {
122 case ColumnValue::Name:
123 return tr(
"File name");
124 case ColumnValue::Size:
125 return tr(
"File size");
126 case ColumnValue::Type:
127 return tr(
"File type");
128 case ColumnValue::LastModified:
129 return tr(
"File last modified time");
130 case ColumnValue::Permission:
131 return tr(
"Permissions");
132 case ColumnValue::Owner:
133 return tr(
"Owner/Group");
140int CRemoteFileSystem::ColumnCount()
143 return (
int)ColumnValue::Permission;
145 return (
int)ColumnValue::End;
149int CRemoteFileSystem::ChildCount()
151 return m_vChild.size();
166 Q_ASSERT_X(pChild->GetType(),
"AppendChild",
"Must set all the properties before call them");
172 if(-1 != IndexOf(pChild->GetPath()))
174 qDebug(log) << pChild->GetName() <<
"is exist";
178 m_vChild.append(pChild);
179 pChild->SetParent(
this);
183int CRemoteFileSystem::RemoveChild(
int index)
185 if(0 > index || m_vChild.size() < index)
187 m_vChild.removeAt(index);
193 if(nIndex < 0 || nIndex >= m_vChild.size())
195 return m_vChild.at(nIndex);
200 return m_vChild.indexOf(pChild);
203int CRemoteFileSystem::IndexOf(
const QString& szPath)
205 for(
int i = 0; i < m_vChild.size(); i++) {
206 auto p = m_vChild[i];
207 if(p && p->GetPath() == szPath)
213int CRemoteFileSystem::IndexOfParent()
217 nIndex= GetParent()->IndexOf(
this);
221QString CRemoteFileSystem::GetPath()
226QString CRemoteFileSystem::GetName()
229 QString szPath = GetPath();
232 int nIndex = szPath.lastIndexOf(
'/');
235 szName = szPath.right(szPath.size() - nIndex - 1);
236 if(GetState() == State::Getting)
237 szName +=
"(" + tr(
"getting") +
" ......)";
241quint64 CRemoteFileSystem::GetSize()
246void CRemoteFileSystem::SetSize(quint64 size)
251bool CRemoteFileSystem::IsDir()
253 return !(GetType() & TYPE::FILE);
256QIcon CRemoteFileSystem::Icon()
258 if(GetType() & TYPE::DRIVE)
259 return QIcon::fromTheme(
"drive-harddisk");
260 if(GetType() & TYPE::DIR)
261 return QIcon::fromTheme(
"folder-remote");
262 if(GetType() & TYPE::FILE || GetType() & TYPE::SPECIAL)
263 return QApplication::style()->standardIcon(QStyle::SP_FileIcon);
264 if(GetType() & TYPE::SYMLINK)
265 return QIcon::fromTheme(
"emblem-symbolic-link");
269CRemoteFileSystem::TYPES CRemoteFileSystem::GetType()
274QDateTime CRemoteFileSystem::GetCreateTime()
279void CRemoteFileSystem::SetCreateTime(
const QDateTime &date)
284QDateTime CRemoteFileSystem::GetLastModified()
286 return m_lastModifed;
289void CRemoteFileSystem::SetLastModified(
const QDateTime &date)
291 m_lastModifed = date;
294QFileDevice::Permissions CRemoteFileSystem::GetPermissions()
296 return m_Permissions;
299void CRemoteFileSystem::SetPermissions(QFileDevice::Permissions privileges)
301 m_Permissions = privileges;
304QString CRemoteFileSystem::GetOwner()
309void CRemoteFileSystem::SetOwner(QString szOwner)
314void CRemoteFileSystem::SetState(State a)
319const CRemoteFileSystem::State CRemoteFileSystem::GetState()
const
324CRemoteFileSystemModel::CRemoteFileSystemModel(
325 QObject *parent, CRemoteFileSystem::TYPES filter)
326 : QAbstractItemModel(parent)
331CRemoteFileSystemModel::~CRemoteFileSystemModel()
333 qDebug(log) << Q_FUNC_INFO;
335 DeleteRemoteFileSystem(m_pRoot);
341 for(
int i = 0; i < p->ChildCount(); i++) {
342 auto pChild = p->GetChild(i);
344 DeleteRemoteFileSystem(pChild);
349QModelIndex CRemoteFileSystemModel::SetRootPath(
const QString &szPath)
351 if(szPath.isEmpty())
return QModelIndex();
352 if(m_pRoot && m_pRoot->GetPath() == szPath)
353 return index(m_pRoot);
357 DeleteRemoteFileSystem(m_pRoot);
361 QModelIndex idx = index(m_pRoot);
363 qDebug(log) <<
"SetRootPath:" <<
this << idx << szPath;
372CRemoteFileSystem* CRemoteFileSystemModel::GetRemoteFileSystemFromIndex(
const QModelIndex &index)
const
379CRemoteFileSystem::TYPES CRemoteFileSystemModel::GetFilter()
384QVariant CRemoteFileSystemModel::headerData(
int section, Qt::Orientation orientation,
int role)
const
386 if(Qt::DisplayRole != role)
388 if(Qt::Vertical == orientation) {
389 return QString::number(section + 1);
391 return CRemoteFileSystem::HeaderData(section);
396int CRemoteFileSystemModel::rowCount(
const QModelIndex &parent)
const
399 if(!parent.isValid())
return 0;
401 pItem = GetRemoteFileSystemFromIndex(parent);
403 return pItem->ChildCount();
407int CRemoteFileSystemModel::columnCount(
const QModelIndex &parent)
const
409 if(!parent.isValid())
return 0;
410 return CRemoteFileSystem::ColumnCount();
413QVariant CRemoteFileSystemModel::data(
const QModelIndex &index,
int role)
const
417 if (!index.isValid())
419 if (role != Qt::DisplayRole && role != Qt::DecorationRole)
425 if(!(pItem->GetType() & m_Filter))
427 if(Qt::DecorationRole == role && index.column() == 0)
428 return pItem->Icon();
429 if(Qt::DisplayRole == role || Qt::EditRole == role)
430 return pItem->Data(index.column());
431 if(Qt::ToolTipRole == role)
432 return pItem->GetPath();
436QModelIndex CRemoteFileSystemModel::index(
const QString& szPath)
const
439 qDebug(log) << Q_FUNC_INFO << szPath;
440 QModelIndex idxParent;
441 QModelIndex idx = index(0, 0);
442 while(idx.isValid()) {
443 idx = index(r++, 0, idxParent);
445 if(!pRemoteFileSystem)
447 QString szDir = pRemoteFileSystem->GetPath();
448 qDebug(log) << szDir << szPath;
451 if(pRemoteFileSystem->GetType() & CRemoteFileSystem::TYPE::FILE) {
452 qDebug(log) << szDir <<
"Is file:";
455 if(szDir.right(1) !=
'/')
457 if(szPath.left(szDir.size()) == szDir) {
458 qDebug(log) <<
"Contain:" << szPath << szDir;
464 return QModelIndex();
467QModelIndex CRemoteFileSystemModel::index(
CRemoteFileSystem* node,
int column)
const
469 if(
nullptr == node)
return QModelIndex();
473 row = node->IndexOfParent();
474 }
else if(node == m_pRoot) {
477 if(0 > row || 0 > column || CRemoteFileSystem::ColumnCount() < column)
478 return QModelIndex();
479 return createIndex(row, column, node);
482QModelIndex CRemoteFileSystemModel::index(
int row,
int column,
const QModelIndex &parent)
const
485 if (!hasIndex(row, column, parent))
486 return QModelIndex();
487 if(!parent.isValid())
488 return index(m_pRoot, column);
490 pItem = GetRemoteFileSystemFromIndex(parent);
492 return QModelIndex();
493 pItem = pItem->GetChild(row);
495 return createIndex(row, column, pItem);
497 return QModelIndex();
500QModelIndex CRemoteFileSystemModel::parent(
const QModelIndex &child)
const
503 if (!child.isValid())
504 return QModelIndex();
507 return QModelIndex();
510 return index(pItemParent);
511 return QModelIndex();
514bool CRemoteFileSystemModel::canFetchMore(
const QModelIndex &parent)
const
516 if(!parent.isValid()) {
517 qDebug(log) <<
"canFetchMore: parent is valid" << parent;
521 if(p && p->GetState() == CRemoteFileSystem::State::No
522 && !(p->GetType() & CRemoteFileSystem::TYPE::FILE)) {
523 qDebug(log) <<
"canFetchMore:" << parent << p->GetPath() <<
"true";
526 qDebug(log) << Q_FUNC_INFO << parent;
530void CRemoteFileSystemModel::fetchMore(
const QModelIndex &parent)
532 qDebug(log) << Q_FUNC_INFO << parent;
533 auto p = GetRemoteFileSystemFromIndex(parent);
536 qCritical(log) <<
"fetchMore:" << parent <<
"The pointer is nullptr";
539 if(p->GetType() & CRemoteFileSystem::TYPE::FILE) {
540 qCritical(log) <<
"fetchMore:" << parent <<
"The node is file";
543 QString szPath = p->GetPath();
544 if(szPath.isEmpty()) {
545 qCritical(log) <<
"fetchMore:" << parent <<
"The path is empty";
548 if(p->GetState() != CRemoteFileSystem::State::No) {
549 qDebug(log) <<
"fetchMore:" << parent << p->GetState() <<
"The state is not NO";
552 if(m_GetFolder.indexOf(p) != -1)
554 m_GetFolder.append(p);
555 p->SetState(CRemoteFileSystem::State::Getting);
557 qDebug(log) <<
"fetchMore:" << parent << p << szPath;
560void CRemoteFileSystemModel::slotGetDir(
562 QVector<QSharedPointer<CRemoteFileSystem> > contents,
566 qCritical(log) <<
"The pointer is nullptr";
569 int nIndex = m_GetFolder.indexOf(p);
571 qDebug(log) <<
"Is not the model";
575 m_GetFolder.removeAt(nIndex);
576 QModelIndex parentIndex;
577 parentIndex = index(p, 0);
578 qDebug(log) <<
"slotGetDir:" << p << p << p->GetPath() << parentIndex << contents.size();
579 p->SetState(CRemoteFileSystem::State::Ok);
580 if(contents.size() > 0) {
582 foreach(
auto c, contents) {
584 if(!(c->GetType() & GetFilter()))
continue;
587 beginInsertRows(parentIndex, 0, nCount);
588 foreach(
auto c, contents) {
590 if(!(c->GetType() & GetFilter()))
continue;
593 pRfs->SetSize(c->GetSize());
594 pRfs->SetPermissions(c->GetPermissions());
595 pRfs->SetLastModified(c->GetLastModified());
596 pRfs->SetCreateTime(c->GetCreateTime());
600 auto topleft = index(0, 0, parentIndex);
601 auto bottomRight = index(p->ChildCount(), p->ColumnCount(), parentIndex);
602 if(topleft.isValid() && bottomRight.isValid())
603 emit dataChanged(topleft, bottomRight);
605 emit dataChanged(parentIndex, parentIndex);
608void CRemoteFileSystemModel::CreateDir(QModelIndex index,
const QString &dir)
610 auto p = GetRemoteFileSystemFromIndex(index);
612 if(p && !p->GetPath().isEmpty()) {
613 QString szPath = p->GetPath() +
"/" + dir;
614 if(p->IndexOf(szPath) > -1) {
615 qCritical(log) <<
"The path is exist:" << szPath;
616 QMessageBox::critical(
nullptr, tr(
"Error"), tr(
"The path is exist: %1").arg(szPath));
619 emit sigMakeDir(szPath);
620 p->SetState(CRemoteFileSystem::State::No);
621 fetchMore(parent(this->index(p)));
625void CRemoteFileSystemModel::RemoveDir(QModelIndex index)
627 auto p = GetRemoteFileSystemFromIndex(index);
628 if(p && !p->GetPath().isEmpty()) {
629 if(QMessageBox::question(
630 nullptr, tr(
"Delete directory"),
631 tr(
"Are you sure you want to delete '%1'?").arg(p->GetPath()),
632 QMessageBox::Yes | QMessageBox::No)
635 if(p->GetType() & CRemoteFileSystem::TYPE::DIR)
636 emit sigRemoveDir(p->GetPath());
638 emit sigRemoveFile(p->GetPath());
640 auto pParent = p->GetParent();
642 int nIdx = pParent->IndexOf(p);
643 beginRemoveRows(index.parent(), nIdx, nIdx);
644 pParent->RemoveChild(nIdx);
645 DeleteRemoteFileSystem(p);
647 pParent->SetState(CRemoteFileSystem::State::No);
648 fetchMore(index.parent());
653bool CRemoteFileSystemModel::setData(
654 const QModelIndex &index,
const QVariant &value,
int role)
656 qDebug(log) << Q_FUNC_INFO << index << value << role;
659 if(Qt::EditRole != role) {
660 return QAbstractItemModel::setData(index, value, role);
664 auto p = GetRemoteFileSystemFromIndex(index);
665 QString szName = value.toString();
666 if(p && !p->GetPath().isEmpty() && p->GetName() != szName) {
667 QFileInfo fi(p->GetPath());
668 szName = fi.path() +
"/" + szName;
669 emit sigRename(p->GetPath(), szName);
670 auto pParent = p->GetParent();
672 Q_ASSERT(pParent == GetRemoteFileSystemFromIndex(index.parent()));
673 int nIdx = pParent->IndexOf(p);
674 beginRemoveRows(index.parent(), nIdx, nIdx);
675 pParent->RemoveChild(nIdx);
676 DeleteRemoteFileSystem(p);
678 pParent->SetState(CRemoteFileSystem::State::No);
679 fetchMore(index.parent());
685Qt::ItemFlags CRemoteFileSystemModel::flags(
const QModelIndex &index)
const
687 Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
688 if (!index.isValid())
691 if (index.column() == (
int)CRemoteFileSystem::ColumnValue::Name)
692 return defaultFlags | Qt::ItemIsEditable;
int AppendChild(CRemoteFileSystem *pChild)
Append child.