mirror of
https://github.com/RetroShare/RetroShare.git
synced 2026-09-14 11:06:01 +05:00
Merge branch 'master' into DisplayEngineVersion
This commit is contained in:
commit
c631972ee5
@ -726,30 +726,33 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const
|
||||
case COLUMN_THREAD_IP:
|
||||
case COLUMN_THREAD_LAST_CONTACT:
|
||||
{
|
||||
if(!isProfileExpanded(e))
|
||||
// BUG FIX: Removed 'if(!isProfileExpanded(e))' to keep the last contact and IP
|
||||
// visible even when the profile is expanded (e.g. during search filtering).
|
||||
const HierarchicalProfileInformation *hn = getProfileInfo(e);
|
||||
|
||||
if(!hn) return QVariant();
|
||||
|
||||
QDateTime most_recent_time = DateTime::DateTimeFromTime_t(0);
|
||||
QString most_recent_ip("---");
|
||||
|
||||
// We aggregate the most recent contact info from all child nodes/locations
|
||||
for(uint32_t i=0;i<hn->child_node_indices.size();++i)
|
||||
{
|
||||
const HierarchicalProfileInformation *hn = getProfileInfo(e);
|
||||
const HierarchicalNodeInformation& node = mLocations[hn->child_node_indices[i]];
|
||||
auto node_time = DateTime::DateTimeFromTime_t(node.node_info.lastConnect);
|
||||
|
||||
QDateTime most_recent_time = DateTime::DateTimeFromTime_t(0);
|
||||
QString most_recent_ip("---");
|
||||
|
||||
for(uint32_t i=0;i<hn->child_node_indices.size();++i)
|
||||
if(most_recent_time < node_time)
|
||||
{
|
||||
const HierarchicalNodeInformation& node = mLocations[hn->child_node_indices[i]];
|
||||
auto node_time = DateTime::DateTimeFromTime_t(node.node_info.lastConnect);
|
||||
|
||||
if(most_recent_time < node_time)
|
||||
{
|
||||
most_recent_time = node_time;
|
||||
most_recent_ip = (node.node_info.state & RS_PEER_STATE_CONNECTED) ? StatusDefs::connectStateIpString(node.node_info) : QString("---");
|
||||
}
|
||||
most_recent_time = node_time;
|
||||
most_recent_ip = (node.node_info.state & RS_PEER_STATE_CONNECTED) ? StatusDefs::connectStateIpString(node.node_info) : QString("---");
|
||||
}
|
||||
|
||||
if(col == COLUMN_THREAD_LAST_CONTACT) return QVariant(most_recent_time);
|
||||
if(col == COLUMN_THREAD_IP) return QVariant(most_recent_ip);
|
||||
}
|
||||
|
||||
}// Fall-through
|
||||
if(col == COLUMN_THREAD_LAST_CONTACT) return QVariant(most_recent_time);
|
||||
if(col == COLUMN_THREAD_IP) return QVariant(most_recent_ip);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@ -994,49 +997,47 @@ QVariant RsFriendListModel::decorationRole(const EntryIndex& entry,int col) cons
|
||||
}
|
||||
case ENTRY_TYPE_PROFILE:
|
||||
{
|
||||
if(!isProfileExpanded(entry))
|
||||
{
|
||||
QPixmap sslAvatar;
|
||||
bool foundAvatar = false;
|
||||
const HierarchicalProfileInformation *hn = getProfileInfo(entry);
|
||||
RsStatusValue status = RsStatusValue::RS_STATUS_OFFLINE;
|
||||
const HierarchicalNodeInformation *bestNodeInformation = NULL;
|
||||
// BUG FIX: Removed 'if(!isProfileExpanded(entry))' to keep the icon visible
|
||||
// even when the profile is expanded (e.g. during search filtering).
|
||||
|
||||
QPixmap sslAvatar;
|
||||
bool foundAvatar = false;
|
||||
const HierarchicalProfileInformation *hn = getProfileInfo(entry);
|
||||
RsStatusValue status = RsStatusValue::RS_STATUS_OFFLINE;
|
||||
const HierarchicalNodeInformation *bestNodeInformation = NULL;
|
||||
|
||||
if (mDisplayStatusIcon) {
|
||||
bestNodeInformation = getBestNodeInformation(hn, &status);
|
||||
if (bestNodeInformation) {
|
||||
if (AvatarDefs::getAvatarFromSslId(RsPeerId(bestNodeInformation->node_info.id.toStdString()), sslAvatar, "")) {
|
||||
/* Use avatar from best node */
|
||||
foundAvatar = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mDisplayStatusIcon) {
|
||||
bestNodeInformation = getBestNodeInformation(hn, &status);
|
||||
if (bestNodeInformation) {
|
||||
if (AvatarDefs::getAvatarFromSslId(RsPeerId(bestNodeInformation->node_info.id.toStdString()), sslAvatar, "")) {
|
||||
/* Use avatar from best node */
|
||||
foundAvatar = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundAvatar) {
|
||||
/* Use first available avatar */
|
||||
for(uint32_t i=0;i<hn->child_node_indices.size();++i) {
|
||||
if(AvatarDefs::getAvatarFromSslId(RsPeerId(mLocations[hn->child_node_indices[i]].node_info.id.toStdString()), sslAvatar, "")) {
|
||||
foundAvatar = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundAvatar) {
|
||||
/* Use first available avatar */
|
||||
for(uint32_t i=0;i<hn->child_node_indices.size();++i) {
|
||||
if(AvatarDefs::getAvatarFromSslId(RsPeerId(mLocations[hn->child_node_indices[i]].node_info.id.toStdString()), sslAvatar, "")) {
|
||||
foundAvatar = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundAvatar || sslAvatar.isNull()) {
|
||||
sslAvatar = FilesDefs::getPixmapFromQtResourcePath(AVATAR_DEFAULT_IMAGE);
|
||||
}
|
||||
if (!foundAvatar || sslAvatar.isNull()) {
|
||||
sslAvatar = FilesDefs::getPixmapFromQtResourcePath(AVATAR_DEFAULT_IMAGE);
|
||||
}
|
||||
|
||||
if (mDisplayStatusIcon) {
|
||||
if (bestNodeInformation) {
|
||||
QPixmap sslOverlayIcon = FilesDefs::getPixmapFromQtResourcePath(StatusDefs::imageStatus(status));
|
||||
return QVariant(QIcon(createAvatar(sslAvatar, sslOverlayIcon)));
|
||||
}
|
||||
}
|
||||
if (mDisplayStatusIcon) {
|
||||
if (bestNodeInformation) {
|
||||
QPixmap sslOverlayIcon = FilesDefs::getPixmapFromQtResourcePath(StatusDefs::imageStatus(status));
|
||||
return QVariant(QIcon(createAvatar(sslAvatar, sslOverlayIcon)));
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant(QIcon(sslAvatar));
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
return QVariant(QIcon(sslAvatar));
|
||||
}
|
||||
|
||||
case ENTRY_TYPE_NODE:
|
||||
|
||||
@ -1153,63 +1153,57 @@ void NewFriendList::removeGroup()
|
||||
|
||||
void NewFriendList::applyWhileKeepingTree(std::function<void()> predicate)
|
||||
{
|
||||
// 1. Store the current vertical scroll position to prevent the list from jumping
|
||||
int scrollValue = ui->peerTreeWidget->verticalScrollBar()->value();
|
||||
|
||||
std::set<QString> expanded_indexes;
|
||||
QString selected;
|
||||
|
||||
// 2. Save the current state of the tree (which groups are open and what is selected)
|
||||
saveExpandedPathsAndSelection(expanded_indexes, selected);
|
||||
|
||||
#ifdef DEBUG_NEW_FRIEND_LIST
|
||||
std::cerr << "After collecting selection, selected paths is: \"" << selected.toStdString() << "\", " ;
|
||||
std::cerr << "expanded paths are: " << std::endl;
|
||||
for(auto path:expanded_indexes)
|
||||
std::cerr << " \"" << path.toStdString() << "\"" << std::endl;
|
||||
std::cerr << "Current sort column is: " << mLastSortColumn << " and order is " << mLastSortOrder << std::endl;
|
||||
#endif
|
||||
// 3. Clear selection and block signals to avoid UI flicker during updates
|
||||
whileBlocking(ui->peerTreeWidget)->clearSelection();
|
||||
|
||||
// This is a hack to avoid crashes on windows while calling endInsertRows(). I'm not sure wether these crashes are
|
||||
// due to a Qt bug, or a misuse of the proxy model on my side. Anyway, this solves them for good.
|
||||
// As a side effect we need to save/restore hidden columns because setSourceModel() resets this setting.
|
||||
|
||||
// save hidden columns and sizes
|
||||
// 4. Save current column visibility and widths
|
||||
// Detaching the model resets these settings, so we must back them up
|
||||
std::vector<bool> col_visible(RsFriendListModel::COLUMN_THREAD_NB_COLUMNS);
|
||||
std::vector<int> col_sizes(RsFriendListModel::COLUMN_THREAD_NB_COLUMNS);
|
||||
|
||||
for(int i=0;i<RsFriendListModel::COLUMN_THREAD_NB_COLUMNS;++i)
|
||||
for(int i=0; i < RsFriendListModel::COLUMN_THREAD_NB_COLUMNS; ++i)
|
||||
{
|
||||
col_visible[i] = !ui->peerTreeWidget->isColumnHidden(i);
|
||||
col_sizes[i] = ui->peerTreeWidget->columnWidth(i);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_NEW_FRIEND_LIST
|
||||
std::cerr << "Applying predicate..." << std::endl;
|
||||
#endif
|
||||
// 5. Detach the model from the view
|
||||
// This "hack" prevents crashes on some platforms (like Windows) during deep data updates
|
||||
mProxyModel->setSourceModel(nullptr);
|
||||
|
||||
// 6. Execute the actual data update (the predicate)
|
||||
predicate();
|
||||
|
||||
// 7. Reattach the model and restore expanded items/selection
|
||||
QModelIndex selected_index;
|
||||
mProxyModel->setSourceModel(mModel);
|
||||
restoreExpandedPathsAndSelection(expanded_indexes,selected,selected_index);
|
||||
restoreExpandedPathsAndSelection(expanded_indexes, selected, selected_index);
|
||||
|
||||
// restore hidden columns
|
||||
for(uint32_t i=0;i<RsFriendListModel::COLUMN_THREAD_NB_COLUMNS;++i)
|
||||
// 8. Restore the previously saved column visibility and widths
|
||||
for(uint32_t i=0; i < RsFriendListModel::COLUMN_THREAD_NB_COLUMNS; ++i)
|
||||
{
|
||||
ui->peerTreeWidget->setColumnHidden(i,!col_visible[i]);
|
||||
ui->peerTreeWidget->setColumnWidth(i,col_sizes[i]);
|
||||
ui->peerTreeWidget->setColumnHidden(i, !col_visible[i]);
|
||||
ui->peerTreeWidget->setColumnWidth(i, col_sizes[i]);
|
||||
}
|
||||
|
||||
// restore sorting
|
||||
// sortColumn(mLastSortColumn,mLastSortOrder);
|
||||
#ifdef DEBUG_NEW_FRIEND_LIST
|
||||
std::cerr << "Sorting again with sort column: " << mLastSortColumn << " and order " << mLastSortOrder << std::endl;
|
||||
#endif
|
||||
// 9. Re-apply the current sorting to the list
|
||||
mProxyModel->setSortingEnabled(true);
|
||||
mProxyModel->sort(mLastSortColumn,mLastSortOrder);
|
||||
mProxyModel->sort(mLastSortColumn, mLastSortOrder);
|
||||
mProxyModel->setSortingEnabled(false);
|
||||
|
||||
if(selected_index.isValid())
|
||||
ui->peerTreeWidget->scrollTo(selected_index);
|
||||
// 10. CRITICAL FIX: Restore the exact scroll position
|
||||
// We use setValue() instead of scrollTo() to ensure the view stays exactly where it was,
|
||||
// even if a friend connects/disconnects outside of the visible area.
|
||||
ui->peerTreeWidget->verticalScrollBar()->setValue(scrollValue);
|
||||
}
|
||||
|
||||
void NewFriendList::sortColumn(int col,Qt::SortOrder so)
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "FriendListModel.h"
|
||||
#include "retroshare/rsstatus.h"
|
||||
#include "util/FontSizeHandler.h"
|
||||
#include <QScrollBar>
|
||||
|
||||
namespace Ui {
|
||||
class NewFriendList;
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include <QMenu>
|
||||
#include <QTextEdit>
|
||||
#include <QTreeView>
|
||||
#include <QFileDialog>
|
||||
|
||||
#define COLUMN_FILE 0
|
||||
#define COLUMN_FILEPATH 1
|
||||
@ -54,12 +55,12 @@
|
||||
#define ROLE_FILEC Qt::UserRole + 6
|
||||
#define ROLE_SELFILEC Qt::UserRole + 7
|
||||
|
||||
#define MAX_FILE_ADDED_BEFORE_ASK 500 //Number of file added in Recursive mode before asking to continue
|
||||
#define MAX_FILE_ADDED_BEFORE_ASK 500 //Number of files added in Recursive mode before asking to continue
|
||||
|
||||
#define IMAGE_SEARCH ":/icons/svg/magnifying-glass.svg"
|
||||
|
||||
/**
|
||||
* @brief The FSMSortFilterProxyModel class sort directory before file.
|
||||
* @brief The FSMSortFilterProxyModel class sorts directories before files.
|
||||
*/
|
||||
class FSMSortFilterProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
@ -97,21 +98,20 @@ protected:
|
||||
return asc;
|
||||
|
||||
|
||||
/*If sorting by Size (Take real size, not Display one 10<2)*/
|
||||
/*If sorting by Size (Take real size, not Display string)*/
|
||||
if ((sortColumn()==1) && (!leftFileInfo.isDir() && !rightFileInfo.isDir())) {
|
||||
if (leftFileInfo.size() < rightFileInfo.size())
|
||||
return true;
|
||||
if (leftFileInfo.size() > rightFileInfo.size())
|
||||
return false;
|
||||
}
|
||||
/*If sorting by Date Modified (Take real date, not Display one 01-10-2014<02-01-1980)*/
|
||||
/*If sorting by Date Modified (Take real date, not Display string)*/
|
||||
if (sortColumn()==3) {
|
||||
if (leftFileInfo.lastModified() < rightFileInfo.lastModified())
|
||||
return true;
|
||||
if (leftFileInfo.lastModified() > rightFileInfo.lastModified())
|
||||
return false;
|
||||
}
|
||||
//Columns found here:https://qt.gitorious.org/qt/qt/source/9e8abb63ba4609887d988ee15ba6daee0b01380e:src/gui/dialogs/qfilesystemmodel.cpp
|
||||
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
}
|
||||
@ -121,11 +121,10 @@ protected:
|
||||
/**
|
||||
* @brief RsCollectionDialog::RsCollectionDialog
|
||||
* @param collectionFileName: Filename of RSCollection saved
|
||||
* @param creation: Open dialog as RsColl Creation or RsColl DownLoad
|
||||
* @param readOnly: Open dialog for RsColl as ReadOnly
|
||||
* @param mode: Open dialog as RsColl Creation or RsColl DownLoad
|
||||
*/
|
||||
RsCollectionDialog::RsCollectionDialog(const QString& collectionFileName, RsCollectionDialogMode mode)
|
||||
: _mode(mode)
|
||||
: _mode(mode), _dirModel(nullptr), _tree_proxyModel(nullptr), _selectionProxy(nullptr)
|
||||
{
|
||||
RsCollection::RsCollectionErrorCode err_code;
|
||||
mCollection = new RsCollection(collectionFileName,err_code);
|
||||
@ -140,11 +139,12 @@ RsCollectionDialog::RsCollectionDialog(const QString& collectionFileName, RsColl
|
||||
}
|
||||
|
||||
RsCollectionDialog::RsCollectionDialog(const RsCollection& coll, RsCollectionDialogMode mode)
|
||||
: _mode(mode)
|
||||
: _mode(mode), _dirModel(nullptr), _tree_proxyModel(nullptr), _selectionProxy(nullptr)
|
||||
{
|
||||
mCollection = new RsCollection(coll);
|
||||
init(QString());
|
||||
}
|
||||
|
||||
void RsCollectionDialog::init(const QString& collectionFileName)
|
||||
{
|
||||
ui.setupUi(this) ;
|
||||
@ -209,21 +209,32 @@ void RsCollectionDialog::init(const QString& collectionFileName)
|
||||
connect(ui._download_PB, SIGNAL(clicked()), this, SLOT(download()));
|
||||
connect(ui._hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
|
||||
|
||||
// 3 Initialize List
|
||||
_dirModel = new QFileSystemModel(this);
|
||||
_dirModel->setRootPath("/");
|
||||
_dirModel->setFilter(QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot);
|
||||
_dirLoaded = false;
|
||||
connect(_dirModel, SIGNAL(directoryLoaded(QString)), this, SLOT(directoryLoaded(QString)));
|
||||
// 3 Initialize Local System List ONLY in EDIT mode
|
||||
if (_mode == EDIT)
|
||||
{
|
||||
_dirModel = new QFileSystemModel(this);
|
||||
_dirModel->setRootPath(QDir::homePath());
|
||||
_dirModel->setFilter(QDir::AllEntries | QDir::NoSymLinks | QDir::NoDotAndDotDot);
|
||||
_dirLoaded = false;
|
||||
connect(_dirModel, SIGNAL(directoryLoaded(QString)), this, SLOT(directoryLoaded(QString)));
|
||||
|
||||
_tree_proxyModel = new FSMSortFilterProxyModel(this);
|
||||
_tree_proxyModel->setSourceModel(_dirModel);
|
||||
_tree_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
_tree_proxyModel->setSortRole(Qt::DisplayRole);
|
||||
_tree_proxyModel = new FSMSortFilterProxyModel(this);
|
||||
_tree_proxyModel->setSourceModel(_dirModel);
|
||||
_tree_proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
_tree_proxyModel->setSortRole(Qt::DisplayRole);
|
||||
|
||||
ui._systemFileTW->setModel(_tree_proxyModel);
|
||||
//Selection Setup
|
||||
_selectionProxy = ui._systemFileTW->selectionModel();
|
||||
ui._systemFileTW->setModel(_tree_proxyModel);
|
||||
_selectionProxy = ui._systemFileTW->selectionModel();
|
||||
|
||||
ui._systemFileTW->installEventFilter(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dirModel = nullptr;
|
||||
_tree_proxyModel = nullptr;
|
||||
_selectionProxy = nullptr;
|
||||
_dirLoaded = true;
|
||||
}
|
||||
|
||||
// 4 Restore Configuration
|
||||
// load settings
|
||||
@ -236,8 +247,6 @@ void RsCollectionDialog::init(const QString& collectionFileName)
|
||||
ui._treeViewFrame->setVisible(_mode == EDIT);
|
||||
ui._download_PB->setVisible(_mode == DOWNLOAD);
|
||||
|
||||
ui._systemFileTW->installEventFilter(this);
|
||||
|
||||
// 6 Add HashBox
|
||||
setAcceptDrops(true);
|
||||
ui._hashBox->setDropWidget(this);
|
||||
@ -306,7 +315,7 @@ void RsCollectionDialog::processSettings(bool bLoad)
|
||||
// load settings
|
||||
|
||||
if(_mode == EDIT){
|
||||
// Load windows geometrie
|
||||
// Load windows geometry
|
||||
restoreGeometry(Settings->value("WindowGeometrie_CM").toByteArray());
|
||||
// Load splitters state
|
||||
ui._mainSplitter->restoreState(Settings->value("MainSplitterState_CM").toByteArray());
|
||||
@ -316,7 +325,7 @@ void RsCollectionDialog::processSettings(bool bLoad)
|
||||
// Load file entries header configuration
|
||||
ui._fileEntriesTW->header()->restoreState(Settings->value("FileEntriesHeader_CM").toByteArray());
|
||||
} else {
|
||||
// Load windows geometrie
|
||||
// Load windows geometry
|
||||
restoreGeometry(Settings->value("WindowGeometrie").toByteArray());
|
||||
// Load splitters state
|
||||
ui._mainSplitter->restoreState(Settings->value("MainSplitterState").toByteArray());
|
||||
@ -328,7 +337,7 @@ void RsCollectionDialog::processSettings(bool bLoad)
|
||||
}
|
||||
} else {
|
||||
if(_mode == EDIT){
|
||||
// Save windows geometrie
|
||||
// Save windows geometry
|
||||
Settings->setValue("WindowGeometrie_CM",saveGeometry());
|
||||
// Save splitters state
|
||||
Settings->setValue("MainSplitterState_CM", ui._mainSplitter->saveState());
|
||||
@ -338,7 +347,7 @@ void RsCollectionDialog::processSettings(bool bLoad)
|
||||
// Save file entries header configuration
|
||||
Settings->setValue("FileEntriesHeader_CM", ui._fileEntriesTW->header()->saveState());
|
||||
} else {
|
||||
// Save windows geometrie
|
||||
// Save windows geometry
|
||||
Settings->setValue("WindowGeometrie",saveGeometry());
|
||||
// Save splitter state
|
||||
Settings->setValue("MainSplitterState", ui._mainSplitter->saveState());
|
||||
@ -359,6 +368,8 @@ void RsCollectionDialog::processSettings(bool bLoad)
|
||||
*/
|
||||
void RsCollectionDialog::directoryLoaded(QString dirLoaded)
|
||||
{
|
||||
if(!_dirModel) return;
|
||||
|
||||
if(!_dirLoaded)
|
||||
{
|
||||
|
||||
@ -545,13 +556,15 @@ static void recursBuildFileTree(const QString& path,RsFileTree& tree,RsFileTree:
|
||||
}
|
||||
/**
|
||||
* @brief RsCollectionDialog::addRecursive: Add Selected item to RSCollection
|
||||
* -Add File seperatly if parent folder not selected
|
||||
* -Add File in folder if selected
|
||||
* -Get root folder the selected one
|
||||
* -Add File seperatly if parent folder not selected
|
||||
* -Add File in folder if selected
|
||||
* -Get root folder the selected one
|
||||
* @param recursive: If true, add all selected directory childrens
|
||||
*/
|
||||
void RsCollectionDialog::addSelection(bool recursive)
|
||||
{
|
||||
if(!_dirModel) return;
|
||||
|
||||
QMap<QString, QString > dirToAdd;
|
||||
QModelIndexList milSelectionList = ui._systemFileTW->selectionModel()->selectedIndexes();
|
||||
|
||||
@ -599,7 +612,6 @@ void RsCollectionDialog::addSelection(bool recursive)
|
||||
void RsCollectionDialog::remove()
|
||||
{
|
||||
QMap<QString, QString > dirToRemove;
|
||||
int count=0;//to not scan all items on list .count()
|
||||
|
||||
QModelIndexList milSelectionList = ui._fileEntriesTW->selectionModel()->selectedIndexes();
|
||||
|
||||
@ -654,7 +666,7 @@ void RsCollectionDialog::makeDir()
|
||||
|
||||
/**
|
||||
* @brief RsCollectionDialog::fileHashingFinished: Connected to ui._hashBox.fileHashingFinished
|
||||
* Add finished File to collection in respective directory
|
||||
* Add finished File to collection in respective directory
|
||||
* @param hashedFiles: List of the file finished
|
||||
*/
|
||||
void RsCollectionDialog::fileHashingFinished(QList<HashedFile> hashedFiles)
|
||||
@ -772,10 +784,15 @@ void RsCollectionDialog::download()
|
||||
continue;
|
||||
|
||||
if(mb.clickedButton() == btnCorrectAll)
|
||||
{
|
||||
auto_correct = true;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Requesting file " << corrected_name << " to directory " << path << std::endl;
|
||||
if(mb.clickedButton() == btnCorrect)
|
||||
{
|
||||
auto_correct = false; // logic placeholder
|
||||
}
|
||||
}
|
||||
|
||||
rsFiles->FileRequest(corrected_name,f.hash,f.size,path,RS_FILE_REQ_ANONYMOUS_ROUTING,std::list<RsPeerId>());
|
||||
}
|
||||
@ -801,12 +818,12 @@ void RsCollectionDialog::save()
|
||||
close();
|
||||
}
|
||||
|
||||
bool RsCollectionDialog::editExistingCollection(const QString& fileName, bool showError /* = true*/)
|
||||
bool RsCollectionDialog::editExistingCollection(const QString& fileName, bool /*showError*/)
|
||||
{
|
||||
return RsCollectionDialog(fileName,EDIT).exec();
|
||||
}
|
||||
|
||||
bool RsCollectionDialog::openExistingCollection(const QString& fileName, bool showError /* = true*/)
|
||||
bool RsCollectionDialog::openExistingCollection(const QString& fileName, bool /*showError*/)
|
||||
{
|
||||
return RsCollectionDialog(fileName,DOWNLOAD).exec();
|
||||
}
|
||||
@ -845,6 +862,11 @@ bool RsCollectionDialog::openNewCollection(const RsFileTree& tree)
|
||||
|
||||
if (mb.clickedButton()==btnCancel)
|
||||
return false;
|
||||
|
||||
if (mb.clickedButton()==btnOwerWrite)
|
||||
{
|
||||
// Proceed to overwrite
|
||||
}
|
||||
}
|
||||
|
||||
if(!collection.save(fileName))
|
||||
@ -852,4 +874,3 @@ bool RsCollectionDialog::openNewCollection(const RsFileTree& tree)
|
||||
|
||||
return RsCollectionDialog(fileName,EDIT).exec();
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
#include <QTimer>
|
||||
#include <QTreeWidget>
|
||||
#include <QWheelEvent>
|
||||
#include <QPointer> // Required for thread safety check
|
||||
|
||||
#include <retroshare/rsgxstrans.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
@ -452,42 +453,35 @@ void GxsTransportStatistics::loadGroupStats(const RsGxsGroupId& groupId)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void GxsTransportStatistics::loadGroups()
|
||||
{
|
||||
mStateHelper->setLoading(GXSTRANS_GROUP_META, true);
|
||||
mStateHelper->setLoading(GXSTRANS_GROUP_META, true);
|
||||
|
||||
RsThread::async([this]()
|
||||
{
|
||||
// 1 - get message data from p3GxsForums
|
||||
/* Perform the statistics retrieval in a background thread to avoid UI lag */
|
||||
RsThread::async([this]()
|
||||
{
|
||||
/* Temporary storage for statistics retrieved from the GXS transport service */
|
||||
auto stats = new std::map<RsGxsGroupId, RsGxsTransGroupStatistics>();
|
||||
|
||||
#ifdef DEBUG_FORUMS
|
||||
std::cerr << "Retrieving post data for post " << mThreadId << std::endl;
|
||||
#endif
|
||||
auto stats = new std::map<RsGxsGroupId,RsGxsTransGroupStatistics>();
|
||||
|
||||
if(!rsGxsTrans->getGroupStatistics(*stats))
|
||||
{
|
||||
RS_ERR("Cannot retrieve group statistics in GxsTransportStatistics");
|
||||
if(!rsGxsTrans->getGroupStatistics(*stats))
|
||||
{
|
||||
RS_ERR("Cannot retrieve group statistics in GxsTransportStatistics");
|
||||
delete stats;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
RsQThreadUtils::postToObject( [stats, this]()
|
||||
{
|
||||
/* Here it goes any code you want to be executed on the Qt Gui
|
||||
* thread, for example to update the data model with new information
|
||||
* after a blocking call to RetroShare API complete */
|
||||
|
||||
// TODO: consider making mGroupStats an unique_ptr to avoid copying
|
||||
mGroupStats = *stats;
|
||||
updateContent();
|
||||
mStateHelper->setLoading(GXSTRANS_GROUP_META, false);
|
||||
/* Switch back to the GUI thread to update the display components */
|
||||
RsQThreadUtils::postToObject([stats, this]()
|
||||
{
|
||||
/* Update the local cache and refresh the tree widgets.
|
||||
* Since StatisticsWindow is no longer destroyed on close,
|
||||
* 'this' is guaranteed to be valid here. */
|
||||
mGroupStats = *stats;
|
||||
updateContent();
|
||||
mStateHelper->setLoading(GXSTRANS_GROUP_META, false);
|
||||
|
||||
delete stats;
|
||||
}, this );
|
||||
|
||||
}, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QActionGroup>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@ -73,8 +74,14 @@ void StatisticsWindow::showYourself()
|
||||
mInstance = new StatisticsWindow();
|
||||
}
|
||||
|
||||
/* Ensure the window is visible and restored if minimized */
|
||||
if (mInstance->isMinimized()) {
|
||||
mInstance->showNormal();
|
||||
}
|
||||
|
||||
mInstance->show();
|
||||
mInstance->activateWindow();
|
||||
mInstance->raise(); /* Bring to front */
|
||||
mInstance->activateWindow(); /* Give focus */
|
||||
}
|
||||
|
||||
StatisticsWindow* StatisticsWindow::getInstance()
|
||||
@ -91,23 +98,25 @@ void StatisticsWindow::releaseInstance()
|
||||
|
||||
/********************************************** STATIC WINDOW *************************************/
|
||||
|
||||
|
||||
|
||||
StatisticsWindow::StatisticsWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::StatisticsWindow)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
Settings->loadWidgetInformation(this);
|
||||
|
||||
Settings->loadWidgetInformation(this);
|
||||
|
||||
// Ensure the window is NOT destroyed on close to preserve temporal curves
|
||||
// and avoid async race conditions.
|
||||
this->setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
|
||||
initStackedPage();
|
||||
connect(ui->stackPages, SIGNAL(currentChanged(int)), this, SLOT(setNewPage(int)));
|
||||
ui->stackPages->setCurrentIndex(0);
|
||||
int toolSize = Settings->getToolButtonSize();
|
||||
ui->toolBar->setToolButtonStyle(Settings->getToolButtonStyle());
|
||||
ui->toolBar->setIconSize(QSize(toolSize,toolSize));
|
||||
setWindowTitle("RetroShare Statistics - " + MainWindow::getInstance()->get_nameAndLocation());
|
||||
int toolSize = Settings->getToolButtonSize();
|
||||
ui->toolBar->setToolButtonStyle(Settings->getToolButtonStyle());
|
||||
ui->toolBar->setIconSize(QSize(toolSize,toolSize));
|
||||
setWindowTitle("RetroShare Statistics - " + MainWindow::getInstance()->get_nameAndLocation());
|
||||
}
|
||||
|
||||
StatisticsWindow::~StatisticsWindow()
|
||||
@ -228,3 +237,15 @@ void StatisticsWindow::setNewPage(int page)
|
||||
ui->stackPages->setCurrentIndex(page);
|
||||
}
|
||||
}
|
||||
|
||||
void StatisticsWindow::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
// Just call close(), which will hide the window without destroying
|
||||
// the static instance or resetting statistics data.
|
||||
this->close();
|
||||
} else {
|
||||
QMainWindow::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,7 +66,8 @@ public slots:
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e);
|
||||
void closeEvent (QCloseEvent * event);
|
||||
void closeEvent (QCloseEvent * event);
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
private:
|
||||
void initStackedPage();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user