2012-11-27 18:21:20 -05:00
|
|
|
/****************************************************************
|
|
|
|
* This file is distributed under the following license:
|
|
|
|
*
|
|
|
|
* Copyright (c) 2012, RetroShare Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
****************************************************************/
|
2016-08-05 12:15:21 -04:00
|
|
|
#include "RSTreeWidget.h"
|
2012-11-27 18:21:20 -05:00
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
#include <QHBoxLayout>
|
2015-07-09 16:23:52 -04:00
|
|
|
#include <QHeaderView>
|
2016-08-05 12:15:21 -04:00
|
|
|
#include <QLabel>
|
2015-07-09 16:23:52 -04:00
|
|
|
#include <QMenu>
|
2016-08-05 12:15:21 -04:00
|
|
|
#include <QMouseEvent>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QWidgetAction>
|
2012-11-27 18:21:20 -05:00
|
|
|
|
2015-07-09 16:23:52 -04:00
|
|
|
#include "gui/settings/rsharesettings.h"
|
2012-11-27 18:21:20 -05:00
|
|
|
|
|
|
|
RSTreeWidget::RSTreeWidget(QWidget *parent) : QTreeWidget(parent)
|
|
|
|
{
|
2015-08-08 14:27:19 -04:00
|
|
|
mEnableColumnCustomize = false;
|
|
|
|
mSettingsVersion = 0; // disabled
|
2015-08-21 12:24:56 -04:00
|
|
|
|
|
|
|
QHeaderView *h = header();
|
|
|
|
h->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
connect(h, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(headerContextMenuRequested(QPoint)));
|
2012-11-27 18:21:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void RSTreeWidget::setPlaceholderText(const QString &text)
|
|
|
|
{
|
2013-01-05 21:30:10 -05:00
|
|
|
mPlaceholderText = text;
|
2012-11-27 18:21:20 -05:00
|
|
|
viewport()->repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RSTreeWidget::paintEvent(QPaintEvent *event)
|
|
|
|
{
|
|
|
|
QTreeWidget::paintEvent(event);
|
|
|
|
|
2013-01-05 21:30:10 -05:00
|
|
|
if (mPlaceholderText.isEmpty() == false && model() && model()->rowCount() == 0) {
|
2012-11-27 18:21:20 -05:00
|
|
|
QWidget *vieportWidget = viewport();
|
|
|
|
QPainter painter(vieportWidget);
|
|
|
|
|
|
|
|
QPen pen = painter.pen();
|
|
|
|
QColor color = pen.color();
|
|
|
|
color.setAlpha(128);
|
|
|
|
pen.setColor(color);
|
|
|
|
painter.setPen(pen);
|
|
|
|
|
2013-01-05 21:30:10 -05:00
|
|
|
painter.drawText(QRect(QPoint(), vieportWidget->size()), Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap, mPlaceholderText);
|
2012-11-27 18:21:20 -05:00
|
|
|
}
|
|
|
|
}
|
2013-01-05 21:30:10 -05:00
|
|
|
|
|
|
|
void RSTreeWidget::mousePressEvent(QMouseEvent *event)
|
|
|
|
{
|
2013-01-14 17:42:48 -05:00
|
|
|
#if QT_VERSION < 0x040700
|
|
|
|
if (event->buttons() & Qt::MidButton) {
|
|
|
|
#else
|
2013-01-05 21:30:10 -05:00
|
|
|
if (event->buttons() & Qt::MiddleButton) {
|
2013-01-14 17:42:48 -05:00
|
|
|
#endif
|
2013-01-05 21:30:10 -05:00
|
|
|
if (receivers(SIGNAL(signalMouseMiddleButtonClicked(QTreeWidgetItem*))) > 0) {
|
|
|
|
QTreeWidgetItem *item = itemAt(event->pos());
|
|
|
|
if (item) {
|
|
|
|
setCurrentItem(item);
|
|
|
|
emit signalMouseMiddleButtonClicked(item);
|
|
|
|
}
|
|
|
|
return; // eat event
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QTreeWidget::mousePressEvent(event);
|
|
|
|
}
|
2013-07-09 07:58:55 -04:00
|
|
|
|
2015-08-26 13:26:20 -04:00
|
|
|
void RSTreeWidget::filterItems(int filterColumn, const QString &text, int role)
|
2013-07-09 07:58:55 -04:00
|
|
|
{
|
|
|
|
int count = topLevelItemCount();
|
|
|
|
for (int index = 0; index < count; ++index) {
|
2015-08-26 13:26:20 -04:00
|
|
|
filterItem(topLevelItem(index), filterColumn, text, role);
|
2013-07-09 07:58:55 -04:00
|
|
|
}
|
2015-07-09 16:23:52 -04:00
|
|
|
|
|
|
|
QTreeWidgetItem *item = currentItem();
|
|
|
|
if (item && item->isHidden()) {
|
|
|
|
// active item is hidden, deselect it
|
|
|
|
setCurrentItem(NULL);
|
|
|
|
}
|
2013-07-09 07:58:55 -04:00
|
|
|
}
|
|
|
|
|
2015-08-26 13:26:20 -04:00
|
|
|
bool RSTreeWidget::filterItem(QTreeWidgetItem *item, int filterColumn, const QString &text, int role)
|
2013-07-09 07:58:55 -04:00
|
|
|
{
|
|
|
|
bool itemVisible = true;
|
|
|
|
|
|
|
|
if (!text.isEmpty()) {
|
2015-08-26 13:26:20 -04:00
|
|
|
if (!item->data(filterColumn, role).toString().contains(text, Qt::CaseInsensitive)) {
|
2013-07-09 07:58:55 -04:00
|
|
|
itemVisible = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int visibleChildCount = 0;
|
|
|
|
int count = item->childCount();
|
|
|
|
for (int index = 0; index < count; ++index) {
|
2015-08-26 13:26:20 -04:00
|
|
|
if (filterItem(item->child(index), filterColumn, text, role)) {
|
2013-07-09 07:58:55 -04:00
|
|
|
++visibleChildCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itemVisible || visibleChildCount) {
|
|
|
|
item->setHidden(false);
|
|
|
|
} else {
|
|
|
|
item->setHidden(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (itemVisible || visibleChildCount);
|
|
|
|
}
|
2015-07-09 16:23:52 -04:00
|
|
|
|
2015-08-08 14:27:19 -04:00
|
|
|
void RSTreeWidget::setSettingsVersion(qint32 version)
|
|
|
|
{
|
|
|
|
mSettingsVersion = version;
|
|
|
|
}
|
|
|
|
|
2015-07-09 16:23:52 -04:00
|
|
|
void RSTreeWidget::processSettings(bool load)
|
|
|
|
{
|
|
|
|
if (load) {
|
2015-08-08 14:27:19 -04:00
|
|
|
// Load settings
|
2015-07-09 16:23:52 -04:00
|
|
|
|
2015-08-08 14:27:19 -04:00
|
|
|
// State of tree widget
|
|
|
|
if (mSettingsVersion == 0 || Settings->value(QString("%1Version").arg(objectName())) == mSettingsVersion) {
|
|
|
|
// Compare version, because Qt can crash in restoreState after column changes
|
|
|
|
header()->restoreState(Settings->value(objectName()).toByteArray());
|
|
|
|
}
|
2015-07-09 16:23:52 -04:00
|
|
|
} else {
|
2015-08-08 14:27:19 -04:00
|
|
|
// Save settings
|
2015-07-09 16:23:52 -04:00
|
|
|
|
|
|
|
// state of tree widget
|
|
|
|
Settings->setValue(objectName(), header()->saveState());
|
2015-08-08 14:27:19 -04:00
|
|
|
|
|
|
|
// Save version
|
|
|
|
if (mSettingsVersion) {
|
|
|
|
Settings->setValue(QString("%1Version").arg(objectName()), mSettingsVersion);
|
|
|
|
}
|
2015-07-09 16:23:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-08 14:27:19 -04:00
|
|
|
void RSTreeWidget::enableColumnCustomize(bool customizable)
|
2015-07-09 16:23:52 -04:00
|
|
|
{
|
2015-08-08 14:27:19 -04:00
|
|
|
if (customizable == mEnableColumnCustomize) {
|
2015-07-09 16:23:52 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-08-08 14:27:19 -04:00
|
|
|
mEnableColumnCustomize = customizable;
|
2015-07-09 16:23:52 -04:00
|
|
|
}
|
|
|
|
|
2015-08-08 14:27:19 -04:00
|
|
|
void RSTreeWidget::setColumnCustomizable(int column, bool customizable)
|
|
|
|
{
|
|
|
|
mColumnCustomizable[column] = customizable;
|
|
|
|
}
|
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
void RSTreeWidget::addContextMenuAction(QAction *action)
|
2015-08-21 12:24:56 -04:00
|
|
|
{
|
2016-08-05 12:15:21 -04:00
|
|
|
mContextMenuActions.push_back(action);
|
2015-08-21 12:24:56 -04:00
|
|
|
}
|
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
void RSTreeWidget::addContextMenuMenu(QMenu *menu)
|
2016-07-29 14:54:26 -04:00
|
|
|
{
|
2016-08-05 12:15:21 -04:00
|
|
|
mContextMenuMenus.push_back(menu);
|
2016-07-29 14:54:26 -04:00
|
|
|
}
|
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
QMenu *RSTreeWidget::createStandardContextMenu(QMenu *contextMenu)
|
2015-07-09 16:23:52 -04:00
|
|
|
{
|
2016-08-05 12:15:21 -04:00
|
|
|
if (!contextMenu){
|
|
|
|
contextMenu = new QMenu(this);
|
|
|
|
contextMenu->addSeparator();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!mContextMenuActions.isEmpty() || mEnableColumnCustomize ||!mContextMenuActions.isEmpty() || !mContextMenuMenus.isEmpty()) {
|
|
|
|
QWidget *widget = new QWidget(contextMenu);
|
|
|
|
widget->setStyleSheet( ".QWidget{background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #FEFEFE, stop:1 #E8E8E8); border: 1px solid #CCCCCC;}");
|
|
|
|
|
|
|
|
// create menu header
|
|
|
|
QHBoxLayout *hbox = new QHBoxLayout(widget);
|
|
|
|
hbox->setMargin(0);
|
|
|
|
hbox->setSpacing(6);
|
|
|
|
|
|
|
|
QLabel *iconLabel = new QLabel(widget);
|
|
|
|
QPixmap pix = QPixmap(":/images/settings.png").scaledToHeight(QFontMetricsF(iconLabel->font()).height()*1.5);
|
|
|
|
iconLabel->setPixmap(pix);
|
|
|
|
iconLabel->setMaximumSize(iconLabel->frameSize().height() + pix.height(), pix.width());
|
|
|
|
hbox->addWidget(iconLabel);
|
|
|
|
|
|
|
|
QLabel *textLabel = new QLabel("<strong>" + tr("Tree View Options") + "</strong>", widget);
|
|
|
|
hbox->addWidget(textLabel);
|
|
|
|
|
|
|
|
QSpacerItem *spacerItem = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
|
|
hbox->addItem(spacerItem);
|
|
|
|
|
|
|
|
widget->setLayout(hbox);
|
|
|
|
|
|
|
|
QWidgetAction *widgetAction = new QWidgetAction(this);
|
|
|
|
widgetAction->setDefaultWidget(widget);
|
|
|
|
contextMenu->addAction(widgetAction);
|
|
|
|
}
|
2015-08-21 12:24:56 -04:00
|
|
|
|
|
|
|
if (mEnableColumnCustomize) {
|
2016-08-05 12:15:21 -04:00
|
|
|
QMenu *headerMenu = contextMenu->addMenu(QIcon(),tr("Show Headers"));
|
|
|
|
|
2015-08-21 12:24:56 -04:00
|
|
|
QTreeWidgetItem *item = headerItem();
|
|
|
|
int columnCount = item->columnCount();
|
|
|
|
for (int column = 0; column < columnCount; ++column) {
|
|
|
|
QMap<int, bool>::const_iterator it = mColumnCustomizable.find(column);
|
|
|
|
if (it != mColumnCustomizable.end() && *it == false) {
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-05 12:15:21 -04:00
|
|
|
QAction *action = headerMenu->addAction(QIcon(), item->text(column), this, SLOT(columnVisible()));
|
2015-08-21 12:24:56 -04:00
|
|
|
action->setCheckable(true);
|
|
|
|
action->setData(column);
|
|
|
|
action->setChecked(!isColumnHidden(column));
|
|
|
|
}
|
2015-07-09 16:23:52 -04:00
|
|
|
}
|
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
if (!mContextMenuActions.isEmpty()) {
|
2015-08-21 12:24:56 -04:00
|
|
|
bool addSeparator = false;
|
2016-08-05 12:15:21 -04:00
|
|
|
if (!contextMenu->isEmpty()) {
|
2015-08-21 12:24:56 -04:00
|
|
|
// Check for visible action
|
2016-08-05 12:15:21 -04:00
|
|
|
foreach (QAction *action, mContextMenuActions) {
|
2015-08-21 12:24:56 -04:00
|
|
|
if (action->isVisible()) {
|
|
|
|
addSeparator = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-09 16:23:52 -04:00
|
|
|
|
2015-08-21 12:24:56 -04:00
|
|
|
if (addSeparator) {
|
2016-08-05 12:15:21 -04:00
|
|
|
contextMenu->addSeparator();
|
2015-08-08 14:27:19 -04:00
|
|
|
}
|
2015-08-21 12:24:56 -04:00
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
contextMenu->addActions(mContextMenuActions);
|
2015-08-21 12:24:56 -04:00
|
|
|
}
|
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
if (!mContextMenuMenus.isEmpty()) {
|
|
|
|
foreach(QMenu *menu, mContextMenuMenus) {
|
|
|
|
contextMenu->addSeparator();
|
|
|
|
contextMenu->addMenu(menu);
|
2016-07-29 14:54:26 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
return contextMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RSTreeWidget::headerContextMenuRequested(const QPoint &pos)
|
|
|
|
{
|
|
|
|
QMenu *contextMenu = createStandardContextMenu(NULL);
|
|
|
|
if (contextMenu->isEmpty()) {
|
2015-08-21 12:24:56 -04:00
|
|
|
return;
|
2015-07-09 16:23:52 -04:00
|
|
|
}
|
|
|
|
|
2016-08-05 12:15:21 -04:00
|
|
|
contextMenu->exec(mapToGlobal(pos));
|
|
|
|
delete contextMenu;
|
2015-07-09 16:23:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void RSTreeWidget::columnVisible()
|
|
|
|
{
|
|
|
|
QAction *action = dynamic_cast<QAction*>(sender());
|
|
|
|
if (!action) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int column = action->data().toInt();
|
|
|
|
bool visible = action->isChecked();
|
|
|
|
setColumnHidden(column, !visible);
|
|
|
|
|
|
|
|
emit columnVisibleChanged(column, visible);
|
|
|
|
}
|
2015-08-21 12:24:56 -04:00
|
|
|
|
|
|
|
void RSTreeWidget::resort()
|
|
|
|
{
|
|
|
|
if (isSortingEnabled()) {
|
|
|
|
sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
|
|
|
|
}
|
|
|
|
}
|