diff options
Diffstat (limited to 'khexedit/lib/khexedit.h')
-rw-r--r-- | khexedit/lib/khexedit.h | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/khexedit/lib/khexedit.h b/khexedit/lib/khexedit.h new file mode 100644 index 0000000..66059c8 --- /dev/null +++ b/khexedit/lib/khexedit.h @@ -0,0 +1,562 @@ +/*************************************************************************** + khexedit.h - description + ------------------- + begin : Die Mai 13 2003 + copyright : (C) 2003 by Friedrich W. H. Kossebau + email : Friedrich.W.H@Kossebau.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License version 2 as published by the Free Software Foundation. * + * * + ***************************************************************************/ + + +#ifndef KHE_KHEXEDIT_H +#define KHE_KHEXEDIT_H + +// qt specific +#include <qclipboard.h> +// lib specific +// #include "khe.h" +#include "khexedit_export.h" +#include "kcolumnsview.h" + +class QTimer; + +namespace KHE +{ + +class KCoordRange; + +class KDataBuffer; + +class KCharColumn; +class KValueColumn; +class KBufferColumn; +class KOffsetColumn; +class KBorderColumn; + +class KBufferCursor; +class KBufferLayout; +class KBufferRanges; + +class KController; +class KTabController; +class KNavigator; +class KValueEditor; +class KCharEditor; + +class KBufferDrag; + +class KCursor; +class KCharCodec; + +class KHexEditPrivate; + + +/** the main widget + * + * The functions split up in helper functions and those that are complete. + * + * Complete functions can be called from the outside and leave the widget in + * a consistent state. They care for exceptions so one can safely call them in all + * situations (like empty buffer, cursor behind end etc.) + * + * Helper functions do only partial tasks and need to be completed. They often do not + * check for exceptions so one has to care for this. + * + *@author Friedrich W. H. Kossebau + */ + +class KHEXEDIT_EXPORT KHexEdit : public KColumnsView +{ + friend class KTabController; + friend class KNavigator; + friend class KEditor; + friend class KValueEditor; + friend class KCharEditor; + + Q_OBJECT + Q_ENUMS( KResizeStyle KCoding ) + Q_PROPERTY( bool OverwriteMode READ isOverwriteMode WRITE setOverwriteMode ) + Q_PROPERTY( bool OverwriteOnly READ isOverwriteOnly WRITE setOverwriteOnly ) + Q_PROPERTY( bool Modified READ isModified WRITE setModified DESIGNABLE false ) + Q_PROPERTY( bool ReadOnly READ isReadOnly WRITE setReadOnly ) + + Q_PROPERTY( int NoOfBytesPerLine READ noOfBytesPerLine WRITE setNoOfBytesPerLine ) + Q_PROPERTY( bool TabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus ) + + //Q_PROPERTY( bool hasSelectedData READ hasSelectedData ) + //Q_PROPERTY( QByteArray SelectedData READ selectedData ) + Q_PROPERTY( KResizeStyle ResizeStyle READ resizeStyle WRITE setResizeStyle ) + Q_PROPERTY( int StartOffset READ startOffset WRITE setStartOffset ) + Q_PROPERTY( int FirstLineOffset READ firstLineOffset WRITE setFirstLineOffset ) + //_PROPERTY( int undoDepth READ undoDepth WRITE setUndoDepth ) + //_PROPERTY( bool undoRedoEnabled READ isUndoRedoEnabled WRITE setUndoRedoEnabled ) + // value column + Q_PROPERTY( KCoding Coding READ coding WRITE setCoding ) + Q_PROPERTY( int ByteSpacingWidth READ byteSpacingWidth WRITE setByteSpacingWidth ) + Q_PROPERTY( int NoOfGroupedBytes READ noOfGroupedBytes WRITE setNoOfGroupedBytes ) + Q_PROPERTY( int GroupSpacingWidth READ groupSpacingWidth WRITE setGroupSpacingWidth ) + Q_PROPERTY( int BinaryGapWidth READ binaryGapWidth WRITE setBinaryGapWidth ) + // char column + Q_PROPERTY( bool ShowUnprintable READ showUnprintable WRITE setShowUnprintable ) + Q_PROPERTY( QChar SubstituteChar READ substituteChar WRITE setSubstituteChar ) + + public: + enum KResizeStyle { NoResize=0, LockGrouping=1, FullSizeUsage=2, MaxResizeStyleId=0xFF }; + enum KCoding { HexadecimalCoding=0, DecimalCoding=1, OctalCoding=2, BinaryCoding=3, MaxCodingId=0xFFFF }; + enum KEncoding { LocalEncoding=0, ISO8859_1Encoding=1, EBCDIC1047Encoding=2, + StartOfOwnEncoding=0x8000, MaxEncodingId=0xFFFF }; + + enum KBufferColumnId { ValueColumnId=1, CharColumnId=2 }; + + + public: + KHexEdit( KDataBuffer *Buffer = 0, QWidget *Parent = 0, const char *Name = 0, WFlags F = 0 ); + virtual ~KHexEdit(); + + + public: // KColumnsView API + virtual void drawContents( QPainter *p, int cx, int cy, int cw, int ch ); + + public: // QWidget API +// void focusInEvent( QFocusEvent *FocusEvent ); // TODO: why don't these work? +// void focusOutEvent( QFocusEvent *FocusEvent ); + virtual bool eventFilter( QObject *O, QEvent *E ); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + + public: // value access + /** returns the index of the cursor position */ + int cursorPosition() const; + /***/ + bool isCursorBehind() const; + KBufferColumnId cursorColumn() const; + + bool isOverwriteMode() const; + bool isOverwriteOnly() const; + bool isReadOnly() const; + bool isModified() const; + + bool tabChangesFocus() const; + + KResizeStyle resizeStyle() const; + int noOfBytesPerLine() const; + int startOffset() const; + int firstLineOffset() const; + + bool offsetColumnVisible() const; + int visibleBufferColumns() const; + + // value column + KCoding coding() const; + int/*KPixelX*/ byteSpacingWidth() const; + int noOfGroupedBytes() const; + int/*KPixelX*/ groupSpacingWidth() const; + int/*KPixelX*/ binaryGapWidth() const; + + // char column + /** reports if "unprintable" chars (value<32) are displayed in the char column + * with their original character. Default is false + * @return @c true if original chars are displayed, otherwise @c false + */ + bool showUnprintable() const; + /** gives the used substitute character for "unprintable" chars, default is '.' + * @return substitute character + */ + QChar substituteChar() const; + /** returns the actually used undefined character for "undefined" chars, default is '?' */ + QChar undefinedChar() const; + /** + * @return encoding used in the char column + */ + KEncoding encoding() const; + /** + * @return name of the encoding used in the char column + */ + const QString &encodingName() const; + + public: // logic value service + /** calculates the number of bytes per line that fit into a widget with the given size + * tests whether a vertical scroll bar is needed at all or not due to the given width + * takes the frame width into account + * @param TestSize Size the widget might have + * @return number of bytes per line that fit into a widget with the given size + */ + int fittingBytesPerLine( const QSize &TestSize ) const; + /** detects the index of the byte at the given point + * @param Point in viewport coordinate system + * @return index of the byte that covers the point + */ + int indexByPoint(const QPoint &Point ) const; + + public: + /** returns true if there is a selected range in the array */ + bool hasSelectedData() const; + /** + * @return deep copy of the selected data + */ + QByteArray selectedData() const; + KSection selection() const; + + public: // modification access + /** puts the cursor to the position of index, handles all drawing + * @param Index + */ + void setCursorPosition( int Index, bool Behind=false ); + /** puts the cursor in the column at the pos of Point (in absolute coord), does not handle the drawing */ + void placeCursor( const QPoint &Point ); + /***/ + void setCursorColumn( KBufferColumnId ); +// void repaintByte( int row, int column, bool Erase = true ); +// void updateByte( int row, int column ); +// void ensureByteVisible( int row, int column ); + + public slots: + /** */ + void setDataBuffer( KDataBuffer *B ); + + /** switches the Offset column on/off */ + void toggleOffsetColumn( bool Visible ); + /** */ + void showBufferColumns( int Columns ); + /** scrolls the view as much as needed to have the cursor fully visible */ + void ensureCursorVisible(); + + // setting parameters + /** sets the resizestyle for the value column. Default is KHE::FullSizeUsage */ + void setResizeStyle( KResizeStyle Style ); + /** sets whether the widget is readonly or not, Default is true. + * If the databuffer which is worked on can't be written the widget stays readonly + */ + virtual void setReadOnly( bool b ); + /** sets whether the widget is overwriteonly or not. Default is false. */ + virtual void setOverwriteOnly( bool b ); + /** sets whether the widget is in overwrite mode or not. Default is true. */ + virtual void setOverwriteMode( bool b ); + /** sets whether the data should be treated modified or not */ + virtual void setModified( bool b ); + /** sets whether on a tab key there should be switched from the char column back to the value column + * or be switched to the next focusable widget. Default is false + */ + virtual void setTabChangesFocus( bool b = true ); + // + /** sets the number of bytes per line, switching the resize style to KHE::NoResize */ + virtual void setNoOfBytesPerLine( int NoCpL ); + /** sets absolut offset of the data */ + void setStartOffset( int SO ); + /** sets offset of the char in the upper left corner */ + void setFirstLineOffset( int FLO ); + // value column parameters + /** sets the spacing between the bytes in the value column + * @param BSW spacing between the bytes in pixels + * default is 3 + */ + void setByteSpacingWidth( int/*KPixelX*/ BSW ) ; + /** sets the number of grouped bytes in the value column + * @param NoGB numbers of grouped bytes, 0 means no grouping + * default is 4 + */ + void setNoOfGroupedBytes( int NoGB ); + /** sets the spacing between the groups of bytes in the value column + * @param GSW spacing between the groups in pixels + * default is 9 + */ + void setGroupSpacingWidth( int/*KPixelX*/ GSW ); + /** sets the spacing in the middle of a binary byte in the value column + * @param BinaryGapW spacing in the middle of a binary in pixels + * returns true if there was a change + */ + void setBinaryGapWidth( int BGW ); + /** sets the spacing in the value column + * @param ByteSpacingWidth spacing between the bytes in pixels + * @param NoOfGroupedBytes numbers of grouped bytes, 0 means no grouping + * @param GroupSpacingWidth spacing between the groups in pixels + * Default is 4 for NoOfGroupedBytes + */ + void setBufferSpacing( KPixelX ByteSpacingWidth, int NoOfGroupedBytes = 0, KPixelX GroupSpacingWidth = 0 ); + /** sets the format of the value column. Default is KHE::HexadecimalCoding */ + void setCoding( KCoding C ); + // char column parameters + /** sets whether "unprintable" chars (>32) should be displayed in the char column + * with their corresponding character. + * @param SU + * returns true if there was a change + */ + void setShowUnprintable( bool SU = true ); + /** sets the substitute character for "unprintable" chars + * returns true if there was a change + */ + void setSubstituteChar( QChar SC ); + /** sets the undefined character for "undefined" chars + * returns true if there was a change + */ + void setUndefinedChar( QChar UC ); + /** sets the encoding of the char column. Default is KHE::LocalEncoding. + * If the encoding is not available the format will not be changed. */ + void setEncoding( KEncoding C ); + /** sets the encoding of the char column. Default is KHE::LocalEncoding. + * If the encoding is not available the format will not be changed. + * @param Encoding name of the encoding + */ + void setEncoding( const QString& Encoding ); + + // interaction + /** de-/selects all data */ + void selectAll( bool select ); + /** de-/selects all data */ + void select( KSection S ); + /** selects word at index, returns true if there is one */ + bool selectWord( /*unsigned*/ int Index /*, Chartype*/ ); + /** removes the selected data, takes care of the cursor */ + virtual void removeSelectedData(); + /** inserts */ + virtual void insert( const QByteArray &D ); + + // clipboard interaction + virtual void copy(); + virtual void cut(); + virtual void paste(); + + // zooming + virtual void zoomIn( int PointInc ); + virtual void zoomIn(); + virtual void zoomOut( int PointInc ); + virtual void zoomOut(); + virtual void zoomTo( int PointSize ); + virtual void unZoom(); + + // cursor control + /** we have focus again, start the timer */ + virtual void startCursor(); + /** we lost focus, stop the timer */ + virtual void stopCursor(); + /** simply pauses any blinking, i.e. ignores any calls to blinkCursor */ + virtual void pauseCursor( bool LeaveEdit = false ); + /** undoes pauseCursor */ + virtual void unpauseCursor(); + + + signals: + /** Index of the byte that was clicked */ + void clicked( int Index ); + /** Index of the byte that was double clicked */ + void doubleClicked( int Index ); + + void cursorPositionChanged( int Index ); + /** selection has changed */ + void selectionChanged( int StartIndex, int EndIndex ); + /** there is a cut available or not */ + void cutAvailable( bool Really ); + /** there is a copy available or not */ + void copyAvailable( bool Really ); + /** there has been a change to the buffer */ + void bufferChanged( int StartIndex, int EndIndex ); + + + protected: // QWidget API + virtual void keyPressEvent( QKeyEvent *KeyEvent ); + virtual void resizeEvent( QResizeEvent *ResizeEvent ); + virtual void showEvent( QShowEvent *e ); + + protected: // QScrollView API + virtual void contentsMousePressEvent( QMouseEvent *e ); + virtual void contentsMouseReleaseEvent( QMouseEvent * e ); + virtual void contentsMouseMoveEvent( QMouseEvent *e ); + virtual void contentsMouseDoubleClickEvent( QMouseEvent * e ); + virtual void contentsDragEnterEvent( QDragEnterEvent *e ); + virtual void contentsDragMoveEvent( QDragMoveEvent *e ); + virtual void contentsDragLeaveEvent( QDragLeaveEvent * ); + virtual void contentsDropEvent( QDropEvent *e ); + virtual void contentsWheelEvent( QWheelEvent *e ); +// virtual void contentsContextMenuEvent( QContextMenuEvent *e ); + + protected: // KColumnsView API + virtual void setNoOfLines( int NewNoOfLines ); + + + protected: // element accessor functions + KValueColumn& valueColumn(); + KCharColumn& charColumn(); + KBufferColumn& activeColumn(); + KBufferColumn& inactiveColumn(); + const KValueColumn& valueColumn() const; + const KCharColumn& charColumn() const; + const KBufferColumn& activeColumn() const; + const KBufferColumn& inactiveColumn() const; + + protected: // atomic ui operations + /** handles screen update in case of a change to any of the width sizes + */ + void updateViewByWidth(); + /** repaints all the parts that are signed as changed */ + void repaintChanged(); + + protected: // drawing related operations + /** recreates the cursor pixmaps and paints active and inactive cursors if doable */ + void updateCursor(); + void createCursorPixmaps(); + void pointPainterToCursor( QPainter &Painter, const KBufferColumn &Column ) const; + /** draws the blinking cursor or removes it */ + void paintActiveCursor( bool CursorOn ); + void paintInactiveCursor( bool CursorOn ); + void paintLine( KBufferColumn *C, int Line, KSection Positions ); + + protected: // partial operations + void handleMouseMove( const QPoint& Point ); + KBufferDrag *dragObject( QWidget *Parent = 0 ) const; + void pasteFromSource( QMimeSource *Source ); + /** removes the section from the databuffer and updates all affected values */ + KSection removeData( KSection Indizes ); + /** sets ChangedRange to the range of VisibleRange that is actually changed + * @return true if there was a change within the visible range + */ + bool hasChanged( const KCoordRange &VisibleRange, KCoordRange *ChangedRange ) const; + void handleInternalDrag( QDropEvent *e ); + + protected: + /** recalcs all dependant values with the actual NoOfBytesPerLine */ + void adjustToLayoutNoOfBytesPerLine(); + /** recalcs a layout due to the resize style that fits into the view size + * and updates the dependant values + */ + void adjustLayoutToSize(); + /** */ + void updateLength(); + /** calls updateContent for the Column */ + void updateColumn( KColumn &Column ); + + protected slots: + /** gets called by the cursor blink timer */ + void blinkCursor(); + /** gets called by the scroll timer (for mouse selection) */ + void autoScrollTimerDone(); + /** */ + void clipboardChanged(); + /** */ + void startDrag(); + + protected slots: // QWidget API + virtual void fontChange( const QFont &OldFont ); + + + protected: + /** Buffer with the data */ + KDataBuffer *DataBuffer; + + /** holds the logical layout */ + KBufferLayout *BufferLayout; + /** */ + KBufferCursor *BufferCursor; + /** */ + KBufferRanges *BufferRanges; + + + protected: + KOffsetColumn *OffsetColumn; + KBorderColumn *FirstBorderColumn; + KValueColumn *ValueColumn; + KBorderColumn *SecondBorderColumn; + KCharColumn *CharColumn; + + /** points to the column with keyboard focus */ + KBufferColumn *ActiveColumn; + /** points to the column without keyboard focus (if there is) */ + KBufferColumn *InactiveColumn; + + /** the actual input controller */ + KController *Controller; + /** */ + KTabController *TabController; + /** */ + KNavigator *Navigator; + /** */ + KValueEditor *ValueEditor; + /** */ + KCharEditor *CharEditor; + + protected: + /** Timer that controls the blinking of the cursor */ + QTimer *CursorBlinkTimer; + /** Timer that triggers ensureCursorVisible function calls */ + QTimer *ScrollTimer; +/* QTimer *ChangeIntervalTimer, */ + /** Timer to start a drag */ + QTimer *DragStartTimer; + /** timer to measure whether the time between a double click and the following counts for a tripleclick */ + QTimer *TrippleClickTimer; + + /** object to store the blinking cursor pixmaps */ + KCursor *CursorPixmaps; + /** */ + KCharCodec *Codec; + + protected: + /** point at which the current double click happended (used by TrippleClick) */ + QPoint DoubleClickPoint; + /** line in which the current double click happended (used by TrippleClick) */ + int DoubleClickLine; + /** point at which the current dragging started */ + QPoint DragStartPoint; + /** */ + QClipboard::Mode ClipboardMode; + /** font size as set by user (used for zooming) */ + int DefaultFontSize; + + protected: // parameters + /** style of resizing */ + KResizeStyle ResizeStyle; + /** */ + KEncoding Encoding; + + /** flag whether the widget is set to readonly. Cannot override the databuffer's setting, of course. */ + bool ReadOnly:1; + /** flag if only overwrite is allowed */ + bool OverWriteOnly:1; + /** flag if overwrite mode is active */ + bool OverWrite:1; + /** flag if a mouse button is pressed */ + bool MousePressed:1; + /** flag if a double click is happening */ + bool InDoubleClick:1; + /** flag if a Drag'n'Drop is happening */ + bool InDnD:1; + /** flag if a drag might have started */ + bool DragStartPossible:1; + /** flag if the cursor should be invisible */ + bool CursorPaused:1; + /** flag if the cursor is visible */ + bool BlinkCursorVisible:1; + /** flag whether the font is changed due to a zooming */ + bool InZooming:1; + + private: + /** the binary compatibility saving helper */ + KHexEditPrivate* d; + + private: // Disabling copy constructor and operator= - not useful + KHexEdit( const KHexEdit & ); + KHexEdit &operator=( const KHexEdit & ); +}; + + +inline const KValueColumn& KHexEdit::valueColumn() const { return *ValueColumn; } +inline const KCharColumn& KHexEdit::charColumn() const { return *CharColumn; } +inline const KBufferColumn& KHexEdit::activeColumn() const { return *ActiveColumn; } +inline const KBufferColumn& KHexEdit::inactiveColumn() const { return *InactiveColumn; } + +inline KValueColumn& KHexEdit::valueColumn() { return *ValueColumn; } +inline KCharColumn& KHexEdit::charColumn() { return *CharColumn; } +inline KBufferColumn& KHexEdit::activeColumn() { return *ActiveColumn; } +inline KBufferColumn& KHexEdit::inactiveColumn() { return *InactiveColumn; } + +} + +#endif |