Merge branch 'master' into DisplayEngineVersion

This commit is contained in:
jolavillette 2026-01-07 23:37:21 +01:00
commit c631972ee5
7 changed files with 194 additions and 161 deletions

View File

@ -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:

View File

@ -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)

View File

@ -30,6 +30,7 @@
#include "FriendListModel.h"
#include "retroshare/rsstatus.h"
#include "util/FontSizeHandler.h"
#include <QScrollBar>
namespace Ui {
class NewFriendList;

View File

@ -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();
}

View File

@ -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);
});
}

View File

@ -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);
}
}

View File

@ -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();