summaryrefslogtreecommitdiffstats
path: root/ui/qt/widgets/byte_view_text.h
blob: b6a6cce8bafa4799af6beedd1dab1b05ab8f945a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/** @file
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#ifndef BYTE_VIEW_TEXT_H
#define BYTE_VIEW_TEXT_H

#include <config.h>

#include "ui/recent.h"

#include <QAbstractScrollArea>
#include <QFont>
#include <QVector>
#include <QMenu>
#include <QSize>
#include <QString>
#include <QTextLayout>
#include <QVector>

#include <ui/qt/utils/data_printer.h>
#include <ui/qt/utils/idata_printable.h>

// XXX - Is there any reason we shouldn't add ByteViewImage, etc?

class ByteViewText : public QAbstractScrollArea, public IDataPrintable
{
    Q_OBJECT
    Q_INTERFACES(IDataPrintable)

public:
    explicit ByteViewText(const QByteArray &data, packet_char_enc encoding = PACKET_CHAR_ENC_CHAR_ASCII, QWidget *parent = 0);
    ~ByteViewText();

    virtual QSize minimumSizeHint() const;

    void setFormat(bytes_view_type format);
    bool isEmpty() const;

signals:
    void byteHovered(int pos);
    void byteSelected(int pos);
    void byteViewSettingsChanged();

public slots:
    void setMonospaceFont(const QFont &mono_font);
    void updateByteViewSettings();
    void detachData();

    void markProtocol(int start, int length);
    void markField(int start, int length, bool scroll_to = true);
    void markAppendix(int start, int length);
    void unmarkField();

protected:
    virtual void paintEvent(QPaintEvent *);
    virtual void resizeEvent(QResizeEvent *);
    virtual void mousePressEvent (QMouseEvent * event);
    virtual void mouseMoveEvent (QMouseEvent * event);
    virtual void leaveEvent(QEvent *event);
    virtual void contextMenuEvent(QContextMenuEvent *event);

private:
    // Text highlight modes.
    typedef enum {
        ModeNormal,
        ModeField,
        ModeProtocol,
        ModeOffsetNormal,
        ModeOffsetField,
        ModeNonPrintable
    } HighlightMode;

    QTextLayout *layout_;
    QByteArray data_;

    void updateLayoutMetrics();
    int stringWidth(const QString &line);
    void drawLine(QPainter *painter, const int offset, const int row_y);
    bool addFormatRange(QList<QTextLayout::FormatRange> &fmt_list, int start, int length, HighlightMode mode);
    bool addHexFormatRange(QList<QTextLayout::FormatRange> &fmt_list, int mark_start, int mark_length, int tvb_offset, int max_tvb_pos, HighlightMode mode);
    bool addAsciiFormatRange(QList<QTextLayout::FormatRange> &fmt_list, int mark_start, int mark_length, int tvb_offset, int max_tvb_pos, HighlightMode mode);
    void scrollToByte(int byte);
    void updateScrollbars();
    int byteOffsetAtPixel(QPoint pos);

    void createContextMenu();
    void updateContextMenu();

    int offsetChars(bool include_pad = true);
    int offsetPixels();
    int hexPixels();
    int asciiPixels();
    int totalPixels();
    const QByteArray printableData() { return data_; }

    static const int separator_interval_;

    // Colors
    QColor offset_normal_fg_;
    QColor offset_field_fg_;

    // Data
    packet_char_enc encoding_;  // ASCII or EBCDIC
    QMenu ctx_menu_;

    // Data highlight
    int hovered_byte_offset_;
    int marked_byte_offset_;
    int proto_start_;
    int proto_len_;
    int field_start_;
    int field_len_;
    int field_a_start_;
    int field_a_len_;

    bool show_offset_;          // Should we show the byte offset?
    bool show_hex_;             // Should we show the hex display?
    bool show_ascii_;           // Should we show the ASCII display?
    int row_width_;             // Number of bytes per line
    int em_width_;              // Single character width and text margin. NOTE: Use fontMetrics::width for multiple characters.
    int line_height_;           // Font line spacing
    QList<QRect> hover_outlines_; // Hovered byte outlines.

    bool allow_hover_selection_;

    // Data selection
    QVector<int> x_pos_to_column_;

    // Context menu actions
    QAction *action_allow_hover_selection_;
    QAction *action_bytes_hex_;
    QAction *action_bytes_dec_;
    QAction *action_bytes_oct_;
    QAction *action_bytes_bits_;
    QAction *action_bytes_enc_from_packet_;
    QAction *action_bytes_enc_ascii_;
    QAction *action_bytes_enc_ebcdic_;

private slots:
    void copyBytes(bool);
    void setHexDisplayFormat(QAction *action);
    void setCharacterEncoding(QAction *action);
    void toggleHoverAllowed(bool);

};

#endif // BYTE_VIEW_TEXT_H