1
0
Fork 0

Invalidate font size cache (#723)

* GUI: fix issues related to surrogates

Assume UTF-16LE byte order now.

* GUI: resolve issue #722

invalidate font size cache when font is updated.

* GUI: remove asterisks

* GUI: allow hiding columns

* GUI: column edit dialog

* GUI: column edit dialog

* GUI: column edit dialog

* GUI: column edit dialog

* GUI: resolve issue #722

* GUI: column edit dialog
This commit is contained in:
Torusrxxx 2016-06-06 09:19:38 +00:00 committed by Duncan Ogilvie
parent c5cfa605e9
commit c800b2f5ba
9 changed files with 413 additions and 29 deletions

View File

@ -1,6 +1,7 @@
#include "AbstractTableView.h"
#include <QStyleOptionButton>
#include "Configuration.h"
#include "ColumnReorderDialog.h"
AbstractTableView::AbstractTableView(QWidget* parent)
: QAbstractScrollArea(parent),
@ -77,13 +78,16 @@ void AbstractTableView::updateColors()
void AbstractTableView::updateFonts()
{
setFont(ConfigFont("AbstractTableView"));
puts("updateFonts()");
if(mFontMetrics)
delete mFontMetrics;
mFontMetrics = new CachedFontMetrics(this, font());
invalidateCachedFont();
mHeader.height = QFontMetrics(font()).height() + 4;
}
void AbstractTableView::invalidateCachedFont()
{
delete mFontMetrics;
mFontMetrics = new CachedFontMetrics(this, font());
}
void AbstractTableView::updateShortcuts()
{
for(const auto & actionShortcut : actionShortcutPairs)
@ -122,12 +126,17 @@ void AbstractTableView::paintEvent(QPaintEvent* event)
if(getColumnCount()) //make sure the last column is never smaller than the window
{
int totalWidth = 0;
int last = getColumnCount() - 1;
for(int i = 0; i < last; i++)
totalWidth += getColumnWidth(mColumnOrder[i]);
int lastWidth = totalWidth;
last = mColumnOrder[last];
totalWidth += getColumnWidth(last);
int last = 0;
for(int i = 0; i < getColumnCount(); i++)
{
if(getColumnHidden(mColumnOrder[i]))
continue;
last = mColumnOrder[i];
lastWidth = getColumnWidth(last);
totalWidth += lastWidth;
}
lastWidth = totalWidth - lastWidth;
int width = this->viewport()->width();
lastWidth = width > lastWidth ? width - lastWidth : 0;
if(totalWidth < width)
@ -162,9 +171,9 @@ void AbstractTableView::paintEvent(QPaintEvent* event)
for(int j = 0; j < getColumnCount(); j++)
{
int i = mColumnOrder[j];
int width = getColumnWidth(i);
if(width == 0)
if(getColumnHidden(i))
continue;
int width = getColumnWidth(i);
QStyleOptionButton wOpt;
if((mColumnList[i].header.isPressed == true) && (mColumnList[i].header.isMouseOver == true)
|| (mGuiState==AbstractTableView::HeaderButtonReordering && mColumnOrder[mHoveredColumnDisplayIndex] == i))
@ -190,6 +199,8 @@ void AbstractTableView::paintEvent(QPaintEvent* event)
for(int k = 0; k < getColumnCount(); k++)
{
int j = mColumnOrder[k];
if(getColumnHidden(j))
continue;
for(int i = 0; i < wViewableRowsCount; i++)
{
// Paints cell contents
@ -433,6 +444,15 @@ void AbstractTableView::mouseReleaseEvent(QMouseEvent* event)
}
}
void AbstractTableView::mouseDoubleClickEvent(QMouseEvent *event)
{
if(event->y() < getHeaderHeight())
{
ColumnReorderDialog reorderDialog(this);
reorderDialog.setWindowTitle(tr("Edit columns"));
reorderDialog.exec();
}
}
/**
* @brief This method has been reimplemented. It manages the following actions:
@ -666,11 +686,11 @@ dsint AbstractTableView::scaleFromScrollBarRangeToUint64(int value)
/**
* @brief This method updates the scrollbar range and pre-computes some attributes for the 32<->64bits conversion methods.
* @brief This method updates the vertical scrollbar range and pre-computes some attributes for the 32<->64bits conversion methods.
*
* @param[in] range New table range (size)
*
* @return 32bits integer.
* @return none.
*/
void AbstractTableView::updateScrollBarRange(dsint range)
{
@ -745,7 +765,10 @@ int AbstractTableView::getColumnIndexFromX(int x)
while(wColIndex < getColumnCount())
{
wX += getColumnWidth(mColumnOrder[wColIndex]);
int col = mColumnOrder[wColIndex];
if(getColumnHidden(col))
continue;
wX += getColumnWidth(col);
if(x <= wX)
{
@ -773,7 +796,10 @@ int AbstractTableView::getColumnDisplayIndexFromX(int x)
while(wColIndex < getColumnCount())
{
wX += getColumnWidth(mColumnOrder[wColIndex]);
int col = mColumnOrder[wColIndex];
if(getColumnHidden(col))
continue;
wX += getColumnWidth(col);
if(x <= wX)
{
@ -803,7 +829,8 @@ int AbstractTableView::getColumnPosition(int index)
{
index = mColumnOrder[index];
for(int i = 0; i < index; i++)
posX += getColumnWidth(mColumnOrder[i]);
if(!getColumnHidden(mColumnOrder[i]))
posX += getColumnWidth(mColumnOrder[i]);
return posX;
}
else
@ -880,7 +907,7 @@ void AbstractTableView::addColumnAt(int width, const QString & title, bool isCli
wColumn.header = wHeaderButton;
wColumn.width = width;
wColumn.hidden = false;
wColumn.title = title;
wCurrentCount = mColumnList.length();
mColumnList.append(wColumn);
@ -911,7 +938,7 @@ void AbstractTableView::setColTitle(int index, const QString & title)
QString AbstractTableView::getColTitle(int index)
{
if(mColumnList.size() > 0 && index >= 0 && index < mColumnList.size())
return mColumnList.at(index).title;
return mColumnList[index].title;
return "";
}
@ -941,15 +968,32 @@ int AbstractTableView::getColumnWidth(int index)
if(index < 0)
return -1;
else if(index < getColumnCount())
return mColumnList.at(index).width;
return mColumnList[index].width;
return 0;
}
bool AbstractTableView::getColumnHidden(int col)
{
if(col < 0)
return true;
else if(col < getColumnCount())
return mColumnList[col].hidden;
else
return true;
}
void AbstractTableView::setColumnHidden(int col, bool hidden)
{
if(col < getColumnCount() && col >= 0)
mColumnList[col].hidden = hidden;
}
void AbstractTableView::setColumnWidth(int index, int width)
{
int totalWidth = 0;
for(int i = 0; i < getColumnCount(); i++)
totalWidth += getColumnWidth(i);
if(!getColumnHidden(i))
totalWidth += getColumnWidth(i);
if(totalWidth > this->viewport()->width())
horizontalScrollBar()->setRange(0, totalWidth - this->viewport()->width());
else if(totalWidth <= this->viewport()->width())

View File

@ -64,6 +64,7 @@ public:
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
void wheelEvent(QWheelEvent* event);
void resizeEvent(QResizeEvent* event);
void keyPressEvent(QKeyEvent* event);
@ -154,6 +155,7 @@ private:
typedef struct _Column_t
{
int width;
bool hidden;
HeaderButton_t header;
QString title;
} Column_t;
@ -199,6 +201,9 @@ private:
ScrollBar64_t mScrollBarAttributes;
int getColumnDisplayIndexFromX(int x);
bool getColumnHidden(int col);
void setColumnHidden(int col, bool hidden);
friend class ColumnReorderDialog;
protected:
bool mAllowPainting;
bool mDrawDebugOnly;
@ -212,6 +217,7 @@ protected:
// Font metrics
CachedFontMetrics* mFontMetrics;
void invalidateCachedFont();
//action helpers
private:

View File

@ -116,6 +116,7 @@ void Disassembly::updateColors()
void Disassembly::updateFonts()
{
setFont(ConfigFont("Disassembly"));
invalidateCachedFont();
}
void Disassembly::tokenizerConfigUpdatedSlot()

View File

@ -0,0 +1,145 @@
#include "ColumnReorderDialog.h"
#include "ui_ColumnReorderDialog.h"
#include <QMessageBox>
ColumnReorderDialog::ColumnReorderDialog(AbstractTableView *parent) :
QDialog(parent),
mParent(parent),
ui(new Ui::ColumnReorderDialog)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
for(int j = 0; j < parent->getColumnCount(); j++)
{
int i = parent->mColumnOrder[j];
if(parent->getColumnHidden(i))
{
ui->listAvailable->addItem(parent->getColTitle(i));
ui->listAvailable->item(ui->listAvailable->count() - 1)->setData(1, QVariant(j));
}
else
{
ui->listDisplayed->addItem(parent->getColTitle(i));
ui->listDisplayed->item(ui->listDisplayed->count() - 1)->setData(1, QVariant(j));
}
}
if(ui->listAvailable->count() == 0)
{
ui->addAllButton->setEnabled(false);
ui->addButton->setEnabled(false);
}
}
ColumnReorderDialog::~ColumnReorderDialog()
{
delete ui;
}
void ColumnReorderDialog::on_okButton_clicked()
{
int i = 0;
if(ui->listDisplayed->count() == 0)
{
QMessageBox msg(QMessageBox::Warning, tr("Error"), tr("There isn't anything to display yet!"));
msg.exec();
return;
}
for(i = 0; i < ui->listDisplayed->count(); i++)
{
int col = ui->listDisplayed->item(i)->data(1).toInt();
mParent->mColumnOrder[i] = col;
mParent->setColumnHidden(col, false);
}
for(int j = 0; j < ui->listAvailable->count(); j++, i++)
{
int col = ui->listAvailable->item(j)->data(1).toInt();
mParent->mColumnOrder[i] = col;
mParent->setColumnHidden(col, true);
}
this->done(QDialog::Accepted);
}
void ColumnReorderDialog::on_cancelButton_clicked()
{
this->done(QDialog::Rejected);
}
void ColumnReorderDialog::on_addButton_clicked()
{
if(ui->listAvailable->selectedItems().empty())
return;
auto selected = ui->listAvailable->selectedItems();
for(auto i : selected)
{
ui->listDisplayed->addItem(i->text());
ui->listDisplayed->item(ui->listDisplayed->count() - 1)->setData(1, i->data(1));
delete i;
}
if(ui->listAvailable->count() == 0)
{
ui->addAllButton->setEnabled(false);
ui->addButton->setEnabled(false);
}
}
void ColumnReorderDialog::on_addAllButton_clicked()
{
for(int i = 0; i < ui->listAvailable->count(); i++)
{
ui->listDisplayed->addItem(ui->listAvailable->item(i)->text());
ui->listDisplayed->item(ui->listDisplayed->count() - 1)->setData(1, ui->listAvailable->item(i)->data(1));
}
ui->listAvailable->clear();
ui->addAllButton->setEnabled(false);
ui->addButton->setEnabled(false);
}
void ColumnReorderDialog::on_upButton_clicked()
{
if(ui->listDisplayed->selectedItems().empty())
return;
auto i = ui->listDisplayed->currentIndex().row();
if(i != 0)
{
auto prevItem = ui->listDisplayed->item(i - 1);
auto currentItem = ui->listDisplayed->item(i);
QString text = prevItem->text();
auto data = prevItem->data(1);
prevItem->setText(currentItem->text());
prevItem->setData(1, currentItem->data(1));
currentItem->setText(text);
currentItem->setData(1, data);
ui->listDisplayed->setCurrentRow(i - 1);
}
}
void ColumnReorderDialog::on_downButton_clicked()
{
if(ui->listDisplayed->selectedItems().empty())
return;
auto i = ui->listDisplayed->currentIndex().row();
if(i != ui->listDisplayed->count() - 1)
{
auto nextItem = ui->listDisplayed->item(i + 1);
auto currentItem = ui->listDisplayed->item(i);
QString text = nextItem->text();
auto data = nextItem->data(1);
nextItem->setText(currentItem->text());
nextItem->setData(1, currentItem->data(1));
currentItem->setText(text);
currentItem->setData(1, data);
ui->listDisplayed->setCurrentRow(i + 1);
}
}
void ColumnReorderDialog::on_hideButton_clicked()
{
if(ui->listDisplayed->selectedItems().empty())
return;
auto currentItem = ui->listDisplayed->currentItem();
ui->listAvailable->addItem(currentItem->text());
ui->listAvailable->item(ui->listAvailable->count() - 1)->setData(1, currentItem->data(1));
delete currentItem;
ui->addAllButton->setEnabled(true);
ui->addButton->setEnabled(true);
}

View File

@ -0,0 +1,33 @@
#ifndef COLUMNREORDERDIALOG_H
#define COLUMNREORDERDIALOG_H
#include "AbstractTableView.h"
#include <QDialog>
namespace Ui {
class ColumnReorderDialog;
}
class ColumnReorderDialog : public QDialog
{
Q_OBJECT
public:
explicit ColumnReorderDialog(AbstractTableView* parent = 0);
~ColumnReorderDialog();
private slots:
void on_upButton_clicked();
void on_downButton_clicked();
void on_addButton_clicked();
void on_hideButton_clicked();
void on_addAllButton_clicked();
void on_okButton_clicked();
void on_cancelButton_clicked();
private:
Ui::ColumnReorderDialog* ui;
AbstractTableView* mParent;
};
#endif // COLUMNREORDERDIALOG_H

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ColumnReorderDialog</class>
<widget class="QDialog" name="ColumnReorderDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>352</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout0">
<item>
<widget class="QLabel" name="label0">
<property name="text">
<string>Displayed</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listDisplayed"/>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout1">
<item>
<widget class="QPushButton" name="addButton">
<property name="text">
<string>&lt;- Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="hideButton">
<property name="text">
<string>Hide -&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="upButton">
<property name="text">
<string>Up</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="downButton">
<property name="text">
<string>Down</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addAllButton">
<property name="text">
<string>&lt;&lt; Add all</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout2">
<item>
<widget class="QLabel" name="label1">
<property name="text">
<string>Available</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listAvailable">
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="okButton">
<property name="text">
<string>&amp;Ok</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>&amp;Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -387,28 +387,28 @@
<item>
<widget class="QCheckBox" name="chkArgumentSpaces">
<property name="text">
<string>Argument Spaces*</string>
<string>Argument Spaces</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkTabBetweenMnemonicAndArguments">
<property name="text">
<string>Tab between mnemonic and arguments*</string>
<string>Tab between mnemonic and arguments</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkMemorySpaces">
<property name="text">
<string>Memory Spaces*</string>
<string>Memory Spaces</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkUppercase">
<property name="text">
<string>Uppercase*</string>
<string>Uppercase</string>
</property>
</widget>
</item>

View File

@ -19,6 +19,14 @@ public:
int width(const QChar & ch)
{
auto unicode = ch.unicode();
if(unicode >= 0xD800)
{
if(unicode >= 0xE000)
unicode -= 0xE000 - 0xD800;
else
// is lonely surrogate
return mFontMetrics.width(ch);
}
if(!mWidths[unicode])
return mWidths[unicode] = mFontMetrics.width(ch);
return mWidths[unicode];
@ -27,14 +35,22 @@ public:
int width(const QString & text)
{
int result = 0;
QChar temp;
for(const QChar & ch : text)
result += width(ch);
{
if(ch.isLowSurrogate())
temp = ch;
else if(ch.isHighSurrogate())
result += mFontMetrics.width(QString(temp) + ch);
else
result += width(ch);
}
return result;
}
private:
QFontMetrics mFontMetrics;
ushort mWidths[65536];
uchar mWidths[0x10000 - 0xE000 + 0xD800];
};
#endif // CACHEDFONTMETRICS_H

View File

@ -153,7 +153,8 @@ SOURCES += \
Src/Utils/LongLongValidator.cpp \
Src/Utils/MiscUtil.cpp \
Src/Gui/XrefBrowseDialog.cpp \
Src/Gui/CodepageSelectionDialog.cpp
Src/Gui/CodepageSelectionDialog.cpp \
Src/Gui/ColumnReorderDialog.cpp
HEADERS += \
@ -248,7 +249,8 @@ HEADERS += \
Src/Utils/MiscUtil.h \
Src/Gui/XrefBrowseDialog.h \
Src/Gui/CodepageSelectionDialog.h \
Src/Utils/CachedFontMetrics.h
Src/Utils/CachedFontMetrics.h \
Src/Gui/ColumnReorderDialog.h
FORMS += \
Src/Gui/MainWindow.ui \
@ -279,7 +281,8 @@ FORMS += \
Src/Gui/CPUArgumentWidget.ui \
Src/Gui/EditFloatRegister.ui \
Src/Gui/XrefBrowseDialog.ui \
Src/Gui/CodepageSelectionDialog.ui
Src/Gui/CodepageSelectionDialog.ui \
Src/Gui/ColumnReorderDialog.ui
TRANSLATIONS = \
Translations/x64dbg_zh_CN.ts