diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp index 6e7c31777..f3ae5d878 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp @@ -1,21 +1,21 @@ /******************************************************************************* * retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.cpp * - * * + * * * Copyright (c) 2009 Retroshare Team * - * * + * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * + * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * * along with this program. If not, see . * - * * + * * *******************************************************************************/ #include "SharedFilesDialog.h" @@ -52,6 +52,7 @@ #include #include #include +#include // Ajouté #include @@ -107,7 +108,8 @@ const QString Image_AddNewAssotiationForFile = ":/icons/svg/options.svg"; class SFDSortFilterProxyModel : public QSortFilterProxyModel { public: - SFDSortFilterProxyModel(RetroshareDirModel *dirModel, QObject *parent) : QSortFilterProxyModel(parent) + SFDSortFilterProxyModel(RetroshareDirModel *dirModel, QObject *parent) + : QSortFilterProxyModel(parent), m_uploadedOnly(false) { m_dirModel = dirModel; @@ -118,7 +120,27 @@ public: setDynamicSortFilter(false); } + void setUploadedOnly(bool val) { + m_uploadedOnly = val; + invalidateFilter(); + } + protected: + virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const + { + // 1. Custom Upload Check + if (m_uploadedOnly) { + // Check column 6 (Uploaded) + QModelIndex uploadIdx = sourceModel()->index(source_row, SHARED_FILES_DIALOG_COLUMN_UPLOADED, source_parent); + QString uploadStr = sourceModel()->data(uploadIdx, Qt::DisplayRole).toString(); + // If empty or "-", treat as 0 -> filtered out + if (uploadStr.isEmpty() || uploadStr == "-") return false; + } + + // 2. Default logic (preserves the "filtered" role check used by RetroShare for search/filtering) + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); + } + virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const { bool dirLeft = (m_dirModel->getType(left) == DIR_TYPE_DIR); @@ -133,6 +155,7 @@ protected: private: RetroshareDirModel *m_dirModel; + bool m_uploadedOnly; }; // This class allows to draw the item in the share flags column using an appropriate size @@ -179,6 +202,14 @@ SharedFilesDialog::SharedFilesDialog(bool remote_mode, QWidget *parent) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); + // --- Ajout de la CheckBox --- + uploadedOnly_CB = new QCheckBox(tr("Uploaded only"), this); + uploadedOnly_CB->setToolTip(tr("Show only files and folders that have been uploaded")); + // On l'ajoute au layout horizontal existant qui contient les filtres + ui.horizontalLayout_2->addWidget(uploadedOnly_CB); + connect(uploadedOnly_CB, SIGNAL(toggled(bool)), this, SLOT(filterUploadedOnlyToggled(bool))); + // ---------------------------- + //connect(notify, SIGNAL(filesPreModChanged(bool)), this, SLOT(preModDirectories(bool))); //connect(notify, SIGNAL(filesPostModChanged(bool)), this, SLOT(postModDirectories(bool))); @@ -513,6 +544,9 @@ void LocalSharedFilesDialog::showProperColumns() ui.filterPatternLineEdit->show(); #endif } + // MODIFICATION: On s'assure que la colonne Uploaded est visible en mode local + // (Le filtre ne fonctionnera que si la colonne contient des données) + ui.dirTreeView->setColumnHidden(SHARED_FILES_DIALOG_COLUMN_UPLOADED, false); } void RemoteSharedFilesDialog::showProperColumns() { @@ -1408,7 +1442,7 @@ void SharedFilesDialog::indicatorChanged(int index) else ui.dirTreeView->sortByColumn(SHARED_FILES_DIALOG_COLUMN_NAME, Qt::AscendingOrder); - updateDisplay() ; + //updateDisplay() ; } void SharedFilesDialog::onFilterTextEdited() @@ -1502,6 +1536,21 @@ void SharedFilesDialog::startFilter() FilterItems(); } +void SharedFilesDialog::filterUploadedOnlyToggled(bool checked) +{ + tree_proxyModel->setUploadedOnly(checked); + flat_proxyModel->setUploadedOnly(checked); + + // Forcer le rafraîchissement + tree_proxyModel->invalidate(); + flat_proxyModel->invalidate(); + + // En mode Arbre, il peut être nécessaire d'étendre les éléments pour voir les résultats + if(checked && ui.viewType_CB->currentIndex() == VIEW_TYPE_TREE) { + expandAll(); + } +} + void SharedFilesDialog::updateDirTreeView() { if (model == flat_model) @@ -1760,3 +1809,4 @@ void SharedFilesDialog::updateFontSize() ui.dirTreeView->setIconSize(QSize(iconHeight, iconHeight)); } } + diff --git a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h index 375b6c075..0883fbf54 100644 --- a/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h +++ b/retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h @@ -1,21 +1,21 @@ /******************************************************************************* * retroshare-gui/src/gui/FileTransfer/SharedFilesDialog.h * - * * + * * * Copyright (c) 2009 Retroshare Team * - * * + * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * + * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * * along with this program. If not, see . * - * * + * * *******************************************************************************/ #ifndef _SHAREDFILESDIALOG_H @@ -29,9 +29,11 @@ #include "util/RsProtectedTimer.h" #include +#include // Ajout pour la checkbox class RetroshareDirModel; class QSortFilterProxyModel; +class SFDSortFilterProxyModel; // Forward declaration class SharedFilesDialog : public RsAutoUpdatePage { @@ -83,6 +85,9 @@ private slots: void startFilter(); void updateDirTreeView(); + + // Nouveau slot pour le filtre + void filterUploadedOnlyToggled(bool checked); public slots: void changeCurrentViewModel(int viewTypeIndex); @@ -136,8 +141,10 @@ protected: RetroshareDirModel *tree_model; RetroshareDirModel *flat_model; RetroshareDirModel *model; - QSortFilterProxyModel *tree_proxyModel; - QSortFilterProxyModel *flat_proxyModel; + + // Changé le type pour utiliser notre classe personnalisée + SFDSortFilterProxyModel *tree_proxyModel; + SFDSortFilterProxyModel *flat_proxyModel; QSortFilterProxyModel *proxyModel; QString currentCommand; @@ -148,6 +155,9 @@ protected: RsProtectedTimer* mFilterTimer; RsEventsHandlerId_t mEventHandlerId ; + + // Nouvelle CheckBox + QCheckBox *uploadedOnly_CB; }; class LocalSharedFilesDialog : public SharedFilesDialog @@ -208,4 +218,3 @@ class RemoteSharedFilesDialog : public SharedFilesDialog }; #endif - diff --git a/retroshare-gui/src/gui/RemoteDirModel.cpp b/retroshare-gui/src/gui/RemoteDirModel.cpp index 9aa1386ee..73fc3f9e1 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.cpp +++ b/retroshare-gui/src/gui/RemoteDirModel.cpp @@ -1,21 +1,21 @@ /******************************************************************************* - * gui/RemoteDirModel.cpp * - * * + * gui/RemoteDirModel.cpp * + * * * Copyright (c) 2006 Retroshare Team * - * * + * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * + * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * * along with this program. If not, see . * - * * + * * *******************************************************************************/ #include "RemoteDirModel.h" @@ -42,6 +42,7 @@ #include #include #include +#include // Keep iostream for debug logs /***** * #define RDM_DEBUG @@ -58,8 +59,8 @@ #define REMOTEDIRMODEL_COLUMN_COUNT 7 #define RETROSHARE_DIR_MODEL_FILTER_STRING "filtered" -static const uint32_t FLAT_VIEW_MAX_REFS_PER_SECOND = 2000 ; -static const size_t FLAT_VIEW_MAX_REFS_TABLE_SIZE = 10000 ; // +static const uint32_t FLAT_VIEW_MAX_REFS_PER_SECOND = 10000 ; +static const size_t FLAT_VIEW_MAX_REFS_TABLE_SIZE = 30000 ; // static const uint32_t FLAT_VIEW_MIN_DELAY_BETWEEN_UPDATES = 120 ; // dont rebuild ref list more than every 2 mins. RetroshareDirModel::RetroshareDirModel(bool mode, QObject *parent) @@ -148,8 +149,76 @@ void RetroshareDirModel::treeStyle() categoryIcon.addPixmap(FilesDefs::getPixmapFromQtResourcePath(":/icons/folderopen.png"), QIcon::Normal, QIcon::On); peerIcon = FilesDefs::getIconFromQtResourcePath(":/icons/folder-account.svg"); } + +void TreeStyle_RDM::recalculateDirectoryTotals() +{ + // DEBUG: Start of recalculation + // std::cerr << "UPLOAD_DBG: --- Starting recalculateDirectoryTotals ---" << std::endl; + + m_folderUploadTotals.clear(); + + // Only relevant for local files. Remote files do not expose upload statistics per file in the same way here. + if(RemoteMode) + return; + + std::vector stack; + // Start with NULL (Root) + stack.push_back(NULL); + + int processedFiles = 0; + + while(!stack.empty()) + { + void* ref = stack.back(); + stack.pop_back(); + + DirDetails details; + if(requestDirDetails(ref, RemoteMode, details)) + { + if(details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) + { + uint64_t uploaded = rsFiles->getCumulativeUpload(details.hash); + if(uploaded > 0) + { + processedFiles++; + // details.path for a file is the directory containing it. + QString currentPath = QDir::cleanPath(QString::fromUtf8(details.path.c_str())); + + // Iterate up the directory tree + while(!currentPath.isEmpty() && currentPath != ".") + { + m_folderUploadTotals[currentPath] += uploaded; + + // Get parent directory using QFileInfo logic + QString parent = QFileInfo(currentPath).path(); + + // Break if we reached root or top (QFileInfo returns path itself if no parent) + if(parent == currentPath || parent.isEmpty()) { + break; + } + currentPath = parent; + } + } + } + // Included DIR_TYPE_PERSON to allow recursion into root "My Files" + else if(details.type == DIR_TYPE_DIR || details.type == DIR_TYPE_ROOT || details.type == DIR_TYPE_PERSON) + { + for(const auto& child : details.children) + { + stack.push_back(child.ref); + } + } + } + } + // DEBUG: Summary + std::cerr << "UPLOAD_DBG: --- Finished Recalc. Processed " << processedFiles << " active files. Map size: " << m_folderUploadTotals.size() << " ---" << std::endl; +} + void TreeStyle_RDM::update() { + // Recalculate totals before notifying view update + recalculateDirectoryTotals(); + preMods() ; postMods() ; } @@ -610,7 +679,6 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const { case REMOTEDIRMODEL_COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); - break; case REMOTEDIRMODEL_COLUMN_FILENB: if (details.children.size() > 1) { @@ -622,11 +690,34 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const case REMOTEDIRMODEL_COLUMN_AGE: return misc::timeRelativeToNow(details.max_mtime); case REMOTEDIRMODEL_COLUMN_FRIEND_ACCESS: - return QVariant(); + return getFlagsString(details.flags); case REMOTEDIRMODEL_COLUMN_WN_VISU_DIR: return getGroupsString(details.flags,details.parent_groups) ; case REMOTEDIRMODEL_COLUMN_UPLOADED: + { + // New logic: Check if we have a calculated total for this directory + + // Based on logs, the 'details.path' for a directory IS the full path to that directory. + // We do NOT need to append the name. + + QString path = QDir::cleanPath(QString::fromUtf8(details.path.c_str())); + + // Fallback / Safety: try constructed path if direct path fails (covers root vs sub-dir anomalies) + auto it = m_folderUploadTotals.find(path); + + // DEBUG: Display role request + std::cerr << "UPLOAD_DBG: Display Role for DIR. Name: " << details.name + << " | Raw Path: " << details.path + << " | Lookup Key: [" << path.toStdString() << "]" << std::endl; + + if(it != m_folderUploadTotals.end() && it.value() > 0) + { + std::cerr << "UPLOAD_DBG: -> FOUND! Value: " << it.value() << std::endl; + return misc::friendlyUnit(it.value()); + } + return ""; + } default: return tr("DIR"); @@ -1753,3 +1844,4 @@ void TreeStyle_RDM::showEmpty(const bool value) _showEmpty = value; update(); } + diff --git a/retroshare-gui/src/gui/RemoteDirModel.h b/retroshare-gui/src/gui/RemoteDirModel.h index b7811533e..befcb78e0 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.h +++ b/retroshare-gui/src/gui/RemoteDirModel.h @@ -1,21 +1,21 @@ -/******************************************************************************* + /******************************************************************************* * gui/RemoteDirModel.h * - * * + * * * Copyright (c) 2006 Retroshare Team * - * * + * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * + * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * * along with this program. If not, see . * - * * + * * *******************************************************************************/ #ifndef REMOTE_DIR_MODEL @@ -28,6 +28,8 @@ #include #include #include +#include // Changed from map to QHash for efficiency with QString +#include #include #include @@ -209,6 +211,11 @@ class TreeStyle_RDM: public RetroshareDirModel private: QAction *_showEmptyAct; bool _showEmpty; + + // Helper: Calculate totals using normalized paths + void recalculateDirectoryTotals(); + QHash m_folderUploadTotals; + protected: mutable std::vector _parentRow ; // used to store the real parent row for non empty child };