mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 19:06:10 +00:00
Initial working diff with resizable columns
This commit is contained in:
parent
d974c24daa
commit
0a5a1dfbcf
@ -22,6 +22,11 @@ BinDiff::~BinDiff()
|
||||
rz_analysis_match_result_free(result);
|
||||
}
|
||||
|
||||
bool BinDiff::hasData()
|
||||
{
|
||||
return result != nullptr;
|
||||
}
|
||||
|
||||
void BinDiff::setFile(QString filePath)
|
||||
{
|
||||
mutex.lock();
|
||||
@ -36,6 +41,13 @@ void BinDiff::setAnalysisLevel(int aLevel)
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void BinDiff::setCompareLogic(int cLogic)
|
||||
{
|
||||
mutex.lock();
|
||||
compareLogic = cLogic;
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void BinDiff::run()
|
||||
{
|
||||
qRegisterMetaType<BinDiffStatusDescription>();
|
||||
@ -47,7 +59,7 @@ void BinDiff::run()
|
||||
maxTotal = 1; // maxTotal must be at least 1.
|
||||
mutex.unlock();
|
||||
|
||||
result = Core()->diffNewFile(file, level, threadCallback, this);
|
||||
result = Core()->diffNewFile(file, level, compareLogic, threadCallback, this);
|
||||
|
||||
mutex.lock();
|
||||
bool canComplete = continueRun;
|
||||
|
@ -20,6 +20,8 @@ public:
|
||||
|
||||
void setFile(QString filePth);
|
||||
void setAnalysisLevel(int aLevel);
|
||||
void setCompareLogic(int cLogic);
|
||||
bool hasData();
|
||||
|
||||
QList<BinDiffMatchDescription> matches();
|
||||
QList<FunctionDescription> mismatch(bool originalFile);
|
||||
@ -42,6 +44,7 @@ private:
|
||||
#endif
|
||||
QString file;
|
||||
int level;
|
||||
int compareLogic;
|
||||
|
||||
bool updateProgress(const size_t nLeft, const size_t nMatch);
|
||||
static bool threadCallback(const size_t nLeft, const size_t nMatch, void *user);
|
||||
|
@ -4564,8 +4564,13 @@ bool CutterCore::isWriteModeEnabled()
|
||||
return false;
|
||||
}
|
||||
|
||||
RzList *get_functions(RzAnalysis *analysis)
|
||||
#define IS_IMPORT(name) \
|
||||
(name.startsWith("sym.imp.") || name.startsWith("loc.imp.") || name.startsWith("imp."))
|
||||
#define IS_SYMBOL(name, pfx) (IS_IMPORT(name) || name.startsWith(pfx))
|
||||
|
||||
RzList *get_functions(RzAnalysis *analysis, int compareLogic)
|
||||
{
|
||||
|
||||
RzList *functions = rz_analysis_get_fcns(analysis);
|
||||
if (!functions) {
|
||||
return nullptr;
|
||||
@ -4576,12 +4581,21 @@ RzList *get_functions(RzAnalysis *analysis)
|
||||
return list;
|
||||
}
|
||||
|
||||
QString pfx = Config()->getConfigString("analysis.fcnprefix");
|
||||
if (pfx.isEmpty()) {
|
||||
pfx = "fcn.";
|
||||
} else {
|
||||
pfx += ".";
|
||||
}
|
||||
|
||||
RzAnalysisFunction *func = nullptr;
|
||||
RzListIter *it = nullptr;
|
||||
|
||||
CutterRzListForeach (functions, it, RzAnalysisFunction, func) {
|
||||
QString name = func->name;
|
||||
if (name.startsWith("sym.imp.") || name.startsWith("loc.imp.") || name.startsWith("imp.")) {
|
||||
if (compareLogic == CutterCore::CompareLogicDefault && IS_IMPORT(name)) {
|
||||
continue;
|
||||
} else if (compareLogic == CutterCore::CompareLogicSymbols && IS_SYMBOL(name, pfx)) {
|
||||
continue;
|
||||
}
|
||||
rz_list_add_sorted(list, func, analysis->columnSort);
|
||||
@ -4590,7 +4604,7 @@ RzList *get_functions(RzAnalysis *analysis)
|
||||
return list;
|
||||
}
|
||||
|
||||
RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int level,
|
||||
RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int level, int compareLogic,
|
||||
RzAnalysisMatchThreadInfoCb callback, void *user)
|
||||
{
|
||||
CORE_LOCK();
|
||||
@ -4613,17 +4627,17 @@ RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int leve
|
||||
}
|
||||
|
||||
if (!rz_core_file_open(core_b, filePath.toUtf8().constData(), RZ_PERM_RX, 0)) {
|
||||
qWarning() << "cannot open file " << filePath;
|
||||
qWarning() << tr("cannot open file %1").arg(filePath);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!rz_core_bin_load(core_b, nullptr, UT64_MAX)) {
|
||||
qWarning() << "cannot load bin " << filePath;
|
||||
qWarning() << tr("cannot load bin %1").arg(filePath);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!rz_core_bin_update_arch_bits(core_b)) {
|
||||
qWarning() << "cannot set architecture with bits";
|
||||
qWarning() << tr("cannot set architecture with bits");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -4637,25 +4651,25 @@ RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int leve
|
||||
}
|
||||
|
||||
if (!rz_core_analysis_all(core_b)) {
|
||||
qWarning() << "cannot perform basic analysis of the binary " << filePath;
|
||||
qWarning() << tr("cannot perform basic analysis of the binary %1").arg(filePath);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (level != AnalysisLevelSymbols
|
||||
&& !rz_core_analysis_everything(core_b, level == AnalysisLevelExperimental, nullptr)) {
|
||||
qWarning() << "cannot perform complete analysis of the binary " << filePath;
|
||||
qWarning() << tr("cannot perform complete analysis of the binary %1").arg(filePath);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fcns_a = get_functions(core_a->analysis);
|
||||
fcns_a = get_functions(core_a->analysis, compareLogic);
|
||||
if (rz_list_empty(fcns_a)) {
|
||||
qWarning() << "no functions found in the current opened file";
|
||||
qWarning() << tr("no functions found in the current opened file");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fcns_b = get_functions(core_b->analysis);
|
||||
fcns_b = get_functions(core_b->analysis, compareLogic);
|
||||
if (rz_list_empty(fcns_b)) {
|
||||
qWarning() << "no functions found in " << filePath;
|
||||
qWarning() << tr("no functions found in the just opene file %1").arg(filePath);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -4667,7 +4681,7 @@ RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int leve
|
||||
// calculate all the matches between the functions of the 2 different core files.
|
||||
result = rz_analysis_match_functions(fcns_a, fcns_b, &opts);
|
||||
if (!result) {
|
||||
qWarning() << "failed to perform the function matching operation or job was cancelled.";
|
||||
qWarning() << tr("failed to perform the function matching operation or job was cancelled.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -762,7 +762,13 @@ public:
|
||||
AnalysisLevelExperimental,
|
||||
};
|
||||
|
||||
RzAnalysisMatchResult *diffNewFile(const QString &filePath, int level,
|
||||
enum {
|
||||
CompareLogicDefault = 0, ///< Only symbols and functions (no imports)
|
||||
CompareLogicComplete, ///< All functions (imports included)
|
||||
CompareLogicSymbols, ///< Only symbols
|
||||
};
|
||||
|
||||
RzAnalysisMatchResult *diffNewFile(const QString &filePath, int level, int compareLogic,
|
||||
RzAnalysisMatchThreadInfoCb callback, void *user);
|
||||
|
||||
signals:
|
||||
|
@ -1638,8 +1638,9 @@ void MainWindow::startDiffing()
|
||||
}
|
||||
|
||||
auto level = diffLoadDialog->getLevel();
|
||||
auto compare = diffLoadDialog->getCompare();
|
||||
auto diffWait = new DiffWaitDialog(this);
|
||||
diffWait->show(filename, modified, level);
|
||||
diffWait->show(filename, modified, level, compare);
|
||||
}
|
||||
|
||||
void MainWindow::on_actionForward_triggered()
|
||||
|
@ -10,6 +10,7 @@ BaseFindDialog::BaseFindDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Ba
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
setModal(true);
|
||||
|
||||
// Fill in N-thread Combo
|
||||
size_t n_cores = rz_th_physical_core_number();
|
||||
|
@ -72,6 +72,7 @@ BaseFindResultsDialog::BaseFindResultsDialog(QList<BasefindResultDescription> re
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
setModal(true);
|
||||
|
||||
model = new BaseFindResultsModel(&list, this);
|
||||
ui->tableView->setModel(model);
|
||||
|
@ -14,6 +14,7 @@ BaseFindSearchDialog::BaseFindSearchDialog(QWidget *parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
setModal(true);
|
||||
}
|
||||
|
||||
BaseFindSearchDialog::~BaseFindSearchDialog() {}
|
||||
|
@ -13,6 +13,7 @@ DiffLoadDialog::DiffLoadDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Di
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
setModal(true);
|
||||
|
||||
ui->lineEditFileName->setReadOnly(true);
|
||||
ui->lineEditFileName->setText("");
|
||||
@ -24,6 +25,10 @@ DiffLoadDialog::DiffLoadDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Di
|
||||
ui->comboBoxAnalysis->addItem(tr("Auto"));
|
||||
ui->comboBoxAnalysis->addItem(tr("Experimental"));
|
||||
|
||||
ui->comboBoxCompare->addItem(tr("Default"));
|
||||
ui->comboBoxCompare->addItem(tr("All functions"));
|
||||
ui->comboBoxCompare->addItem(tr("Only Symbols"));
|
||||
|
||||
auto index = ui->comboBoxAnalysis->findData(tr("Auto"), Qt::DisplayRole);
|
||||
ui->comboBoxAnalysis->setCurrentIndex(index);
|
||||
}
|
||||
@ -45,6 +50,11 @@ int DiffLoadDialog::getLevel() const
|
||||
return ui->comboBoxAnalysis->currentIndex();
|
||||
}
|
||||
|
||||
int DiffLoadDialog::getCompare() const
|
||||
{
|
||||
return ui->comboBoxCompare->currentIndex();
|
||||
}
|
||||
|
||||
void DiffLoadDialog::on_buttonDiffOpen_clicked()
|
||||
{
|
||||
QFileDialog dialog(this);
|
||||
|
@ -22,6 +22,7 @@ public:
|
||||
QString getFileToOpen() const;
|
||||
QString getPreviousDiffFile() const;
|
||||
int getLevel() const;
|
||||
int getCompare() const;
|
||||
|
||||
signals:
|
||||
void startDiffing();
|
||||
|
@ -10,7 +10,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>636</width>
|
||||
<height>184</height>
|
||||
<height>226</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -20,7 +20,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="false">Select which file to compare.</string>
|
||||
<string>Select which file to compare.</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
@ -34,22 +34,6 @@
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEditDiffFile"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="fileToCompareLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>File to compare to.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File to compare (required)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="buttonFileOpen">
|
||||
<property name="text">
|
||||
@ -57,6 +41,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="buttonDiffOpen">
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxAnalysis"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditFileName"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="previousDiffLabel">
|
||||
<property name="sizePolicy">
|
||||
@ -73,16 +70,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEditFileName"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="buttonDiffOpen">
|
||||
<property name="text">
|
||||
<string>Select</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelAnalysisLevel">
|
||||
<property name="text">
|
||||
@ -90,8 +77,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboBoxAnalysis"/>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="fileToCompareLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>File to compare to.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File to compare (required)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelCompareLogic">
|
||||
<property name="text">
|
||||
<string>Compare Logic</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="comboBoxCompare"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
@ -13,11 +13,10 @@ DiffWaitDialog::DiffWaitDialog(QWidget *parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
setModal(true);
|
||||
|
||||
ui->lineEditNFuncs->setReadOnly(true);
|
||||
ui->lineEditMatches->setReadOnly(true);
|
||||
ui->lineEditEstimatedTime->setReadOnly(true);
|
||||
ui->lineEditElapsedTime->setReadOnly(true);
|
||||
ui->lineEditOriginal->setReadOnly(true);
|
||||
ui->lineEditModified->setReadOnly(true);
|
||||
ui->progressBar->setValue(0);
|
||||
@ -34,11 +33,11 @@ DiffWaitDialog::~DiffWaitDialog()
|
||||
if (bDiff && bDiff->isRunning()) {
|
||||
bDiff->cancel();
|
||||
bDiff->wait();
|
||||
delete bDiff;
|
||||
}
|
||||
delete bDiff;
|
||||
}
|
||||
|
||||
void DiffWaitDialog::show(QString original, QString modified, int level)
|
||||
void DiffWaitDialog::show(QString original, QString modified, int level, int compare)
|
||||
{
|
||||
connect(this, &DiffWaitDialog::cancelJob, bDiff, &BinDiff::cancel);
|
||||
connect(bDiff, &BinDiff::progress, this, &DiffWaitDialog::onProgress);
|
||||
@ -49,6 +48,7 @@ void DiffWaitDialog::show(QString original, QString modified, int level)
|
||||
ui->lineEditModified->setText(modified);
|
||||
|
||||
bDiff->setAnalysisLevel(level);
|
||||
bDiff->setCompareLogic(compare);
|
||||
bDiff->setFile(modified);
|
||||
eTimer.restart();
|
||||
timer.setSingleShot(false);
|
||||
@ -80,10 +80,12 @@ void DiffWaitDialog::onCompletion()
|
||||
{
|
||||
timer.stop();
|
||||
|
||||
auto results = new DiffWindow(bDiff, parentWidget());
|
||||
bDiff = nullptr;
|
||||
if (bDiff->hasData()) {
|
||||
auto results = new DiffWindow(bDiff, parentWidget());
|
||||
bDiff = nullptr;
|
||||
results->showMaximized();
|
||||
}
|
||||
|
||||
results->showMaximized();
|
||||
close();
|
||||
}
|
||||
|
||||
@ -102,4 +104,5 @@ void DiffWaitDialog::on_buttonBox_rejected()
|
||||
{
|
||||
timer.stop();
|
||||
emit cancelJob();
|
||||
close();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
explicit DiffWaitDialog(QWidget *parent = nullptr);
|
||||
~DiffWaitDialog();
|
||||
|
||||
void show(QString original, QString modified, int level);
|
||||
void show(QString original, QString modified, int level, int compare);
|
||||
|
||||
public slots:
|
||||
void onProgress(BinDiffStatusDescription status);
|
||||
|
@ -41,7 +41,7 @@
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lineEditElapsedTime"/>
|
||||
<widget class="QLabel" name="lineEditElapsedTime"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="lineEditModified"/>
|
||||
@ -98,7 +98,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEditEstimatedTime"/>
|
||||
<widget class="QLabel" name="lineEditEstimatedTime"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
@ -56,7 +56,26 @@ QVariant DiffMatchModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
|
||||
case Qt::ToolTipRole: {
|
||||
return entry.simtype;
|
||||
switch (index.column()) {
|
||||
case NameOrig:
|
||||
return entry.original.name;
|
||||
case SizeOrig:
|
||||
return QString::asprintf("%llu (%#llx)", entry.original.linearSize,
|
||||
entry.original.linearSize);
|
||||
case AddressOrig:
|
||||
return RzAddressString(entry.original.offset);
|
||||
case Similarity:
|
||||
return entry.simtype;
|
||||
case AddressMod:
|
||||
return RzAddressString(entry.modified.offset);
|
||||
case SizeMod:
|
||||
return QString::asprintf("%llu (%#llx)", entry.modified.linearSize,
|
||||
entry.modified.linearSize);
|
||||
case NameMod:
|
||||
return entry.modified.name;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
case Qt::BackgroundRole: {
|
||||
@ -126,6 +145,8 @@ QVariant DiffMismatchModel::data(const QModelIndex &index, int role) const
|
||||
const FunctionDescription &entry = list->at(index.row());
|
||||
|
||||
switch (role) {
|
||||
case Qt::ToolTipRole:
|
||||
/* fall-thru */
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column()) {
|
||||
case FuncName:
|
||||
@ -150,10 +171,6 @@ QVariant DiffMismatchModel::data(const QModelIndex &index, int role) const
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
case Qt::ToolTipRole: {
|
||||
return entry.name;
|
||||
}
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@ -194,6 +211,7 @@ DiffWindow::DiffWindow(BinDiff *bd, QWidget *parent)
|
||||
: QDialog(parent), ui(new Ui::DiffWindow), bDiff(bd)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setModal(true);
|
||||
|
||||
ui->comboBoxShowInfo->addItem(tr("Summary"));
|
||||
ui->comboBoxShowInfo->addItem(tr("AAAA"));
|
||||
@ -213,22 +231,16 @@ DiffWindow::DiffWindow(BinDiff *bd, QWidget *parent)
|
||||
// Matches Table
|
||||
ui->tableViewMatch->setModel(modelMatch);
|
||||
ui->tableViewMatch->sortByColumn(DiffMatchModel::Similarity, Qt::AscendingOrder);
|
||||
ui->tableViewMatch->verticalHeader()->hide();
|
||||
ui->tableViewMatch->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
ui->tableViewMatch->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
// Deletion Table
|
||||
ui->tableViewRem->setModel(modelDel);
|
||||
ui->tableViewRem->sortByColumn(DiffMismatchModel::FuncName, Qt::AscendingOrder);
|
||||
ui->tableViewRem->verticalHeader()->hide();
|
||||
ui->tableViewRem->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
ui->tableViewRem->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
// Addition Table
|
||||
ui->tableViewAdd->setModel(modelAdd);
|
||||
ui->tableViewAdd->sortByColumn(DiffMismatchModel::FuncName, Qt::AscendingOrder);
|
||||
ui->tableViewAdd->verticalHeader()->hide();
|
||||
ui->tableViewAdd->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
ui->tableViewAdd->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,42 @@
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QTableView" name="tableViewMatch"/>
|
||||
<widget class="CutterTreeView" name="tableViewMatch">
|
||||
<attribute name="title">
|
||||
<string>Matches</string>
|
||||
</attribute>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">CutterTreeView::item
|
||||
{
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="autoScroll">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -74,7 +109,42 @@
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutMismatchRem">
|
||||
<item>
|
||||
<widget class="QTableView" name="tableViewRem"/>
|
||||
<widget class="CutterTreeView" name="tableViewRem">
|
||||
<attribute name="title">
|
||||
<string>Matches</string>
|
||||
</attribute>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">CutterTreeView::item
|
||||
{
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="autoScroll">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -84,7 +154,42 @@
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutMismatchAdd">
|
||||
<item>
|
||||
<widget class="QTableView" name="tableViewAdd"/>
|
||||
<widget class="CutterTreeView" name="tableViewAdd">
|
||||
<attribute name="title">
|
||||
<string>Matches</string>
|
||||
</attribute>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">CutterTreeView::item
|
||||
{
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="autoScroll">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@ -151,6 +256,14 @@
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CutterTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>widgets/CutterTreeView.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
Loading…
Reference in New Issue
Block a user