Logo Search packages:      
Sourcecode: kdeutils version File versions

khexedit.h

/***************************************************************************
                          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 "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 KBufferDrag;

class KCursor;

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
  */

00067 class KHexEdit : public KColumnsView
{
  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 )
00074   Q_PROPERTY( bool ReadOnly READ isReadOnly WRITE setReadOnly )

  Q_PROPERTY( int NoOfBytesPerLine READ noOfBytesPerLine WRITE setNoOfBytesPerLine )
00077   Q_PROPERTY( bool TabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus )

  //Q_PROPERTY( bool hasSelectedData READ hasSelectedData )
  //Q_PROPERTY( QByteArray SelectedData READ selectedData )
00081   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 KMoveAction { MoveBackward, MoveWordBackward, MoveForward, MoveWordForward,
                       MoveUp, MovePgUp, MoveDown, MovePgDown,
                       MoveLineStart, MoveHome, MoveLineEnd, MoveEnd };
    enum KKeyboardAction { ActionDelete, ActionWordDelete, ActionBackspace, ActionWordBackspace };

    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, MaxEncodingId=0xFFFF };


  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 true if there is a selected range in the array */
    bool hasSelectedData() 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;
    
  // 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;
    /**
      * @return encoding used in the char column
      */
    KEncoding encoding() 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:
    /** 
      * @return deep copy of the selected data 
      */
    QByteArray selectedData() const;

  public: // modification access
    /** moves the cursor according to the action, handles all drawing */
    void moveCursor( KMoveAction Action );
    /** puts the cursor to the position of index, handles all drawing 
      * @param Index 
      */
    void setCursorPosition( int Index );
    /** 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 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 );
    /** 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 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 );

  // interaction
    /** de-/selects all data */
    void selectAll( bool select );
    /** selects word at index, returns true if there is one */
    bool selectWord( /*unsigned*/ int Index /*, Chartype*/ );
    /**  */
    void moveCursor( KMoveAction Action, bool Select );
    /** executes keyboard Action \a Action. This is normally called by a key event handler. */
    void doKeyboardAction( KKeyboardAction Action );
    /** 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();

  // byte editing
    /** steps inside editing the byte in the value column */
    bool goInsideByte();
    /** */
    void goOutsideByte( bool MoveToNext = false );
    /** increases the byte in the buffer */
    bool incByte();
    /** increases the byte in the buffer */
    bool decByte();



  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();
    /** 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();
    /** the input was not even partially inserted */
    void inputFailed();


  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
    KOffsetColumn& offsetColumn();
    KValueColumn& valueColumn();
    KCharColumn& charColumn();
    KBufferColumn& activeColumn();
    KBufferColumn& inactiveColumn();
    const KOffsetColumn& offsetColumn() const;
    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();
    bool handleByteEditKey( QKeyEvent *KeyEvent );
    bool handleLetter( QKeyEvent *KeyEvent );

  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 paintEditedByte( bool Edited );
    void paintLine( KBufferColumn *C, int Line, KSection Positions );

  protected: // partial operations
    void handleMouseMove( const QPoint& Point );
    KBufferDrag *dragObject( bool F = false, QWidget *Parent = 0 ) const;
    void pasteFromSource( QMimeSource *Source );
    /** removes the section from the databuffer and updates all affected values */
    void 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;
    /** copies the actual edit value to the databuffer and updates the coding string */
    void syncEditedByte();
    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 */
00438     KDataBuffer *DataBuffer;

    /** holds the logical layout */
00441     KBufferLayout *BufferLayout;
    /** */
00443     KBufferCursor *BufferCursor;
    /** */
00445     KBufferRanges *BufferRanges;

    
  protected:
    KOffsetColumn *OffsetColumn;
    KBorderColumn *FirstBorderColumn;
    KValueColumn    *ValueColumn;
    KBorderColumn *SecondBorderColumn;
    KCharColumn   *CharColumn;

    /** points to the column with keyboard focus */
00456     KBufferColumn *ActiveColumn;
    /** points to the column without keyboard focus (if there is) */
00458     KBufferColumn *InactiveColumn;

  protected:
    /** Timer that controls the blinking of the cursor */
00462     QTimer *CursorBlinkTimer;
    /** Timer that triggers ensureCursorVisible function calls */
00464     QTimer *ScrollTimer;
/*     QTimer *ChangeIntervalTimer, */
    /** Timer to start a drag */
00467     QTimer *DragStartTimer;
    /** timer to measure whether the time between a double click and the following counts for a tripleclick */
00469     QTimer *TrippleClickTimer;

    /** object to store the blinking cursor pixmaps */
00472     KCursor *CursorPixmaps;
    /** buffer with the  */
00474     char *ByteBuffer;
    /** stores the number of actual digits */
00476     int LengthOfByteBuffer;
    /** */
00478     unsigned char EditValue;
    /** stores the old byte value */
00480     unsigned char OldValue;

  protected:
    /** point at which the current double click happended (used by TrippleClick) */
00484     QPoint DoubleClickPoint;
    /** line in which the current double click happended (used by TrippleClick) */
00486     int DoubleClickLine;
    /** point at which the current dragging started */
00488     QPoint DragStartPoint;
    /** */
00490     QClipboard::Mode ClipboardMode;
    /** font size as set by user (used for zooming) */
00492     int DefaultFontSize;

  protected: // parameters
    /** style of resizing */
    KResizeStyle ResizeStyle;
    /** flag if tab key should be ignored */
    bool TabChangesFocus:1;
    /** 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 */
00502     bool OverWriteOnly:1;
    /** flag if overwrite mode is active */
00504     bool OverWrite:1;
    /** flag if a mouse button is pressed */
00506     bool MousePressed:1;
    /** flag if a double click is happening */
00508     bool InDoubleClick:1;
    /** flag if a Drag'n'Drop is happening */
00510     bool InDnD:1;
    /** flag if a drag might have started */
00512     bool DragStartPossible:1;
    /** flag if the cursor should be invisible */
00514     bool CursorPaused:1;
    /** flag if the cursor is visible */
00516     bool BlinkCursorVisible:1;
    /** flag whether the font is changed due to a zooming */
00518     bool InZooming:1;
    /** flag whether we are in byte digits editing mode */
00520     bool InEditMode:1;
    /** flag whether byte edit mode was reached by inserting */
00522     bool EditModeByInsert:1;

  private:
    /** the binary compatibility saving helper */
00526     KHexEditPrivate* d;

  private: // Disabling copy constructor and operator= - not useful
    KHexEdit( const KHexEdit & );
    KHexEdit &operator=( const KHexEdit & );
};


inline const KOffsetColumn& KHexEdit::offsetColumn()   const { return *OffsetColumn; }
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 KOffsetColumn& KHexEdit::offsetColumn()   { return *OffsetColumn; }
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

Generated by  Doxygen 1.6.0   Back to index