DocDiff application: differences dock widget

This commit is contained in:
Jakub Melka 2021-10-03 17:16:12 +02:00
parent 5972e17146
commit a78ed9f0b3
7 changed files with 144 additions and 6 deletions

View File

@ -22,6 +22,7 @@
#include "pdfwidgetutils.h" #include "pdfwidgetutils.h"
#include <QPixmap> #include <QPixmap>
#include <QPainter>
#include <QTreeWidgetItem> #include <QTreeWidgetItem>
namespace pdfdocdiff namespace pdfdocdiff
@ -82,12 +83,15 @@ DifferencesDockWidget::DifferencesDockWidget(QWidget* parent,
ui(new Ui::DifferencesDockWidget), ui(new Ui::DifferencesDockWidget),
m_diffResult(diffResult), m_diffResult(diffResult),
m_diffNavigator(diffNavigator), m_diffNavigator(diffNavigator),
m_settings(settings) m_settings(settings),
m_disableChangeSelectedResultIndex(false)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->differencesTreeWidget->setItemDelegate(new DifferenceItemDelegate(this)); ui->differencesTreeWidget->setItemDelegate(new DifferenceItemDelegate(this));
ui->differencesTreeWidget->setIconSize(pdf::PDFWidgetUtils::scaleDPI(ui->differencesTreeWidget, QSize(16, 16))); ui->differencesTreeWidget->setIconSize(pdf::PDFWidgetUtils::scaleDPI(ui->differencesTreeWidget, QSize(16, 16)));
connect(diffNavigator, &pdf::PDFDiffResultNavigator::selectionChanged, this, &DifferencesDockWidget::onSelectionChanged);
connect(ui->differencesTreeWidget, &QTreeWidget::currentItemChanged, this, &DifferencesDockWidget::onCurrentItemChanged);
setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, 120)); setMinimumWidth(pdf::PDFWidgetUtils::scaleDPI_x(this, 120));
} }
@ -123,6 +127,35 @@ QColor DifferencesDockWidget::getColorForIndex(size_t index) const
return color; return color;
} }
QModelIndex DifferencesDockWidget::findResultIndex(size_t index) const
{
QAbstractItemModel* model = ui->differencesTreeWidget->model();
const int count = ui->differencesTreeWidget->topLevelItemCount();
for (int i = 0; i < count; ++i)
{
QModelIndex parentIndex = model->index(i, 0);
if (parentIndex.isValid())
{
const int childCount = model->rowCount(parentIndex);
for (int j = 0; j < childCount; ++j)
{
QModelIndex childIndex = parentIndex.child(j, 0);
QVariant data = childIndex.data(Qt::UserRole);
if (data.isValid())
{
if (data.toULongLong() == index)
{
return childIndex;
}
}
}
}
}
return QModelIndex();
}
void DifferencesDockWidget::update() void DifferencesDockWidget::update()
{ {
ui->differencesTreeWidget->clear(); ui->differencesTreeWidget->clear();
@ -133,7 +166,31 @@ void DifferencesDockWidget::update()
if (m_diffResult && !m_diffResult->isSame()) if (m_diffResult && !m_diffResult->isSame())
{ {
std::map<QRgb, QIcon> icons;
auto getIcon = [this, &icons](QColor color)
{
auto it = icons.find(color.rgb());
if (it == icons.end())
{
QPixmap pixmap(ui->differencesTreeWidget->iconSize());
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(color));
painter.drawEllipse(0, 0, pixmap.width(), pixmap.height());
painter.end();
QIcon icon(pixmap);
it = icons.insert(std::make_pair(color.rgb(), std::move(icon))).first;
}
return it->second;
};
const size_t differenceCount = m_diffResult->getDifferencesCount(); const size_t differenceCount = m_diffResult->getDifferencesCount();
ui->infoTextLabel->setText(tr("%1 Differences").arg(differenceCount));
pdf::PDFInteger lastLeftPageIndex = -1; pdf::PDFInteger lastLeftPageIndex = -1;
pdf::PDFInteger lastRightPageIndex = -1; pdf::PDFInteger lastRightPageIndex = -1;
@ -185,17 +242,52 @@ void DifferencesDockWidget::update()
if (color.isValid()) if (color.isValid())
{ {
QPixmap pixmap(ui->differencesTreeWidget->iconSize()); item->setData(0, Qt::DecorationRole, getIcon(color));
pixmap.fill(color);
QIcon icon(pixmap);
item->setData(0, Qt::DecorationRole, icon);
} }
} }
} }
else
{
ui->infoTextLabel->setText(tr("No Differences Found!"));
}
ui->differencesTreeWidget->addTopLevelItems(topItems); ui->differencesTreeWidget->addTopLevelItems(topItems);
ui->differencesTreeWidget->expandAll(); ui->differencesTreeWidget->expandAll();
} }
void DifferencesDockWidget::onSelectionChanged(size_t currentIndex)
{
if (m_disableChangeSelectedResultIndex)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_disableChangeSelectedResultIndex, true);
QModelIndex index = findResultIndex(currentIndex);
if (index.isValid())
{
ui->differencesTreeWidget->scrollTo(index);
ui->differencesTreeWidget->setCurrentIndex(index);
}
}
void DifferencesDockWidget::onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
{
Q_UNUSED(previous);
if (m_disableChangeSelectedResultIndex || !current)
{
return;
}
pdf::PDFTemporaryValueChange guard(&m_disableChangeSelectedResultIndex, true);
QVariant data = current->data(0, Qt::UserRole);
if (data.isValid())
{
m_diffNavigator->select(data.toULongLong());
}
}
} // namespace pdfdocdiff } // namespace pdfdocdiff

View File

@ -28,6 +28,8 @@ namespace Ui
class DifferencesDockWidget; class DifferencesDockWidget;
} }
class QTreeWidgetItem;
namespace pdf namespace pdf
{ {
class PDFDiffResult; class PDFDiffResult;
@ -64,14 +66,20 @@ public:
void update(); void update();
private slots:
void onSelectionChanged(size_t currentIndex);
void onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
private: private:
Ui::DifferencesDockWidget* ui; Ui::DifferencesDockWidget* ui;
QColor getColorForIndex(size_t index) const; QColor getColorForIndex(size_t index) const;
QModelIndex findResultIndex(size_t index) const;
pdf::PDFDiffResult* m_diffResult; pdf::PDFDiffResult* m_diffResult;
pdf::PDFDiffResultNavigator* m_diffNavigator; pdf::PDFDiffResultNavigator* m_diffNavigator;
Settings* m_settings; Settings* m_settings;
bool m_disableChangeSelectedResultIndex;
}; };
} // namespace pdfdocdiff } // namespace pdfdocdiff

View File

@ -15,6 +15,23 @@
</property> </property>
<widget class="QWidget" name="dockWidgetContents"> <widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="infoTextLabel">
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item> <item>
<widget class="QTreeWidget" name="differencesTreeWidget"> <widget class="QTreeWidget" name="differencesTreeWidget">
<property name="wordWrap"> <property name="wordWrap">

View File

@ -139,6 +139,7 @@ MainWindow::MainWindow(QWidget* parent) :
m_diff.setRightDocument(&m_rightDocument); m_diff.setRightDocument(&m_rightDocument);
m_diffNavigator.setResult(&m_filteredDiffResult); m_diffNavigator.setResult(&m_filteredDiffResult);
connect(&m_diffNavigator, &pdf::PDFDiffResultNavigator::selectionChanged, this, &MainWindow::onSelectionChanged);
loadSettings(); loadSettings();
updateAll(false); updateAll(false);
@ -205,6 +206,12 @@ void MainWindow::updateActions()
} }
} }
void MainWindow::onSelectionChanged(size_t currentIndex)
{
Q_UNUSED(currentIndex);
updateActions();
}
void MainWindow::loadSettings() void MainWindow::loadSettings()
{ {
QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName()); QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

View File

@ -79,6 +79,7 @@ public:
private slots: private slots:
void updateActions(); void updateActions();
void onSelectionChanged(size_t currentIndex);
private: private:
void onMappedActionTriggered(int actionId); void onMappedActionTriggered(int actionId);

View File

@ -1571,4 +1571,13 @@ void PDFDiffResultNavigator::update()
} }
} }
void PDFDiffResultNavigator::select(size_t currentIndex)
{
if (currentIndex < getLimit() && m_currentIndex != currentIndex)
{
m_currentIndex = currentIndex;
emit selectionChanged(m_currentIndex);
}
}
} // namespace pdf } // namespace pdf

View File

@ -215,6 +215,10 @@ public:
/// Updates selection, if difference result was changed /// Updates selection, if difference result was changed
void update(); void update();
/// Selects current index
/// \param currentIndex
void select(size_t currentIndex);
signals: signals:
void selectionChanged(size_t currentIndex); void selectionChanged(size_t currentIndex);