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.