QHexView icon indicating copy to clipboard operation
QHexView copied to clipboard

hexview->setForeground(0, data.size(), QColor(0x00, 0x80, 0xFF)) dose not work

Open jhembed opened this issue 7 months ago • 18 comments

Hello author, when I set the foreground color, this line of code does not work because of the large data.

//  data.size() = 256MB
hexview->setForeground(0, data.size(), QColor(0x00, 0x80, 0xFF));

jhembed avatar May 06 '25 13:05 jhembed

Can you test if it works by using this branch? https://github.com/Dax89/QHexView/tree/direct_renderer

Dax89 avatar May 07 '25 08:05 Dax89

Ok I try

jhembed avatar May 07 '25 12:05 jhembed

Qt 5.14.2,Compile error

Image

jhembed avatar May 07 '25 12:05 jhembed

https://github.com/Dax89/QHexView/tree/direct_renderer,This branch also does not work, it is also unresponsive and crashes.

Image

jhembed avatar May 07 '25 13:05 jhembed

Qt 5.14.2,Compile error

Image

Fixed.

https://github.com/Dax89/QHexView/tree/direct_renderer,This branch also does not work, it is also unresponsive and crashes.

I have checked the code and 256MB is a bit big to handle (currently colors' metadata is stored in a map), maybe QHexDelegate might be more useful for these edge cases.

But I need more details about what do you want to achieve in order to give more helpful replies!

Dax89 avatar May 07 '25 13:05 Dax89

I used two sets of themes, one black theme and one white theme. I want to reset the foreground color after switching themes.

jhembed avatar May 07 '25 13:05 jhembed

Ah ok, setForeground() (along with its related metadata functions) is used to highlight parts of the loaded buffer. In this case you need to use the classic Qt's palette() method provided by Qt in order to change QHexView's colors.

QPalette p = hexview.palette();
p.setColor(QPalette::Base, Qt::black);       // Widget's Background
p.setColor(QPalette::WindowText, Qt::white); // Widget's Foreground
hexview.setPalette(p);

It's supported in direct_renderer branch.

Dax89 avatar May 07 '25 13:05 Dax89

I now need to implement the changed content to turn red, but this does not work properly, and there is no problem in version 5.0.

Image

jhembed avatar May 08 '25 03:05 jhembed

Fixed, thanks for reporting it!

If you can, use direct_renderer branch fow now, because it will get merged in the mainline branch (5.0) soon

Dax89 avatar May 08 '25 08:05 Dax89

I used a global stylesheet, and when I switched themes, the underscore was always white, and there was no problem in version 5.0.

Image

Image

jhembed avatar May 08 '25 10:05 jhembed

The last commit fix this issue in a Qt6 environment, I can't test it in a Qt5 one, let me know if it's ok on your side too

Dax89 avatar May 08 '25 17:05 Dax89

Qt5 is ok.

new problem, I want to make the font red after the content changes. If the font that has been changed is set to red, using QPalette will not change the red to the original color.

Image

jhembed avatar May 13 '25 04:05 jhembed

So if I have understood correctly you want to highlight changes, those APIs are not meant to do that.

In the last few commits have implemented changes tracking builtin in widget, all you need to do is:

QHexDocument* doc = ... // Load your data
doc->setTrackChanges(true); // Enable tracking

QHexView* hexview = ... // Create an hexview
QHexOptions opts = hexview->options(); // Get a copy of the current options

// Set a tracking color pattern
opts.trackchange_format.background = Qt::red;
opts.trackchange_format.foreground = Qt::white;

// Attach document and options (order doesn't really matter here)
hexview->setOptions(opts);
hexview->setDocument(doc);

If you want to reset changes (eg. during a save) both QHexDocument and QHexView provides the slot clearChanges(). Let me know if this implementation suits you needs!

Dax89 avatar May 16 '25 10:05 Dax89

I'd say the trackchange_format could be split into trackchange_format_overwrite and trackchange_format_insert respectively to further differentiate the type of changes being made.

T-640 avatar May 20 '25 11:05 T-640

not update .pri

Image

jhembed avatar May 21 '25 05:05 jhembed

Can we change the byte order display mode? Just like this.

Image

jhembed avatar May 21 '25 08:05 jhembed

not update .pri

Fixed, I've missed that file.

I'd say the trackchange_format could be split into trackchange_format_overwrite and trackchange_format_insert respectively to further differentiate the type of changes being made.

Yes, it makes more sense!

Can we change the byte order display mode? Just like this.

The bytes' endianness? Maybe, I need to check that

Dax89 avatar May 21 '25 16:05 Dax89

I'd say the trackchange_format could be split into trackchange_format_overwrite and trackchange_format_insert respectively to further differentiate the type of changes being made.

They are now implemented as trackchange_format_ins and trackchange_format_ovr

Dax89 avatar May 23 '25 15:05 Dax89

How to change the display order of the byte order? I want it to display as 20000408.

Image

jhembed avatar Jul 15 '25 06:07 jhembed

Can we change the byte order display mode? Just like this.

Image

Already asked here. It can be implemented but it's doesn't look trivial: I need to handle correctly the input according to the group size.

Dax89 avatar Jul 15 '25 14:07 Dax89

Can we change the byte order display mode? Just like this. Image

Already asked here. It can be implemented but it's doesn't look trivial: I need to handle correctly the input according to the group size.

This was normal in previous versions, and I want to know what has changed in version 5.0.

jhembed avatar Jul 16 '25 01:07 jhembed

Can we change the byte order display mode? Just like this. Image

Already asked here. It can be implemented but it's doesn't look trivial: I need to handle correctly the input according to the group size.

This was normal in previous versions, and I want to know what has changed in version 5.0.

Sorry, I was mistaken.

Can the byte order display be made to switch manually? I really need this function. Thank you very much.

jhembed avatar Jul 16 '25 02:07 jhembed

AFAIK no, because the widget reads data byte-by-byte and it doesn't have any integer-width/endianness knowledge. What are you seeing in your screenshot is just byte-fed data, what the "grouping" does is simply to render data with a different spacing, which is ok.

Normally data is rendered as:

address idx1 idx2 idx3 idx4 ...

With "swapped rendering" is becomes:

address idx4 idx3 idx2 idx1 ...

The rendering part can be done easily. Probably I need to reverse the grouping-loop, so instead of doing:

0...group_size, padding

it does:

group_size...0, padding

But there is also input handling that needs to be fixed because it's not anymore a simple division to translate x,y coordinates to the selected index: if the widget is in "swapped state" the group's size needs to be taken in account too.

I see what can I do in the next days.

In short: Yes it can be implemented, it requires some focusing because the input part is tricky

Dax89 avatar Jul 17 '25 16:07 Dax89

This may sound silly lacking the context behind the task at hand, but wouldn't it be easier to just flip the bytes on the data before it arrives in QHexView?

T-640 avatar Jul 18 '25 10:07 T-640

@T-640 QHexView's data model is byte based too, so reading an integer's and change the byte order is not very pratical, also it gets worse when you need to write back changes.

The general idea is to change the byte order visually. I have done some research: 010 Editor implements this feature, so it's nice to have it built-in (another QHexFlag in QHexOptions).

@jhembed I will implement this feature in the next days, be aware that the ASCII part will be also flipped in order to keep both views in sync.

Dax89 avatar Jul 22 '25 17:07 Dax89

@T-640 QHexView's data model is byte based too, so reading an integer's and change the byte order is not very pratical, also it gets worse when you need to write back changes.

The general idea is to change the byte order visually. I have done some research: 010 Editor implements this feature, so it's nice to have it built-in (another QHexFlag in QHexOptions).

@jhembed I will implement this feature in the next days, be aware that the ASCII part will be also flipped in order to keep both views in sync.

This is great!

jhembed avatar Jul 23 '25 02:07 jhembed

What is the practical application of this feature? I am struggling to understand it. Working with network packets I deal with the byte order all the time, but trying to apply this logic there, I would have to completely dismiss the structure of an IPv4 packet, interpreting it as an array of dwords instead, and if the poor thing hasn't suffered enough put a final nail in the coffin by editing some of these flipped bytes, which sounds insane. I guess the application of it is in other domains, like reverse engineering? Since that other tool you mentioned seemingly puts an emphasis on it. I am genuinely curious, just having a hard time wrapping my head around the concept.

T-640 avatar Jul 23 '25 20:07 T-640

I guess the application of it is in other domains, like reverse engineering?

In my case yes, it's pretty useful to display a dump in my disassembler with the correct byte order without doing pre/post processings, it's just a visual change. Also in my disassembler doing pre processing to create a temporary buffer with "swapped integers" may be very expensive, also I need to do post processing to write back changes and swapping those integers again, if I don't do this the executable gets corrupted.

In general, the feature's use-case is pretty simple: let's suppose you have a random blob of bytes that in reality is an array of 16 bit integers (or 32, 64). Using QHexView to display this random blob with 2 bytes grouping set, it may renderer these integers with the wrong byte order (eg. 0xAABB in reality is 0xBBAA, a completely different number), it depends on which platform are written (big/little endian) and the writing algorithm, we cannot control these.

Desktop PCs generally are little endian platforms and if you want to read big endian integers you need to read and swap them.

BUT, if QHexView knows that a blob of bytes needs to be swapped you can:

  • See the correct integers.
  • Editing is fine, data doesn't get corrupted because widget takes care of the correct index to write back.
  • No useless pre/post processing costs.

It's not an automatic thing: user must already know the integers' width and if they are written with a different byte order.

Obviously if you use 1 byte grouping (classic hex dump) this feature doesn't do anything.

Dax89 avatar Jul 25 '25 08:07 Dax89

@jhembed, the last few commits implements the requested feature, is still WIP and there may be some bugs, I will check better tomorrow.

However QHexFlags::InvertedByteOrder is the required flag to put in QHexOptions::flags, or you can simply swap on the fly by calling QHexView::invertByteOrder() slot which toggles the flag for you.

NOTE: it does have effect only on input and how bytes are rendered. Also, it's only in QHexView and partially in QHexCursor level, QHexDocument is not aware of this (in this case it shares the same behavior of 010 editor). This means that it doesn't matter if you have (or don't have) the widget swapped, you always get the non-swapped data back.

Dax89 avatar Sep 05 '25 17:09 Dax89

@jhembed, the last few commits implements the requested feature, is still WIP and there may be some bugs, I will check better tomorrow.

However QHexFlags::InvertedByteOrder is the required flag to put in QHexOptions::flags, or you can simply swap on the fly by calling QHexView::invertByteOrder() slot which toggles the flag for you.

NOTE: it does have effect only on input and how bytes are rendered. Also, it's only in QHexView and partially in QHexCursor level, QHexDocument is not aware of this (in this case it shares the same behavior of 010 editor). This means that it doesn't matter if you have (or don't have) the widget swapped, you always get the non-swapped data back.

This is really wonderful!

jhembed avatar Sep 17 '25 05:09 jhembed