/*************************************************************************** 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 // lib specific // #include "khe.h" #include "khexedit_export.h" #include "kcolumnsview.h" class TQTimer; namespace KHE { class KCoordRange; class KDataBuffer; class KCharColumn; class KValueColumn; class TDEBufferColumn; class KOffsetColumn; class KBorderColumn; class TDEBufferCursor; class TDEBufferLayout; class TDEBufferRanges; class KController; class KTabController; class KNavigator; class KValueEditor; class KCharEditor; class TDEBufferDrag; 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 TQ_ENUMS( KResizeStyle KCoding ) TQ_PROPERTY( bool OverwriteMode READ isOverwriteMode WRITE setOverwriteMode ) TQ_PROPERTY( bool OverwriteOnly READ isOverwriteOnly WRITE setOverwriteOnly ) TQ_PROPERTY( bool Modified READ isModified WRITE setModified DESIGNABLE false ) TQ_PROPERTY( bool ReadOnly READ isReadOnly WRITE setReadOnly ) TQ_PROPERTY( int NoOfBytesPerLine READ noOfBytesPerLine WRITE setNoOfBytesPerLine ) TQ_PROPERTY( bool TabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus ) //TQ_PROPERTY( bool hasSelectedData READ hasSelectedData ) //TQ_PROPERTY( TQByteArray SelectedData READ selectedData ) TQ_PROPERTY( KResizeStyle ResizeStyle READ resizeStyle WRITE setResizeStyle ) TQ_PROPERTY( int StartOffset READ startOffset WRITE setStartOffset ) TQ_PROPERTY( int FirstLineOffset READ firstLineOffset WRITE setFirstLineOffset ) //_PROPERTY( int undoDepth READ undoDepth WRITE setUndoDepth ) //_PROPERTY( bool undoRedoEnabled READ isUndoRedoEnabled WRITE setUndoRedoEnabled ) // value column TQ_PROPERTY( KCoding Coding READ coding WRITE setCoding ) TQ_PROPERTY( int ByteSpacingWidth READ byteSpacingWidth WRITE setByteSpacingWidth ) TQ_PROPERTY( int NoOfGroupedBytes READ noOfGroupedBytes WRITE setNoOfGroupedBytes ) TQ_PROPERTY( int GroupSpacingWidth READ groupSpacingWidth WRITE setGroupSpacingWidth ) TQ_PROPERTY( int BinaryGapWidth READ binaryGapWidth WRITE setBinaryGapWidth ) // char column TQ_PROPERTY( bool ShowUnprintable READ showUnprintable WRITE setShowUnprintable ) TQ_PROPERTY( TQChar 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 TDEBufferColumnId { ValueColumnId=1, CharColumnId=2 }; public: KHexEdit( KDataBuffer *Buffer = 0, TQWidget *Parent = 0, const char *Name = 0, WFlags F = 0 ); virtual ~KHexEdit(); public: // KColumnsView API virtual void drawContents( TQPainter *p, int cx, int cy, int cw, int ch ); public: // TQWidget API // void focusInEvent( TQFocusEvent *FocusEvent ); // TODO: why don't these work? // void focusOutEvent( TQFocusEvent *FocusEvent ); virtual bool eventFilter( TQObject *O, TQEvent *E ); virtual TQSize sizeHint() const; virtual TQSize minimumSizeHint() const; public: // value access /** returns the index of the cursor position */ int cursorPosition() const; /***/ bool isCursorBehind() const; TDEBufferColumnId 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 */ TQChar substituteChar() const; /** returns the actually used undefined character for "undefined" chars, default is '?' */ TQChar undefinedChar() const; /** * @return encoding used in the char column */ KEncoding encoding() const; /** * @return name of the encoding used in the char column */ const TQString &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 TQSize &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 TQPoint &Point ) const; public: /** returns true if there is a selected range in the array */ bool hasSelectedData() const; /** * @return deep copy of the selected data */ TQByteArray 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 TQPoint &Point ); /***/ void setCursorColumn( TDEBufferColumnId ); // 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( TQChar SC ); /** sets the undefined character for "undefined" chars * returns true if there was a change */ void setUndefinedChar( TQChar 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 TQString& 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 TQByteArray &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: // TQWidget API virtual void keyPressEvent( TQKeyEvent *KeyEvent ); virtual void resizeEvent( TQResizeEvent *ResizeEvent ); virtual void showEvent( TQShowEvent *e ); protected: // TQScrollView API virtual void contentsMousePressEvent( TQMouseEvent *e ); virtual void contentsMouseReleaseEvent( TQMouseEvent * e ); virtual void contentsMouseMoveEvent( TQMouseEvent *e ); virtual void contentsMouseDoubleClickEvent( TQMouseEvent * e ); virtual void contentsDragEnterEvent( TQDragEnterEvent *e ); virtual void contentsDragMoveEvent( TQDragMoveEvent *e ); virtual void contentsDragLeaveEvent( TQDragLeaveEvent * ); virtual void contentsDropEvent( TQDropEvent *e ); virtual void contentsWheelEvent( TQWheelEvent *e ); // virtual void contentsContextMenuEvent( TQContextMenuEvent *e ); protected: // KColumnsView API virtual void setNoOfLines( int NewNoOfLines ); protected: // element accessor functions KValueColumn& valueColumn(); KCharColumn& charColumn(); TDEBufferColumn& activeColumn(); TDEBufferColumn& inactiveColumn(); const KValueColumn& valueColumn() const; const KCharColumn& charColumn() const; const TDEBufferColumn& activeColumn() const; const TDEBufferColumn& 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( TQPainter &Painter, const TDEBufferColumn &Column ) const; /** draws the blinking cursor or removes it */ void paintActiveCursor( bool CursorOn ); void paintInactiveCursor( bool CursorOn ); void paintLine( TDEBufferColumn *C, int Line, KSection Positions ); protected: // partial operations void handleMouseMove( const TQPoint& Point ); TDEBufferDrag *dragObject( TQWidget *Parent = 0 ) const; void pasteFromSource( TQMimeSource *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( TQDropEvent *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: // TQWidget API virtual void fontChange( const TQFont &OldFont ); protected: /** Buffer with the data */ KDataBuffer *DataBuffer; /** holds the logical layout */ TDEBufferLayout *BufferLayout; /** */ TDEBufferCursor *BufferCursor; /** */ TDEBufferRanges *BufferRanges; protected: KOffsetColumn *OffsetColumn; KBorderColumn *FirstBorderColumn; KValueColumn *ValueColumn; KBorderColumn *SecondBorderColumn; KCharColumn *CharColumn; /** points to the column with keyboard focus */ TDEBufferColumn *ActiveColumn; /** points to the column without keyboard focus (if there is) */ TDEBufferColumn *InactiveColumn; /** the actual input controller */ KController *Controller; /** */ KTabController *TabController; /** */ KNavigator *Navigator; /** */ KValueEditor *ValueEditor; /** */ KCharEditor *CharEditor; protected: /** Timer that controls the blinking of the cursor */ TQTimer *CursorBlinkTimer; /** Timer that triggers ensureCursorVisible function calls */ TQTimer *ScrollTimer; /* TQTimer *ChangeIntervalTimer, */ /** Timer to start a drag */ TQTimer *DragStartTimer; /** timer to measure whether the time between a double click and the following counts for a tripleclick */ TQTimer *TrippleClickTimer; /** object to store the blinking cursor pixmaps */ KCursor *CursorPixmaps; /** */ KCharCodec *Codec; protected: /** point at which the current double click happended (used by TrippleClick) */ TQPoint DoubleClickPoint; /** line in which the current double click happended (used by TrippleClick) */ int DoubleClickLine; /** point at which the current dragging started */ TQPoint DragStartPoint; /** */ TQClipboard::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 TDEBufferColumn& KHexEdit::activeColumn() const { return *ActiveColumn; } inline const TDEBufferColumn& KHexEdit::inactiveColumn() const { return *InactiveColumn; } inline KValueColumn& KHexEdit::valueColumn() { return *ValueColumn; } inline KCharColumn& KHexEdit::charColumn() { return *CharColumn; } inline TDEBufferColumn& KHexEdit::activeColumn() { return *ActiveColumn; } inline TDEBufferColumn& KHexEdit::inactiveColumn() { return *InactiveColumn; } } #endif