summaryrefslogtreecommitdiffstats
path: root/khexedit/lib
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch)
tree8d927b7b47a90c4adb646482a52613f58acd6f8c /khexedit/lib
downloadtdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz
tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'khexedit/lib')
-rw-r--r--khexedit/lib/Makefile.am39
-rw-r--r--khexedit/lib/README36
-rw-r--r--khexedit/lib/codecs/Makefile.am15
-rw-r--r--khexedit/lib/codecs/README1
-rw-r--r--khexedit/lib/codecs/kbinarybytecodec.cpp80
-rw-r--r--khexedit/lib/codecs/kbinarybytecodec.h59
-rw-r--r--khexedit/lib/codecs/kbytecodec.cpp63
-rw-r--r--khexedit/lib/codecs/kcharcodec.cpp74
-rw-r--r--khexedit/lib/codecs/kdecimalbytecodec.cpp92
-rw-r--r--khexedit/lib/codecs/kdecimalbytecodec.h59
-rw-r--r--khexedit/lib/codecs/kebcdic1047charcodec.cpp124
-rw-r--r--khexedit/lib/codecs/kebcdic1047charcodec.h50
-rw-r--r--khexedit/lib/codecs/khexadecimalbytecodec.cpp113
-rw-r--r--khexedit/lib/codecs/khexadecimalbytecodec.h69
-rw-r--r--khexedit/lib/codecs/koctalbytecodec.cpp80
-rw-r--r--khexedit/lib/codecs/koctalbytecodec.h59
-rw-r--r--khexedit/lib/codecs/ktextcharcodec.cpp236
-rw-r--r--khexedit/lib/codecs/ktextcharcodec.h66
-rw-r--r--khexedit/lib/controller/Makefile.am12
-rw-r--r--khexedit/lib/controller/kchareditor.cpp58
-rw-r--r--khexedit/lib/controller/kchareditor.h43
-rw-r--r--khexedit/lib/controller/kcontroller.cpp34
-rw-r--r--khexedit/lib/controller/kcontroller.h44
-rw-r--r--khexedit/lib/controller/keditor.cpp197
-rw-r--r--khexedit/lib/controller/keditor.h52
-rw-r--r--khexedit/lib/controller/knavigator.cpp142
-rw-r--r--khexedit/lib/controller/knavigator.h46
-rw-r--r--khexedit/lib/controller/ktabcontroller.cpp70
-rw-r--r--khexedit/lib/controller/ktabcontroller.h52
-rw-r--r--khexedit/lib/controller/kvalueeditor.cpp226
-rw-r--r--khexedit/lib/controller/kvalueeditor.h75
-rw-r--r--khexedit/lib/helper.h31
-rw-r--r--khexedit/lib/kadds.h36
-rw-r--r--khexedit/lib/kbigbuffer.cpp216
-rw-r--r--khexedit/lib/kbigbuffer.h119
-rw-r--r--khexedit/lib/kbordercoltextexport.cpp47
-rw-r--r--khexedit/lib/kbordercoltextexport.h40
-rw-r--r--khexedit/lib/kbordercolumn.cpp82
-rw-r--r--khexedit/lib/kbordercolumn.h52
-rw-r--r--khexedit/lib/kbuffercoltextexport.cpp108
-rw-r--r--khexedit/lib/kbuffercoltextexport.h73
-rw-r--r--khexedit/lib/kbuffercolumn.cpp700
-rw-r--r--khexedit/lib/kbuffercolumn.h253
-rw-r--r--khexedit/lib/kbuffercoord.h293
-rw-r--r--khexedit/lib/kbuffercursor.cpp365
-rw-r--r--khexedit/lib/kbuffercursor.h172
-rw-r--r--khexedit/lib/kbufferdrag.cpp237
-rw-r--r--khexedit/lib/kbufferdrag.h76
-rw-r--r--khexedit/lib/kbufferlayout.cpp240
-rw-r--r--khexedit/lib/kbufferlayout.h196
-rw-r--r--khexedit/lib/kbufferranges.cpp307
-rw-r--r--khexedit/lib/kbufferranges.h130
-rw-r--r--khexedit/lib/kbytecodec.h73
-rw-r--r--khexedit/lib/kbytesedit.cpp162
-rw-r--r--khexedit/lib/kbytesedit.h163
-rw-r--r--khexedit/lib/kcharcodec.h55
-rw-r--r--khexedit/lib/kcharcoltextexport.cpp71
-rw-r--r--khexedit/lib/kcharcoltextexport.h50
-rw-r--r--khexedit/lib/kcharcolumn.cpp61
-rw-r--r--khexedit/lib/kcharcolumn.h116
-rw-r--r--khexedit/lib/kcoltextexport.h40
-rw-r--r--khexedit/lib/kcolumn.cpp60
-rw-r--r--khexedit/lib/kcolumn.h126
-rw-r--r--khexedit/lib/kcolumnsview.cpp236
-rw-r--r--khexedit/lib/kcolumnsview.h168
-rw-r--r--khexedit/lib/kcoordrange.h95
-rw-r--r--khexedit/lib/kcoordrangelist.cpp78
-rw-r--r--khexedit/lib/kcoordrangelist.h44
-rw-r--r--khexedit/lib/kcursor.cpp49
-rw-r--r--khexedit/lib/kcursor.h68
-rw-r--r--khexedit/lib/kdatabuffer.cpp51
-rw-r--r--khexedit/lib/kdatabuffer.h246
-rw-r--r--khexedit/lib/kfixedsizebuffer.cpp272
-rw-r--r--khexedit/lib/kfixedsizebuffer.h116
-rw-r--r--khexedit/lib/khe.h95
-rw-r--r--khexedit/lib/khechar.h44
-rw-r--r--khexedit/lib/khexedit.cpp2032
-rw-r--r--khexedit/lib/khexedit.h562
-rw-r--r--khexedit/lib/khexedit_export.h25
-rw-r--r--khexedit/lib/koffsetcoltextexport.cpp61
-rw-r--r--khexedit/lib/koffsetcoltextexport.h57
-rw-r--r--khexedit/lib/koffsetcolumn.cpp110
-rw-r--r--khexedit/lib/koffsetcolumn.h109
-rw-r--r--khexedit/lib/koffsetformat.cpp48
-rw-r--r--khexedit/lib/koffsetformat.h70
-rw-r--r--khexedit/lib/kplainbuffer.cpp344
-rw-r--r--khexedit/lib/kplainbuffer.h131
-rw-r--r--khexedit/lib/krange.h123
-rw-r--r--khexedit/lib/kreadonlybuffer.h45
-rw-r--r--khexedit/lib/ksection.h108
-rw-r--r--khexedit/lib/ksectionlist.cpp79
-rw-r--r--khexedit/lib/ksectionlist.h44
-rw-r--r--khexedit/lib/kselection.h178
-rw-r--r--khexedit/lib/kvaluecoltextexport.cpp69
-rw-r--r--khexedit/lib/kvaluecoltextexport.h47
-rw-r--r--khexedit/lib/kvaluecolumn.cpp134
-rw-r--r--khexedit/lib/kvaluecolumn.h92
-rw-r--r--khexedit/lib/kwordbufferservice.cpp209
-rw-r--r--khexedit/lib/kwordbufferservice.h137
-rw-r--r--khexedit/lib/kwrappingrobuffer.cpp61
-rw-r--r--khexedit/lib/kwrappingrobuffer.h85
101 files changed, 13638 insertions, 0 deletions
diff --git a/khexedit/lib/Makefile.am b/khexedit/lib/Makefile.am
new file mode 100644
index 0000000..c0c92cc
--- /dev/null
+++ b/khexedit/lib/Makefile.am
@@ -0,0 +1,39 @@
+SUBDIRS = controller codecs
+
+INCLUDES = $(all_includes)
+
+METASOURCES = AUTO
+
+# this library is used by the kbytesedit part and the khepart part
+lib_LTLIBRARIES = libkhexeditcommon.la
+libkhexeditcommon_la_LDFLAGS = $(all_libraries) -no-undefined
+libkhexeditcommon_la_LIBADD = controller/libkcontroller.la codecs/libkhecodecs.la $(LIB_KDECORE)
+libkhexeditcommon_la_SOURCES = kcolumn.cpp kbordercolumn.cpp koffsetcolumn.cpp \
+ kbuffercolumn.cpp kvaluecolumn.cpp kcharcolumn.cpp \
+ kcolumnsview.cpp khexedit.cpp kbytesedit.cpp \
+ koffsetformat.cpp \
+ kdatabuffer.cpp kwrappingrobuffer.cpp \
+ kplainbuffer.cpp kfixedsizebuffer.cpp kbigbuffer.cpp \
+ kbuffercursor.cpp kbufferlayout.cpp kbufferranges.cpp \
+ kcursor.cpp kbufferdrag.cpp \
+ kwordbufferservice.cpp \
+ ksectionlist.cpp kcoordrangelist.cpp \
+ kbordercoltextexport.cpp koffsetcoltextexport.cpp \
+ kbuffercoltextexport.cpp kvaluecoltextexport.cpp kcharcoltextexport.cpp
+
+# no public API for a direct use by now
+noinst_HEADERS = kcolumn.h kbordercolumn.h koffsetcolumn.h \
+ kbuffercolumn.h kvaluecolumn.h kcharcolumn.h \
+ kbytecodec.h koffsetformat.h khexedit_export.h \
+ kbuffercursor.h kbufferlayout.h kbufferranges.h \
+ kbuffercoord.h kselection.h \
+ kcursor.h kbufferdrag.h \
+ kcoordrange.h ksectionlist.h kcoordrangelist.h \
+ khechar.h kcharcodec.h \
+ kcoltextexport.h kbordercoltextexport.h koffsetcoltextexport.h \
+ kbuffercoltextexport.h kvaluecoltextexport.h kcharcoltextexport.h \
+ kadds.h khe.h krange.h ksection.h \
+ kwordbufferservice.h \
+ kcolumnsview.h khexedit.h kbytesedit.h \
+ kplainbuffer.h kfixedsizebuffer.h kbigbuffer.h \
+ kdatabuffer.h kreadonlybuffer.h kwrappingrobuffer.h
diff --git a/khexedit/lib/README b/khexedit/lib/README
new file mode 100644
index 0000000..ad5f346
--- /dev/null
+++ b/khexedit/lib/README
@@ -0,0 +1,36 @@
+hex editor library
+==================
+part of the KHexEdit 2 project (kdenonbeta/khexedit2)
+Author/Maintainer: Friedrich W. H. Kossebau <Friedrich.W.H@Kossebau.de>
+
+
+description:
+-----------
+The lib is the main work of KHexEdit2. It offers
+a general usable hex edit widget "KHexEdit"
+that interacts with an abstract data buffer
+interface called "KDataBuffer". This interface can
+be subclassed to offer access to different data buffers
+like paged gigabyte big files, video memory or whatever
+you can imagine (hopefully).
+
+For those simply needing a widget for a plain array of bytes
+there is the widget subclass "KBytesEdit", which hides the
+databuffer interface and publically simply interacts with
+arrays (like "char Array[25];").
+
+
+installing:
+-----------
+As these widgets and the databuffer interface have not got
+much testing the API might not be finished. Because of that
+it won't be made public available, i.e. there will be no headers
+installed.
+
+
+usage:
+------
+This lib is by now only used by the KBytesEdit part, to be found
+in "../parts/kbytesedit".
+It is _not_ used by the current KHexEdit 1 app. This will change once
+the successor app from KHexEdit2 is done. \ No newline at end of file
diff --git a/khexedit/lib/codecs/Makefile.am b/khexedit/lib/codecs/Makefile.am
new file mode 100644
index 0000000..0c208b7
--- /dev/null
+++ b/khexedit/lib/codecs/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I$(srcdir)/.. $(all_includes)
+
+METASOURCES = AUTO
+
+#
+noinst_LTLIBRARIES = libkhecodecs.la
+libkhecodecs_la_SOURCES = kcharcodec.cpp kbytecodec.cpp \
+ ktextcharcodec.cpp kebcdic1047charcodec.cpp \
+ kbinarybytecodec.cpp koctalbytecodec.cpp \
+ kdecimalbytecodec.cpp khexadecimalbytecodec.cpp
+
+# no public API
+noinst_HEADERS = ktextcharcodec.h kebcdic1047charcodec.h \
+ kbinarybytecodec.h koctalbytecodec.h \
+ kdecimalbytecodec.h khexadecimalbytecodec.h \ No newline at end of file
diff --git a/khexedit/lib/codecs/README b/khexedit/lib/codecs/README
new file mode 100644
index 0000000..b4a0e52
--- /dev/null
+++ b/khexedit/lib/codecs/README
@@ -0,0 +1 @@
+This directory holds all the char codecs. All it exports is the call "createCodec()", the rest in hidden.
diff --git a/khexedit/lib/codecs/kbinarybytecodec.cpp b/khexedit/lib/codecs/kbinarybytecodec.cpp
new file mode 100644
index 0000000..d665a05
--- /dev/null
+++ b/khexedit/lib/codecs/kbinarybytecodec.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ kbinarybytecodec.cpp - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kbinarybytecodec.h"
+
+using namespace KHE;
+
+
+void KBinaryByteCodec::encode( QString &Digits, unsigned int Pos, const unsigned char Char ) const
+{
+ for( unsigned char M=1<<7; M>0; M>>=1 )
+ Digits.at(Pos++) = (Char & M) ? '1' : '0';
+}
+
+void KBinaryByteCodec::encodeShort( QString &Digits, unsigned int Pos, unsigned char Char ) const
+{
+ unsigned char M = 1<<7;
+ // find first set bit
+ for( ; M>0; M>>=1 )
+ if( Char & M )
+ break;
+ // now set the
+ for( ; M>0; M>>=1 )
+ Digits.at(Pos++) = (Char & M) ? '1' : '0';
+}
+
+
+bool KBinaryByteCodec::isValidDigit( unsigned char Digit ) const
+{
+ return Digit == '0' || Digit == '1';
+}
+
+
+bool KBinaryByteCodec::turnToValue( unsigned char *Digit ) const
+{
+ if( isValidDigit(*Digit) )
+ {
+ *Digit -= '0';
+ return true;
+ }
+ return false;
+}
+
+
+bool KBinaryByteCodec::appendDigit( unsigned char *Byte, unsigned char Digit ) const
+{
+ if( turnToValue(&Digit) )
+ {
+ unsigned char B = *Byte;
+ if( B < 128 )
+ {
+ B <<= 1;
+ B += Digit;
+ *Byte = B;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+void KBinaryByteCodec::removeLastDigit( unsigned char *Byte ) const
+{
+ *Byte >>= 1;
+}
diff --git a/khexedit/lib/codecs/kbinarybytecodec.h b/khexedit/lib/codecs/kbinarybytecodec.h
new file mode 100644
index 0000000..d0354fa
--- /dev/null
+++ b/khexedit/lib/codecs/kbinarybytecodec.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ kbinarybytecodec.h - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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_KBINARYBYTECODEC_H
+#define KHE_KBINARYBYTECODEC_H
+
+// lib specific
+#include "kbytecodec.h"
+
+namespace KHE
+{
+
+/** class that is able to convert codings to and from binary
+ *
+ * the buffer will be always filled up to CodingWidth, if not using shortCodingFunction
+ * a closing '\0' will be always added
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KBinaryByteCodec : public KByteCodec
+{
+ public: // API to be implemented
+ /** */
+ virtual unsigned int encodingWidth() const { return 8; }
+ /** */
+ virtual unsigned char digitsFilledLimit() const { return 128; }
+
+ /** encodes the Char and writes the result to */
+ virtual void encode( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual void encodeShort( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual bool appendDigit( unsigned char *Byte, const unsigned char Digit ) const;
+ /** */
+ virtual void removeLastDigit( unsigned char *Byte ) const;
+ /** */
+ virtual bool isValidDigit( const unsigned char Digit ) const;
+ /** */
+ virtual bool turnToValue( unsigned char *Digit ) const;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/codecs/kbytecodec.cpp b/khexedit/lib/codecs/kbytecodec.cpp
new file mode 100644
index 0000000..dc5137f
--- /dev/null
+++ b/khexedit/lib/codecs/kbytecodec.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ kbytecodec.cpp - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kbinarybytecodec.h"
+#include "koctalbytecodec.h"
+#include "kdecimalbytecodec.h"
+#include "khexadecimalbytecodec.h"
+
+using namespace KHE;
+
+
+KByteCodec *KByteCodec::createCodec( KCoding C )
+{
+ KByteCodec *Codec;
+ switch( C )
+ {
+ case DecimalCoding: Codec = new KDecimalByteCodec(); break;
+ case OctalCoding: Codec = new KOctalByteCodec(); break;
+ case BinaryCoding: Codec = new KBinaryByteCodec(); break;
+ case HexadecimalCoding:
+ default: Codec = new KHexadecimalByteCodec();
+ }
+ return Codec;
+}
+
+unsigned int KByteCodec::decode( unsigned char *Char, const QString &Digits, uint Pos ) const
+{
+ //kdDebug() << QString("KByteCodec::decode(%1,%2)").arg(Digits).arg(Pos) << endl;
+ const uint P = Pos;
+
+ // remove leading 0s
+ while( Digits.at(Pos) == '0' ) { ++Pos; }
+
+ unsigned char C = 0;
+ unsigned int d = encodingWidth();
+ do
+ {
+ if( !appendDigit(&C,Digits.at(Pos)) )
+ break;
+
+ ++Pos;
+ --d;
+ }
+ while( d > 0 );
+
+ *Char = C;
+ return Pos - P;
+}
diff --git a/khexedit/lib/codecs/kcharcodec.cpp b/khexedit/lib/codecs/kcharcodec.cpp
new file mode 100644
index 0000000..5a58320
--- /dev/null
+++ b/khexedit/lib/codecs/kcharcodec.cpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ kcharcodec.cpp - description
+ -------------------
+ begin : Do Nov 25 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kcharcodec.h"
+#include "ktextcharcodec.h"
+#include "kebcdic1047charcodec.h"
+
+using namespace KHE;
+
+
+QStringList KCharCodec::CodecNames;
+
+const QStringList &KCharCodec::codecNames()
+{
+ // first call?
+ if( CodecNames.isEmpty() )
+ {
+ CodecNames = KTextCharCodec::codecNames();
+ CodecNames.append( KEBCDIC1047CharCodec::codecName() );
+ }
+
+ return CodecNames;
+}
+
+
+KCharCodec *KCharCodec::createCodec( const QString &Name )
+{
+ KCharCodec *Codec = 0;
+
+ if( KTextCharCodec::codecNames().findIndex(Name) != -1 )
+ Codec = KTextCharCodec::createCodec( Name );
+ else if( KEBCDIC1047CharCodec::codecName() == Name )
+ Codec = KEBCDIC1047CharCodec::create();
+
+ // ensure at least a codec
+ if( Codec == 0 )
+ Codec = KTextCharCodec::createLocalCodec();
+
+ return Codec;
+}
+
+
+KCharCodec *KCharCodec::createCodec( KEncoding C )
+{
+ KCharCodec *Codec;
+ if( C == EBCDIC1047Encoding )
+ Codec = KEBCDIC1047CharCodec::create();
+ else if( C == ISO8859_1Encoding )
+ Codec = KTextCharCodec::createCodec( "ISO 8859-1" );
+ // LocalEncoding
+ else
+ Codec = 0;
+
+ // ensure at least a codec
+ if( Codec == 0 )
+ Codec = KTextCharCodec::createLocalCodec();
+
+ return Codec;
+}
diff --git a/khexedit/lib/codecs/kdecimalbytecodec.cpp b/khexedit/lib/codecs/kdecimalbytecodec.cpp
new file mode 100644
index 0000000..9470382
--- /dev/null
+++ b/khexedit/lib/codecs/kdecimalbytecodec.cpp
@@ -0,0 +1,92 @@
+/***************************************************************************
+ kdecimalbytecodec.cpp - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kdecimalbytecodec.h"
+
+using namespace KHE;
+
+
+void KDecimalByteCodec::encode( QString &Digits, unsigned int Pos, unsigned char Char ) const
+{
+ unsigned char C = Char / 100;
+ Digits.at(Pos++) = '0'+C;
+ Char -= C * 100;
+ C = Char / 10;
+ Digits.at(Pos++) = '0'+C;
+ Char -= C * 10;
+ Digits.at(Pos) = '0'+Char;
+}
+
+
+void KDecimalByteCodec::encodeShort( QString &Digits, unsigned int Pos, unsigned char Char ) const
+{
+ unsigned char C;
+ if( (C = Char / 100) )
+ {
+ Digits.at(Pos++) = '0'+C;
+ Char -= C * 100;
+ }
+ if( (C = Char / 10) )
+ {
+ Digits.at(Pos++) = '0'+C;
+ Char -= C * 10;
+ }
+ Digits.at(Pos) = '0'+Char;
+}
+
+
+
+bool KDecimalByteCodec::isValidDigit( unsigned char Digit ) const
+{
+ return Digit >= '0' && Digit <= '9';
+}
+
+bool KDecimalByteCodec::turnToValue( unsigned char *Digit ) const
+{
+ if( isValidDigit(*Digit) )
+ {
+ *Digit -= '0';
+ return true;
+ }
+ return false;
+}
+
+
+bool KDecimalByteCodec::appendDigit( unsigned char *Byte, unsigned char Digit ) const
+{
+ if( turnToValue(&Digit) )
+ {
+ unsigned char B = *Byte;
+ if( B < 26 )
+ {
+ B *= 10;
+ if( Digit <= 255-B )
+ {
+ B += Digit;
+ *Byte = B;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void KDecimalByteCodec::removeLastDigit( unsigned char *Byte ) const
+{
+ *Byte /= 10;
+}
diff --git a/khexedit/lib/codecs/kdecimalbytecodec.h b/khexedit/lib/codecs/kdecimalbytecodec.h
new file mode 100644
index 0000000..31f61d0
--- /dev/null
+++ b/khexedit/lib/codecs/kdecimalbytecodec.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ kdecimalbytecodec.h - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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_KDECIMALBYTECODEC_H
+#define KHE_KDECIMALBYTECODEC_H
+
+// lib specific
+#include "kbytecodec.h"
+
+namespace KHE
+{
+
+/** class that is able to convert codings to and from binary
+ *
+ * the buffer will be always filled up to CodingWidth, if not using shortCodingFunction
+ * a closing '\0' will be always added
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KDecimalByteCodec : public KByteCodec
+{
+ public: // API to be implemented
+ /** */
+ virtual unsigned int encodingWidth() const { return 3; }
+ /** */
+ virtual unsigned char digitsFilledLimit() const { return 26; }
+
+ /** encodes the Char and writes the result to */
+ virtual void encode( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual void encodeShort( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual bool appendDigit( unsigned char *Byte, const unsigned char Digit ) const;
+ /** */
+ virtual void removeLastDigit( unsigned char *Byte ) const;
+ /** */
+ virtual bool isValidDigit( const unsigned char Digit ) const;
+ /** */
+ virtual bool turnToValue( unsigned char *Digit ) const;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/codecs/kebcdic1047charcodec.cpp b/khexedit/lib/codecs/kebcdic1047charcodec.cpp
new file mode 100644
index 0000000..f26da37
--- /dev/null
+++ b/khexedit/lib/codecs/kebcdic1047charcodec.cpp
@@ -0,0 +1,124 @@
+/***************************************************************************
+ kebcdic1047charcodec.cpp - description
+ -------------------
+ begin : Sa Nov 27 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kebcdic1047charcodec.h"
+
+
+using namespace KHE;
+
+static Q_UINT16 UnicodeChars[256] =
+{
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
+ 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
+ 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
+ 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
+ 0x0020, 0x00A0, 0x00E2, 0x00E4, 0x00E0, 0x00E1, 0x00E3, 0x00E5,
+ 0x00E7, 0x00F1, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
+ 0x0026, 0x00E9, 0x00EA, 0x00EB, 0x00E8, 0x00ED, 0x00EE, 0x00EF,
+ 0x00EC, 0x00DF, 0x0021, 0x0024, 0x002A, 0x0029, 0x003B, 0x005E,
+ 0x002D, 0x002F, 0x00C2, 0x00C4, 0x00C0, 0x00C1, 0x00C3, 0x00C5,
+ 0x00C7, 0x00D1, 0x00A6, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
+ 0x00F8, 0x00C9, 0x00CA, 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF,
+ 0x00CC, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
+ 0x00D8, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
+ 0x0068, 0x0069, 0x00AB, 0x00BB, 0x00F0, 0x00FD, 0x00FE, 0x00B1,
+ 0x00B0, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
+ 0x0071, 0x0072, 0x00AA, 0x00BA, 0x00E6, 0x00B8, 0x00C6, 0x00A4,
+ 0x00B5, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
+ 0x0079, 0x007A, 0x00A1, 0x00BF, 0x00D0, 0x005B, 0x00DE, 0x00AE,
+ 0x00AC, 0x00A3, 0x00A5, 0x00B7, 0x00A9, 0x00A7, 0x00B6, 0x00BC,
+ 0x00BD, 0x00BE, 0x00DD, 0x00A8, 0x00AF, 0x005D, 0x00B4, 0x00D7,
+ 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
+ 0x0048, 0x0049, 0x00AD, 0x00F4, 0x00F6, 0x00F2, 0x00F3, 0x00F5,
+ 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
+ 0x0051, 0x0052, 0x00B9, 0x00FB, 0x00FC, 0x00F9, 0x00FA, 0x00FF,
+ 0x005C, 0x00F7, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005A, 0x00B2, 0x00D4, 0x00D6, 0x00D2, 0x00D3, 0x00D5,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F
+};
+
+static unsigned char EBCDICChars[256] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17,
+ 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B,
+ 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08,
+ 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF,
+ 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5,
+ 0xBB, 0xB4, 0x9A, 0x8A, 0xB0, 0xCA, 0xAF, 0xBC,
+ 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3,
+ 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB,
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68,
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
+ 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF,
+ 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xBA, 0xAE, 0x59,
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48,
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
+ 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1,
+ 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF
+};
+
+static const char KEBCDIC1047CharCodecName[] = "EBCDIC 1047";
+
+
+bool KEBCDIC1047CharCodec::encode( char *D, const QChar &C ) const
+{
+ int I = C.unicode();
+ // not in range?
+ if( 0x00FF < I )
+ return false;
+
+ *D = EBCDICChars[I];
+ return true;
+}
+
+KHEChar KEBCDIC1047CharCodec::decode( char Byte ) const
+{
+ return QChar(UnicodeChars[(unsigned char)Byte]);
+}
+
+const QString& KEBCDIC1047CharCodec::name() const
+{
+ return codecName();
+}
+
+const QString& KEBCDIC1047CharCodec::codecName()
+{
+ static const QString Name( QString::fromLatin1(KEBCDIC1047CharCodecName) );
+ return Name;
+}
diff --git a/khexedit/lib/codecs/kebcdic1047charcodec.h b/khexedit/lib/codecs/kebcdic1047charcodec.h
new file mode 100644
index 0000000..7c30956
--- /dev/null
+++ b/khexedit/lib/codecs/kebcdic1047charcodec.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ kebcdic1047charcodec.h - description
+ -------------------
+ begin : Sa Nov 27 2004
+ copyright : (C) 2004 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_KEBCDIC1047CHARCODEC_H
+#define KHE_KEBCDIC1047CHARCODEC_H
+
+
+#include "kcharcodec.h"
+
+namespace KHE
+{
+
+//
+class KEBCDIC1047CharCodec : public KCharCodec
+{
+ protected:
+ KEBCDIC1047CharCodec();
+
+ public: // KCharCodec API
+ virtual KHEChar decode( char Byte ) const;
+ virtual bool encode( char *D, const QChar &C ) const;
+ virtual const QString& name() const;
+
+ public:
+ static KEBCDIC1047CharCodec *create();
+ static const QString& codecName();
+};
+
+
+inline KEBCDIC1047CharCodec::KEBCDIC1047CharCodec() {}
+
+inline KEBCDIC1047CharCodec *KEBCDIC1047CharCodec::create() { return new KEBCDIC1047CharCodec(); }
+
+}
+
+#endif
diff --git a/khexedit/lib/codecs/khexadecimalbytecodec.cpp b/khexedit/lib/codecs/khexadecimalbytecodec.cpp
new file mode 100644
index 0000000..7072464
--- /dev/null
+++ b/khexedit/lib/codecs/khexadecimalbytecodec.cpp
@@ -0,0 +1,113 @@
+/***************************************************************************
+ khexadecimalbytecodec.cpp - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "khexadecimalbytecodec.h"
+
+using namespace KHE;
+
+
+static const QChar BigDigit[16] =
+{ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' };
+static const QChar SmallDigit[16] =
+{ '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
+
+
+KHexadecimalByteCodec::KHexadecimalByteCodec( bool S ) : Digit( S?SmallDigit:BigDigit ) {}
+
+bool KHexadecimalByteCodec::setSmallDigits( bool S )
+{
+ bool Change = ( S && Digit == BigDigit );
+ Digit = S?SmallDigit:BigDigit;
+ return Change;
+}
+
+bool KHexadecimalByteCodec::smallDigits() const { return Digit != BigDigit; }
+
+
+void KHexadecimalByteCodec::encode( QString &Digits, unsigned int Pos, unsigned char Char ) const
+{
+ Digits.at(Pos++) = Digit[Char>>4];
+ Digits.at(Pos) = Digit[Char&0x0F];
+}
+
+void KHexadecimalByteCodec::encodeShort( QString &Digits, unsigned int Pos, unsigned char Char ) const
+{
+ unsigned char C;
+ if( (C = (Char>>4)) )
+ Digits.at(Pos++) = Digit[C];
+ Digits.at(Pos) = Digit[Char&0x0F];
+}
+
+
+static inline bool isValidBigDigit( unsigned char Digit )
+{
+ return (Digit >= 'A' && Digit <= 'F');
+}
+
+static inline bool isValidSmallDigit( unsigned char Digit )
+{
+ return (Digit >= 'a' && Digit <= 'f');
+}
+
+static inline bool isValidDecimalDigit( unsigned char Digit )
+{
+ return Digit >= '0' && Digit <= '9';
+}
+
+
+bool KHexadecimalByteCodec::isValidDigit( unsigned char Digit ) const
+{
+ return isValidDecimalDigit(Digit) || isValidBigDigit(Digit) || isValidSmallDigit(Digit);
+}
+
+bool KHexadecimalByteCodec::turnToValue( unsigned char *Digit ) const
+{
+ if( isValidDecimalDigit(*Digit) )
+ *Digit -= '0';
+ else if( isValidBigDigit(*Digit) )
+ *Digit -= 'A' - 10;
+ else if( isValidSmallDigit(*Digit) )
+ *Digit -= 'a' - 10;
+ else
+ return false;
+
+ return true;
+}
+
+bool KHexadecimalByteCodec::appendDigit( unsigned char *Byte, unsigned char Digit ) const
+{
+ if( turnToValue(&Digit) )
+ {
+ unsigned char B = *Byte;
+ if( B < 16 )
+ {
+ B <<= 4;
+ B += Digit;
+ *Byte = B;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+void KHexadecimalByteCodec::removeLastDigit( unsigned char *Byte ) const
+{
+ *Byte >>= 4;
+}
diff --git a/khexedit/lib/codecs/khexadecimalbytecodec.h b/khexedit/lib/codecs/khexadecimalbytecodec.h
new file mode 100644
index 0000000..9bb1969
--- /dev/null
+++ b/khexedit/lib/codecs/khexadecimalbytecodec.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ khexadecimalbytecodec.h - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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_KHEXADECIMALBYTECODEC_H
+#define KHE_KHEXADECIMALBYTECODEC_H
+
+// lib specific
+#include "kbytecodec.h"
+
+namespace KHE
+{
+
+/** class that is able to convert codings to and from hexadecimal
+ *
+ * the buffer will be always filled up to CodingWidth, if not using shortCodingFunction
+ * a closing '\0' will be always added
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KHexadecimalByteCodec : public KByteCodec
+{
+ public:
+ KHexadecimalByteCodec( bool S = false );
+
+ public:
+ bool setSmallDigits( bool S );
+ bool smallDigits() const;
+
+ public: // API to be implemented
+ /** */
+ virtual unsigned int encodingWidth() const { return 2; }
+ /** */
+ virtual unsigned char digitsFilledLimit() const { return 16; }
+
+ /** encodes the Char and writes the result to */
+ virtual void encode( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual void encodeShort( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual bool appendDigit( unsigned char *Byte, const unsigned char Digit ) const;
+ /** */
+ virtual void removeLastDigit( unsigned char *Byte ) const;
+ /** */
+ virtual bool isValidDigit( const unsigned char Digit ) const;
+ /** */
+ virtual bool turnToValue( unsigned char *Digit ) const;
+
+ protected:
+ const QChar* Digit;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/codecs/koctalbytecodec.cpp b/khexedit/lib/codecs/koctalbytecodec.cpp
new file mode 100644
index 0000000..1167941
--- /dev/null
+++ b/khexedit/lib/codecs/koctalbytecodec.cpp
@@ -0,0 +1,80 @@
+/***************************************************************************
+ koctalbytecodec.cpp - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "koctalbytecodec.h"
+
+using namespace KHE;
+
+
+void KOctalByteCodec::encode( QString &Digits, unsigned int Pos, unsigned char Char ) const
+{
+ Digits.at(Pos++) = '0'+(Char>>6);
+ Digits.at(Pos++) = '0'+((Char>>3)&0x07);
+ Digits.at(Pos) = '0'+((Char) &0x07);
+}
+
+
+void KOctalByteCodec::encodeShort( QString &Digits, unsigned int Pos, unsigned char Char ) const
+{
+ unsigned char C;
+ if( (C = (Char>>6)&0x07) )
+ Digits.at(Pos++) = '0'+C;
+ if( (C = (Char>>3)&0x07) )
+ Digits.at(Pos++) = '0'+C;
+ Digits.at(Pos) = '0'+((Char)&0x07);
+}
+
+
+bool KOctalByteCodec::isValidDigit( unsigned char Digit ) const
+{
+ return Digit >= '0' && Digit <= '7';
+}
+
+
+bool KOctalByteCodec::turnToValue( unsigned char *Digit ) const
+{
+ if( isValidDigit(*Digit) )
+ {
+ *Digit -= '0';
+ return true;
+ }
+ return false;
+}
+
+
+bool KOctalByteCodec::appendDigit( unsigned char *Byte, unsigned char Digit ) const
+{
+ if( turnToValue(&Digit) )
+ {
+ unsigned char B = *Byte;
+ if( B < 64 )
+ {
+ B <<= 3;
+ B += Digit;
+ *Byte = B;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+void KOctalByteCodec::removeLastDigit( unsigned char *Byte ) const
+{
+ *Byte >>= 3;
+}
diff --git a/khexedit/lib/codecs/koctalbytecodec.h b/khexedit/lib/codecs/koctalbytecodec.h
new file mode 100644
index 0000000..e05ca66
--- /dev/null
+++ b/khexedit/lib/codecs/koctalbytecodec.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+ koctalbytecodec.h - description
+ -------------------
+ begin : Mo Nov 29 2004
+ copyright : (C) 2004 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_KOCTALBYTECODEC_H
+#define KHE_KOCTALBYTECODEC_H
+
+// lib specific
+#include "kbytecodec.h"
+
+namespace KHE
+{
+
+/** class that is able to convert codings to and from binary
+ *
+ * the buffer will be always filled up to CodingWidth, if not using shortCodingFunction
+ * a closing '\0' will be always added
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KOctalByteCodec : public KByteCodec
+{
+ public: // API to be implemented
+ /** */
+ virtual unsigned int encodingWidth() const { return 3; }
+ /** */
+ virtual unsigned char digitsFilledLimit() const { return 64; }
+
+ /** encodes the Char and writes the result to */
+ virtual void encode( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual void encodeShort( QString &Digits, unsigned int Pos, const unsigned char Char ) const;
+ /** */
+ virtual bool appendDigit( unsigned char *Byte, const unsigned char Digit ) const;
+ /** */
+ virtual void removeLastDigit( unsigned char *Byte ) const;
+ /** */
+ virtual bool isValidDigit( const unsigned char Digit ) const;
+ /** */
+ virtual bool turnToValue( unsigned char *Digit ) const;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/codecs/ktextcharcodec.cpp b/khexedit/lib/codecs/ktextcharcodec.cpp
new file mode 100644
index 0000000..613dedd
--- /dev/null
+++ b/khexedit/lib/codecs/ktextcharcodec.cpp
@@ -0,0 +1,236 @@
+/***************************************************************************
+ ktextcharcodec.cpp - description
+ -------------------
+ begin : Sa Nov 27 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include "qtextcodec.h"
+// kde specific
+#include <kglobal.h>
+#include <klocale.h>
+#include <kcharsets.h>
+// lib specific
+#include "ktextcharcodec.h"
+
+
+using namespace KHE;
+
+static const char QTextCodecWhiteSpace = 63;
+
+static struct KEncodingNames {
+ KEncoding Encoding;
+ const char *Name;
+}
+const EncodingNames[] = {
+{ ISO8859_1Encoding, "ISO 8859-1" },
+{ ISO8859_2Encoding, "ISO 8859-2" },
+{ ISO8859_3Encoding, "ISO 8859-3" },
+{ ISO8859_4Encoding, "ISO 8859-4" },
+{ ISO8859_5Encoding, "ISO 8859-5" },
+{ ISO8859_6Encoding, "ISO 8859-6" },
+{ ISO8859_7Encoding, "ISO 8859-7" },
+{ ISO8859_8Encoding, "ISO 8859-8" },
+{ ISO8859_8_IEncoding, "ISO 8859-8-I" },
+{ ISO8859_9Encoding, "ISO 8859-9" },
+{ ISO8859_11Encoding, "ISO 8859-11" },
+{ ISO8859_13Encoding, "ISO 8859-13" },
+{ ISO8859_15Encoding, "ISO 8859-15" },
+{ CP1250Encoding, "CP 1250" },
+{ CP1251Encoding, "CP 1251" },
+{ CP1252Encoding, "CP 1252" },
+{ CP1253Encoding, "CP 1253" },
+{ CP1254Encoding, "CP 1254" },
+{ CP1255Encoding, "CP 1255" },
+{ CP1256Encoding, "CP 1256" },
+{ CP1257Encoding, "CP 1257" },
+{ CP1258Encoding, "CP 1258" },
+{ IBM850Encoding, "IBM 850" },
+{ IBM866Encoding, "IBM 866" },
+{ KOI8_REncoding, "KOI8-R" },
+{ KOI8_UEncoding, "KOI8-U" } };
+//TODO: WS2
+static const unsigned int NoOfEncodings = 26;
+
+static bool is8Bit( QTextCodec *Codec )
+{
+ bool Found = false;
+ for( unsigned int i=0; i<NoOfEncodings; ++i )
+ {
+ if( qstrcmp(Codec->name(),EncodingNames[i].Name) == 0 )
+ {
+ Found = true;
+ break;
+ }
+ }
+ return Found;
+}
+
+static QTextCodec *createLatin1()
+{
+ return KGlobal::charsets()->codecForName( EncodingNames[0].Name );
+}
+
+/** heuristic seems to be doomed :(
+static bool is8Bit( QTextCodec *Codec )
+{
+ bool Result = true;
+
+ // first test different for 0
+ unsigned char c[4];
+ c[0] = 0;
+ c[1] = c[2] = c[3] = 230;
+ QString S = Codec->toUnicode( (const char*)&c,4 );
+ int Length = 1;
+ QCString CS = Codec->fromUnicode( S, Length );
+ //kdDebug() << Codec->name() << " "<<Length << endl;
+ if( Length > 0 )
+ Result = false;
+ // test if all chars survive the recoding
+ else
+ do
+ {
+ ++c[0];
+ S = Codec->toUnicode( (const char*)&c,4 );
+ Length = 1;
+ CS = Codec->fromUnicode( S, Length );
+ //kdDebug() << Codec->name() << " "<<c[0]<<"->"<<CS[0]<<":"<<Length << endl;
+ if( Length != 1 || (CS[0] != (char)c[0] && CS[0] != QTextCodecWhiteSpace) )
+ {
+ Result = false;
+ break;
+ }
+ }
+ while( c[0] < 255 );
+ return Result;
+}
+const QStringList &KTextCharCodec::codecNames()
+{
+ // first call?
+ if( CodecNames.isEmpty() )
+{
+ const QStringList &CharSets = KGlobal::charsets()->availableEncodingNames();
+
+ for( QStringList::ConstIterator it = CharSets.begin(); it != CharSets.end(); ++it )
+{
+ bool Found = true;
+ QTextCodec* Codec = KGlobal::charsets()->codecForName( *it, Found );
+ if( Found && is8Bit(Codec) )
+ CodecNames.append( QString::fromLatin1(Codec->name()) );
+}
+}
+
+ return CodecNames;
+}
+
+QString KTextCharCodec::nameOfEncoding( KEncoding C )
+{
+ KTextCharCodec *Codec = 0;
+
+ const char* N = 0;
+ for( unsigned int i=0; i<NoOfEncodings; ++i )
+ {
+ if( EncodingNames[i].Encoding == C )
+ {
+ N = EncodingNames[i].Name;
+ break;
+ }
+ }
+
+ if( N != 0 )
+ {
+ QString CodeName = QString::fromLatin1( N );
+ }
+ return Codec;
+}
+ */
+
+
+QStringList KTextCharCodec::CodecNames;
+
+KTextCharCodec *KTextCharCodec::createLocalCodec()
+{
+ QTextCodec *Codec = KGlobal::locale()->codecForEncoding();
+ if( !is8Bit(Codec) )
+ Codec = createLatin1();
+ return new KTextCharCodec( Codec );
+}
+
+
+KTextCharCodec *KTextCharCodec::createCodec( const QString &CodeName )
+{
+ bool Ok;
+ QTextCodec *Codec = KGlobal::charsets()->codecForName( CodeName, Ok );
+ if( Ok )
+ Ok = is8Bit( Codec );
+ return Ok ? new KTextCharCodec( Codec ) : 0;
+}
+
+
+const QStringList &KTextCharCodec::codecNames()
+{
+ // first call?
+ if( CodecNames.isEmpty() )
+ {
+ for( unsigned int i=0; i<NoOfEncodings; ++i )
+ {
+ bool Found = true;
+ QString Name = QString::fromLatin1( EncodingNames[i].Name );
+ QTextCodec* Codec = KGlobal::charsets()->codecForName( Name, Found );
+ if( Found )
+ CodecNames.append( QString::fromLatin1(Codec->name()) );
+ }
+ }
+
+ return CodecNames;
+}
+
+
+KTextCharCodec::KTextCharCodec( QTextCodec *C )
+ : Codec( C ),
+ Decoder( C->makeDecoder() ),
+ Encoder( C->makeEncoder() )
+{}
+
+KTextCharCodec::~KTextCharCodec()
+{
+ delete Decoder;
+ delete Encoder;
+}
+
+bool KTextCharCodec::encode( char *D, const QChar &C ) const
+{
+ if( !Codec->canEncode(C) ) // TODO: do we really need the codec?
+ return false;
+ int dummy;
+ char T = Encoder->fromUnicode( C, dummy )[0];
+
+ *D = T;
+ return true;
+}
+
+
+KHEChar KTextCharCodec::decode( char Byte ) const
+{
+ QString S( Decoder->toUnicode(&Byte,1) );
+ return KHEChar(S.at(0));
+}
+
+
+const QString& KTextCharCodec::name() const
+{
+ if( Name.isNull() )
+ Name = QString::fromLatin1( Codec->name() );
+ return Name;
+}
diff --git a/khexedit/lib/codecs/ktextcharcodec.h b/khexedit/lib/codecs/ktextcharcodec.h
new file mode 100644
index 0000000..683919c
--- /dev/null
+++ b/khexedit/lib/codecs/ktextcharcodec.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ ktextcharcodec.h - description
+ -------------------
+ begin : Sa Nov 27 2004
+ copyright : (C) 2004 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_KTEXTCHARCODEC_H
+#define KHE_KTEXTCHARCODEC_H
+
+
+#include "kcharcodec.h"
+
+class QTextCodec;
+class QTextDecoder;
+class QTextEncoder;
+
+namespace KHE
+{
+
+// used by all codecs with full char coping, i.e. there are no undefined chars
+class KTextCharCodec : public KCharCodec
+{
+ public:
+ static KTextCharCodec *createCodec( const QString &CodeName );
+ static KTextCharCodec *createCodec( KEncoding C );
+ static KTextCharCodec *createLocalCodec();
+
+ static const QStringList &codecNames();
+
+ protected:
+ KTextCharCodec( QTextCodec *C );
+ public:
+ virtual ~KTextCharCodec();
+
+ public: // KCharCodec API
+ virtual bool encode( char *D, const QChar &C ) const;
+ virtual KHEChar decode( char Byte ) const;
+ virtual const QString& name() const;
+
+
+ protected:
+ QTextCodec *Codec;
+ /** decodes the chars to unicode */
+ QTextDecoder *Decoder;
+ /** encodes the chars from unicode */
+ QTextEncoder *Encoder;
+ /** */
+ mutable QString Name;
+
+ static QStringList CodecNames;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/controller/Makefile.am b/khexedit/lib/controller/Makefile.am
new file mode 100644
index 0000000..5fd894b
--- /dev/null
+++ b/khexedit/lib/controller/Makefile.am
@@ -0,0 +1,12 @@
+INCLUDES = -I$(srcdir)/.. $(all_includes)
+
+METASOURCES = AUTO
+
+#
+noinst_LTLIBRARIES = libkcontroller.la
+libkcontroller_la_SOURCES = kcontroller.cpp ktabcontroller.cpp knavigator.cpp \
+ keditor.cpp kvalueeditor.cpp kchareditor.cpp
+
+# no public API
+noinst_HEADERS = kcontroller.h ktabcontroller.h knavigator.h \
+ keditor.h kvalueeditor.h kchareditor.h
diff --git a/khexedit/lib/controller/kchareditor.cpp b/khexedit/lib/controller/kchareditor.cpp
new file mode 100644
index 0000000..5b48fc6
--- /dev/null
+++ b/khexedit/lib/controller/kchareditor.cpp
@@ -0,0 +1,58 @@
+/***************************************************************************
+ kchareditor.cpp - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qevent.h>
+// lib specific
+#include "kcharcolumn.h"
+#include "kcharcodec.h"
+#include "khexedit.h"
+#include "kchareditor.h"
+
+
+using namespace KHE;
+
+
+KCharEditor::KCharEditor( KCharColumn *CC, KBufferCursor *BC, KHexEdit *HE, KController *P )
+ : KEditor( BC, HE, P ),
+ CharColumn( CC )
+{
+}
+
+
+bool KCharEditor::handleKeyPress( QKeyEvent *KeyEvent )
+{
+ bool KeyUsed = false;
+ // some input that should be inserted?
+ if( KeyEvent->text().length() > 0
+ && !(KeyEvent->state()&( Qt::ControlButton | Qt::AltButton | Qt::MetaButton )) )
+ {
+ QChar C = KeyEvent->text()[0];
+ if( C.isPrint() )
+ {
+ QByteArray D( 1 );
+ if( CharColumn->codec()->encode(&D[0],C) )
+ {
+ // clearUndoRedoInfo = false;
+ HexEdit->insert( D );
+ KeyUsed = true;
+ }
+ }
+ }
+
+ return KeyUsed ? true : KEditor::handleKeyPress(KeyEvent);
+}
diff --git a/khexedit/lib/controller/kchareditor.h b/khexedit/lib/controller/kchareditor.h
new file mode 100644
index 0000000..74c3d8d
--- /dev/null
+++ b/khexedit/lib/controller/kchareditor.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ kchareditor.h - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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_KCHAREDITOR_H
+#define KHE_KCHAREDITOR_H
+
+// lib specific
+#include "keditor.h"
+
+namespace KHE
+{
+
+class KCharColumn;
+
+class KCharEditor : public KEditor
+{
+ public:
+ KCharEditor( KCharColumn *CC, KBufferCursor *BC, KHexEdit *HE, KController *P );
+
+ public: // KEditor API
+ virtual bool handleKeyPress( QKeyEvent *KeyEvent );
+
+ protected:
+ KCharColumn *CharColumn;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/controller/kcontroller.cpp b/khexedit/lib/controller/kcontroller.cpp
new file mode 100644
index 0000000..490da93
--- /dev/null
+++ b/khexedit/lib/controller/kcontroller.cpp
@@ -0,0 +1,34 @@
+/***************************************************************************
+ kcontroller.cpp - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+
+// lib specific
+#include "khexedit.h"
+#include "kcontroller.h"
+
+
+using namespace KHE;
+
+KController::KController( KHexEdit* HE, KController *P )
+ : Parent( P ), HexEdit( HE )
+{
+}
+
+bool KController::handleKeyPress( QKeyEvent *KeyEvent )
+{
+ return Parent ? Parent->handleKeyPress( KeyEvent ) : false;
+}
diff --git a/khexedit/lib/controller/kcontroller.h b/khexedit/lib/controller/kcontroller.h
new file mode 100644
index 0000000..daeb0d5
--- /dev/null
+++ b/khexedit/lib/controller/kcontroller.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ kcontroller.h - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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_KCONTROLLER_H
+#define KHE_KCONTROLLER_H
+
+
+class QKeyEvent;
+
+namespace KHE
+{
+
+class KHexEdit;
+
+class KController
+{
+ protected:
+ KController( KHexEdit *HE, KController *P );
+
+ public: // KController API
+ virtual bool handleKeyPress( QKeyEvent *KeyEvent );
+
+ protected:
+ KController *Parent;
+ KHexEdit *HexEdit;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/controller/keditor.cpp b/khexedit/lib/controller/keditor.cpp
new file mode 100644
index 0000000..7d4e92f
--- /dev/null
+++ b/khexedit/lib/controller/keditor.cpp
@@ -0,0 +1,197 @@
+/***************************************************************************
+ keditor.cpp - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+
+// lib specific
+#include "kdatabuffer.h"
+#include "kbufferranges.h"
+#include "kbufferlayout.h"
+#include "kbuffercursor.h"
+#include "kwordbufferservice.h"
+#include "khexedit.h"
+#include "keditor.h"
+
+
+using namespace KHE;
+
+KEditor::KEditor( KBufferCursor *BC, KHexEdit* HE, KController *P )
+ : KController( HE, P ),
+ BufferCursor( BC )
+{
+}
+
+
+bool KEditor::handleKeyPress( QKeyEvent *KeyEvent )
+{
+ bool clearUndoRedoInfo = true;
+ bool ShiftPressed = KeyEvent->state() & Qt::ShiftButton;
+ bool ControlPressed = KeyEvent->state() & Qt::ControlButton;
+ bool AltPressed = KeyEvent->state() & Qt::AltButton;
+
+ bool KeyUsed = true;
+ // we only care for cursor keys and the like, won't hardcode any other keys
+ // we also don't check whether the commands are allowed
+ // as the commands are also available as API so the check has to be done
+ // in each command anyway
+ switch( KeyEvent->key() )
+ {
+ case Qt::Key_Delete:
+ if( ShiftPressed )
+ HexEdit->cut();
+ else if( HexEdit->BufferRanges->hasSelection() )
+ HexEdit->removeSelectedData();
+ else
+ {
+ doEditAction( ControlPressed ? WordDelete : CharDelete );
+ clearUndoRedoInfo = false;
+ }
+ break;
+
+ case Qt::Key_Insert:
+ if( ShiftPressed )
+ HexEdit->paste();
+ else if( ControlPressed )
+ HexEdit->copy();
+ else
+ HexEdit->setOverwriteMode( !HexEdit->OverWrite );
+ break;
+
+ case Qt::Key_Backspace:
+ if( AltPressed )
+ {
+ if( ControlPressed )
+ break;
+ else if( ShiftPressed )
+ {
+// HexEdit->redo();
+ break;
+ }
+ else
+ {
+// HexEdit->undo();
+ break;
+ }
+ }
+ else if( HexEdit->BufferRanges->hasSelection() )
+ {
+ HexEdit->removeSelectedData();
+ break;
+ }
+
+ doEditAction( ControlPressed ? WordBackspace : CharBackspace );
+ clearUndoRedoInfo = false;
+ break;
+ case Qt::Key_F16: // "Copy" key on Sun keyboards
+ HexEdit->copy();
+ break;
+ case Qt::Key_F18: // "Paste" key on Sun keyboards
+ HexEdit->paste();
+ break;
+ case Qt::Key_F20: // "Cut" key on Sun keyboards
+ HexEdit->cut();
+ break;
+
+ default:
+ KeyUsed = false;
+ }
+
+// if( clearUndoRedoInfo )
+// clearUndoRedo();
+// changeIntervalTimer->start( 100, true );
+
+ return KeyUsed ? true : KController::handleKeyPress(KeyEvent);
+}
+
+
+
+void KEditor::doEditAction( KEditAction Action )
+{
+ KSection ChangedRange;
+
+ HexEdit->pauseCursor( true );
+
+ switch( Action )
+ {
+ case CharDelete:
+ if( !HexEdit->OverWrite )
+ {
+ int Index = BufferCursor->realIndex();
+ if( Index < HexEdit->BufferLayout->length() )
+ {
+ ChangedRange = HexEdit->removeData( KSection(Index,1,false) );
+ if( Index == HexEdit->BufferLayout->length() )
+ BufferCursor->gotoEnd();
+ }
+ }
+ break;
+
+ case WordDelete: // kills data until the start of the next word
+ if( !HexEdit->OverWrite )
+ {
+ int Index = BufferCursor->realIndex();
+ if( Index < HexEdit->BufferLayout->length() )
+ {
+ KWordBufferService WBS( HexEdit->DataBuffer, HexEdit->Codec );
+ int End = WBS.indexOfBeforeNextWordStart( Index );
+ ChangedRange = HexEdit->removeData( KSection(Index,End) );
+ if( Index == HexEdit->BufferLayout->length() )
+ BufferCursor->gotoEnd();
+ }
+ }
+ break;
+
+ case CharBackspace:
+ if( HexEdit->OverWrite )
+ BufferCursor->gotoPreviousByte();
+ else
+ {
+ int DeleteIndex = BufferCursor->realIndex() - 1;
+ if( DeleteIndex >= 0 )
+ {
+ ChangedRange = HexEdit->removeData( KSection(DeleteIndex,1,false) );
+ if( DeleteIndex == HexEdit->BufferLayout->length() )
+ BufferCursor->gotoEnd();
+ else
+ BufferCursor->gotoPreviousByte();
+ }
+ }
+ break;
+ case WordBackspace:
+ {
+ int LeftIndex = BufferCursor->realIndex() - 1;
+ if( LeftIndex >= 0 )
+ {
+ KWordBufferService WBS( HexEdit->DataBuffer, HexEdit->Codec );
+ int WordStart = WBS.indexOfPreviousWordStart( LeftIndex );
+ if( !HexEdit->OverWrite )
+ ChangedRange = HexEdit->removeData( KSection(WordStart,LeftIndex) );
+ if( WordStart == HexEdit->BufferLayout->length() )
+ BufferCursor->gotoEnd();
+ else
+ BufferCursor->gotoIndex(WordStart);
+ }
+ }
+ }
+
+ HexEdit->repaintChanged();
+ HexEdit->ensureCursorVisible();
+
+ HexEdit->unpauseCursor();
+
+ emit HexEdit->cursorPositionChanged( BufferCursor->index() );
+ if( ChangedRange.isValid() ) emit HexEdit->bufferChanged( ChangedRange.start(), ChangedRange.end() );
+}
diff --git a/khexedit/lib/controller/keditor.h b/khexedit/lib/controller/keditor.h
new file mode 100644
index 0000000..dc2b0fd
--- /dev/null
+++ b/khexedit/lib/controller/keditor.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ keditor.h - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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_KEDITOR_H
+#define KHE_KEDITOR_H
+
+
+// lib specific
+#include "kcontroller.h"
+
+
+namespace KHE
+{
+
+class KBufferCursor;
+
+class KEditor : public KController
+{
+ protected:
+ enum KEditAction { CharDelete, WordDelete, CharBackspace, WordBackspace };
+
+ protected:
+ KEditor( KBufferCursor *BC, KHexEdit *HE, KController *P );
+
+ public: // API
+ virtual bool handleKeyPress( QKeyEvent *KeyEvent );
+
+ protected:
+ /** executes keyboard Action \a Action. This is normally called by a key event handler. */
+ void doEditAction( KEditAction Action );
+
+ protected:
+ KBufferCursor *BufferCursor;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/controller/knavigator.cpp b/khexedit/lib/controller/knavigator.cpp
new file mode 100644
index 0000000..51c8048
--- /dev/null
+++ b/khexedit/lib/controller/knavigator.cpp
@@ -0,0 +1,142 @@
+/***************************************************************************
+ knavigator.cpp - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+
+// qt specific
+#include <qevent.h>
+// lib specific
+#include "kdatabuffer.h"
+#include "kbufferranges.h"
+#include "kbuffercursor.h"
+#include "kwordbufferservice.h"
+#include "khexedit.h"
+#include "knavigator.h"
+
+
+using namespace KHE;
+
+KNavigator::KNavigator( KHexEdit* HE, KController *P )
+ : KController( HE, P )
+{
+}
+
+bool KNavigator::handleKeyPress( QKeyEvent *KeyEvent )
+{
+ bool KeyUsed = true;
+
+ //bool clearUndoRedoInfo = true;
+ bool ShiftPressed = KeyEvent->state() & Qt::ShiftButton;
+ bool ControlPressed = KeyEvent->state() & Qt::ControlButton;
+ //bool AltPressed = KeyEvent->state() & AltButton;
+
+ // we only care for cursor keys and the like, won't hardcode any other keys
+ // we also don't check whether the commands are allowed
+ // as the commands are also available as API so the check has to be done
+ // in each command anyway
+ switch( KeyEvent->key() )
+ {
+ case Qt::Key_Left:
+ moveCursor( ControlPressed ? MoveWordBackward : MoveBackward, ShiftPressed );
+ break;
+ case Qt::Key_Right:
+ moveCursor( ControlPressed ? MoveWordForward : MoveForward, ShiftPressed );
+ break;
+ case Qt::Key_Up:
+ moveCursor( ControlPressed ? MovePgUp : MoveUp, ShiftPressed );
+ break;
+ case Qt::Key_Down:
+ moveCursor( ControlPressed ? MovePgDown : MoveDown, ShiftPressed );
+ break;
+ case Qt::Key_Home:
+ moveCursor( ControlPressed ? MoveHome : MoveLineStart, ShiftPressed );
+ break;
+ case Qt::Key_End:
+ moveCursor( ControlPressed ? MoveEnd : MoveLineEnd, ShiftPressed );
+ break;
+ case Qt::Key_Prior:
+ moveCursor( MovePgUp, ShiftPressed );
+ break;
+ case Qt::Key_Next:
+ moveCursor( MovePgDown, ShiftPressed );
+ break;
+
+ default:
+ KeyUsed = false;
+ }
+
+ return KeyUsed ? true : KController::handleKeyPress(KeyEvent);
+}
+
+
+void KNavigator::moveCursor( KMoveAction Action, bool Select )
+{
+ HexEdit->pauseCursor( true );
+
+ KBufferCursor *BufferCursor = HexEdit->BufferCursor;
+ KBufferRanges *BufferRanges = HexEdit->BufferRanges;
+
+ if( Select )
+ {
+ if( !BufferRanges->selectionStarted() )
+ BufferRanges->setSelectionStart( BufferCursor->realIndex() );
+ }
+ else
+ BufferRanges->removeSelection();
+
+ HexEdit->resetInputContext();
+ switch( Action )
+ {
+ case MoveBackward: BufferCursor->gotoPreviousByte(); break;
+ case MoveWordBackward: {
+ KWordBufferService WBS( HexEdit->DataBuffer, HexEdit->Codec );
+ int NewIndex = WBS.indexOfPreviousWordStart( BufferCursor->realIndex() );
+ BufferCursor->gotoIndex( NewIndex );
+ }
+ break;
+ case MoveForward: BufferCursor->gotoNextByte(); break;
+ case MoveWordForward: {
+ KWordBufferService WBS( HexEdit->DataBuffer, HexEdit->Codec );
+ int NewIndex = WBS.indexOfNextWordStart( BufferCursor->realIndex() );
+ BufferCursor->gotoCIndex( NewIndex );
+ }
+ break;
+ case MoveUp: BufferCursor->gotoUp(); break;
+ case MovePgUp: BufferCursor->gotoPageUp(); break;
+ case MoveDown: BufferCursor->gotoDown(); break;
+ case MovePgDown: BufferCursor->gotoPageDown(); break;
+ case MoveLineStart: BufferCursor->gotoLineStart(); break;
+ case MoveHome: BufferCursor->gotoStart(); break;
+ case MoveLineEnd: BufferCursor->gotoLineEnd(); break;
+ case MoveEnd: BufferCursor->gotoEnd(); break;
+ }
+
+ if( Select )
+ BufferRanges->setSelectionEnd( BufferCursor->realIndex() );
+
+ HexEdit->repaintChanged();
+ HexEdit->ensureCursorVisible();
+
+ HexEdit->unpauseCursor();
+
+ if( BufferRanges->isModified() )
+ {
+ if( !HexEdit->isOverwriteMode() ) emit HexEdit->cutAvailable( BufferRanges->hasSelection() );
+ emit HexEdit->copyAvailable( BufferRanges->hasSelection() );
+ KSection Selection = BufferRanges->selection();
+ emit HexEdit->selectionChanged( Selection.start(), Selection.end() );
+ }
+}
diff --git a/khexedit/lib/controller/knavigator.h b/khexedit/lib/controller/knavigator.h
new file mode 100644
index 0000000..4615419
--- /dev/null
+++ b/khexedit/lib/controller/knavigator.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+ knavigator.h - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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_KNAVIGATOR_H
+#define KHE_KNAVIGATOR_H
+
+// lib specific
+#include "kcontroller.h"
+
+namespace KHE
+{
+
+class KNavigator : public KController
+{
+ protected:
+ enum KMoveAction { MoveBackward, MoveWordBackward, MoveForward, MoveWordForward,
+ MoveUp, MovePgUp, MoveDown, MovePgDown,
+ MoveLineStart, MoveHome, MoveLineEnd, MoveEnd };
+ public:
+ KNavigator( KHexEdit *HE, KController *P );
+
+ public: // KEditor API
+ virtual bool handleKeyPress( QKeyEvent *KeyEvent );
+
+ protected:
+ /** moves the cursor according to the action, handles all drawing */
+ void moveCursor( KMoveAction Action, bool Select );
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/controller/ktabcontroller.cpp b/khexedit/lib/controller/ktabcontroller.cpp
new file mode 100644
index 0000000..76c3051
--- /dev/null
+++ b/khexedit/lib/controller/ktabcontroller.cpp
@@ -0,0 +1,70 @@
+/***************************************************************************
+ ktabcontroller.cpp - description
+ -------------------
+ begin : So Dez 5 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qevent.h>
+// lib specific
+#include "kvaluecolumn.h"
+#include "kcharcolumn.h"
+#include "khexedit.h"
+#include "ktabcontroller.h"
+
+
+using namespace KHE;
+
+KTabController::KTabController( KHexEdit* HE, KController *P )
+ : KController( HE, P ),
+ TabChangesFocus( false )
+{
+}
+
+
+bool KTabController::handleKeyPress( QKeyEvent *KeyEvent )
+{
+ bool KeyUsed = false;
+
+ bool ShiftPressed = KeyEvent->state() & Qt::ShiftButton;
+
+ if( KeyEvent->key() == Qt::Key_Tab )
+ {
+ // are we in the char column?
+ if( HexEdit->cursorColumn() == KHexEdit::CharColumnId )
+ {
+ // in last column we care about tab changes focus
+ if( HexEdit->ValueColumn->isVisible() && (!TabChangesFocus || ShiftPressed) )
+ {
+ HexEdit->setCursorColumn( KHexEdit::ValueColumnId );
+ KeyUsed = true;
+ }
+ }
+ // value column then
+ else
+ {
+ if( HexEdit->CharColumn->isVisible() )
+ {
+ // in last column we care about tab changes focus
+ if( HexEdit->CharColumn->isVisible() && (!TabChangesFocus || !ShiftPressed) )
+ {
+ HexEdit->setCursorColumn( KHexEdit::CharColumnId );
+ KeyUsed = true;
+ }
+ }
+ }
+ }
+
+ return KeyUsed ? true : KController::handleKeyPress(KeyEvent);
+}
diff --git a/khexedit/lib/controller/ktabcontroller.h b/khexedit/lib/controller/ktabcontroller.h
new file mode 100644
index 0000000..e1898b4
--- /dev/null
+++ b/khexedit/lib/controller/ktabcontroller.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ ktabcontroller.h - description
+ -------------------
+ begin : So Dez 5 2004
+ copyright : (C) 2004 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_KTABCONTROLLER_H
+#define KHE_KTABCONTROLLER_H
+
+
+// lib specific
+#include "kcontroller.h"
+
+
+namespace KHE
+{
+
+class KTabController : public KController
+{
+ public:
+ KTabController( KHexEdit *HE, KController *P );
+
+ public: // API
+ virtual bool handleKeyPress( QKeyEvent *KeyEvent );
+
+ public:
+ bool tabChangesFocus() const;
+ void setTabChangesFocus( bool TCF );
+
+ protected:
+ /** flag if tab key should be ignored */
+ bool TabChangesFocus:1;
+};
+
+
+inline bool KTabController::tabChangesFocus() const { return TabChangesFocus; }
+inline void KTabController::setTabChangesFocus( bool TCF ) { TabChangesFocus = TCF; }
+
+}
+
+#endif
diff --git a/khexedit/lib/controller/kvalueeditor.cpp b/khexedit/lib/controller/kvalueeditor.cpp
new file mode 100644
index 0000000..ebfb589
--- /dev/null
+++ b/khexedit/lib/controller/kvalueeditor.cpp
@@ -0,0 +1,226 @@
+/***************************************************************************
+ kvalueeditor.cpp - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qevent.h>
+// lib specific
+#include "kvaluecolumn.h"
+#include "kbufferranges.h"
+#include "kbuffercursor.h"
+#include "khexedit.h"
+#include "kvalueeditor.h"
+
+
+using namespace KHE;
+
+KValueEditor::KValueEditor( KValueColumn *VC, KBufferCursor *BC, KHexEdit* HE, KController *P )
+ : KEditor( BC, HE, P ),
+ ValueColumn( VC ),
+ InEditMode( false ),
+ EditModeByInsert( false )
+{
+}
+
+
+bool KValueEditor::handleKeyPress( QKeyEvent *KeyEvent )
+{
+ bool KeyUsed = true;
+
+ // TODO: for now we don't touch it if there are selections
+ if( !HexEdit->BufferRanges->hasSelection() )
+ {
+ //
+ switch( KeyEvent->key() )
+ {
+ case Qt::Key_Plus:
+ doValueEditAction( IncValue );
+ break;
+ case Qt::Key_Minus:
+ doValueEditAction( DecValue );
+ break;
+ case Qt::Key_Space:
+ if( !InEditMode )
+ {
+ KeyUsed = false;
+ break;
+ }
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ doValueEditAction( InEditMode?LeaveValue:EnterValue );
+ break;
+ case Qt::Key_Escape:
+ if( InEditMode )
+ doValueEditAction( CancelValue );
+ else
+ KeyUsed = false;
+ break;
+ case Qt::Key_Backspace:
+ if( InEditMode )
+ doValueEditAction( ValueBackspace );
+ else
+ KeyUsed = false;
+ break;
+ default:
+ // is plain char?
+ if( KeyEvent->text().length() > 0
+ && ( !(KeyEvent->state()&( Qt::ControlButton | Qt::AltButton | Qt::MetaButton )) ) )
+ {
+ QChar C = KeyEvent->text()[0];
+ // no usable char?
+ if( !C.isLetterOrNumber() )
+ {
+ KeyUsed = false;
+ break;
+ }
+ int Input = C.latin1();
+
+ if( InEditMode )
+ doValueEditAction( ValueAppend, Input );
+ else
+ {
+ unsigned char InputValue = 0;
+ const KByteCodec *ByteCodec = ValueColumn->byteCodec();
+ // valid digit?
+ if( ByteCodec->appendDigit(&InputValue,Input) )
+ {
+ if( HexEdit->OverWrite )
+ doValueEditAction( ValueEdit, InputValue );
+ else
+ {
+ int Index = BufferCursor->realIndex();
+ if( HexEdit->DataBuffer->insert(Index,(char*)&InputValue,1) > 0 )
+ {
+ HexEdit->pauseCursor();
+ HexEdit->updateLength();
+
+ InEditMode = true;
+ EditModeByInsert = true;
+ OldValue = EditValue = InputValue;
+ ByteCodec->encode( ByteBuffer, 0, EditValue );
+
+ BufferCursor->gotoRealIndex();
+ KSection ChangedRange( Index,HexEdit->DataBuffer->size()-1 );
+ HexEdit->BufferRanges->addChangedRange( ChangedRange );
+ HexEdit->repaintChanged();
+ HexEdit->ensureCursorVisible();
+ HexEdit->unpauseCursor();
+ HexEdit->updateCursor();
+ emit HexEdit->bufferChanged( ChangedRange.start(), ChangedRange.end() );
+ }
+ }
+ }
+ }
+ }
+ else
+ KeyUsed = false;
+ }
+ }
+ else
+ KeyUsed = false;
+
+ return KeyUsed ? true : KEditor::handleKeyPress(KeyEvent);
+}
+
+
+void KValueEditor::doValueEditAction( KValueEditAction Action, int Input )
+{
+ // we are not yet in edit mode?
+ if( !InEditMode )
+ {
+ int ValidIndex = BufferCursor->validIndex();
+ // no valid cursor position?
+ if( ValidIndex == -1 || (!HexEdit->OverWrite && Input == -1) || BufferCursor->isBehind() )
+ return;
+
+ InEditMode = true;
+ EditModeByInsert = false; // default, to be overwritten if so
+
+ // save old value
+ OldValue = EditValue = (unsigned char)HexEdit->DataBuffer->datum(ValidIndex);
+ }
+
+ const KByteCodec *ByteCodec = ValueColumn->byteCodec();
+ //
+ unsigned char NewValue = EditValue;
+ bool StayInEditMode = true;
+ bool MoveToNext = false;
+
+ switch( Action )
+ {
+ case ValueEdit:
+ NewValue = Input;
+ EditValue = NewValue^255; // force update
+ EditModeByInsert = true;
+ break;
+ case ValueBackspace:
+ if( NewValue > 0 )
+ ByteCodec->removeLastDigit( &NewValue );
+ break;
+ case EnterValue:
+ EditValue ^= 255; // force update
+ break;
+ case IncValue:
+ if( NewValue < 255 )
+ ++NewValue;
+ break;
+ case DecValue:
+ if( NewValue > 0 )
+ --NewValue;
+ break;
+ case ValueAppend:
+ if( ByteCodec->appendDigit(&NewValue,Input) )
+ if( EditModeByInsert && NewValue >= ByteCodec->digitsFilledLimit() )
+ {
+ StayInEditMode = false;
+ MoveToNext = true;
+ }
+ break;
+ case LeaveValue:
+ StayInEditMode = false;
+ MoveToNext = EditModeByInsert;
+ break;
+ case CancelValue:
+ NewValue = OldValue;
+ StayInEditMode = false;
+ break;
+ }
+
+ bool Changed = (NewValue != EditValue);
+ int Index = BufferCursor->index();
+ if( Changed )
+ {
+ // sync value
+ EditValue = NewValue;
+ ByteCodec->encode( ByteBuffer, 0, EditValue );
+
+ HexEdit->DataBuffer->replace( Index, 1, (char*)&EditValue, 1 );
+ }
+
+ HexEdit->updateCursor();
+
+ if( !StayInEditMode )
+ {
+ HexEdit->pauseCursor();
+ InEditMode = false;
+ if( MoveToNext )
+ BufferCursor->gotoNextByte();
+ HexEdit->unpauseCursor();
+ }
+
+ if( Changed )
+ if( Action != EnterValue ) emit HexEdit->bufferChanged( Index, Index );
+}
diff --git a/khexedit/lib/controller/kvalueeditor.h b/khexedit/lib/controller/kvalueeditor.h
new file mode 100644
index 0000000..496bcde
--- /dev/null
+++ b/khexedit/lib/controller/kvalueeditor.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+ kvalueeditor.h - description
+ -------------------
+ begin : Sa Dez 4 2004
+ copyright : (C) 2004 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_KVALUEEDITOR_H
+#define KHE_KVALUEEDITOR_H
+
+
+// lib specific
+#include "keditor.h"
+
+namespace KHE
+{
+
+class KValueColumn;
+
+
+class KValueEditor: public KEditor
+{
+ protected:
+ enum KValueEditAction
+ { EnterValue, IncValue, DecValue, ValueAppend, ValueEdit, LeaveValue, CancelValue, ValueBackspace };
+
+ public:
+ KValueEditor( KValueColumn *VC, KBufferCursor *BC, KHexEdit *HE, KController *P );
+ virtual ~KValueEditor();
+
+ public: // KEditor API
+ virtual bool handleKeyPress( QKeyEvent *KeyEvent );
+
+ public:
+ void reset();
+
+ public:
+ bool isInEditMode() const;
+
+ protected:
+ /** executes keyboard Action \a Action. This is normally called by a key event handler. */
+ void doValueEditAction( KValueEditAction Action, int Input = -1 );
+
+ public://protected:
+ KValueColumn *ValueColumn;
+ /** flag whether we are in editing mode */
+ bool InEditMode:1;
+ /** flag whether byte edit mode was reached by inserting */
+ bool EditModeByInsert:1;
+ /** */
+ unsigned char EditValue;
+ /** stores the old byte value */
+ unsigned char OldValue;
+ /** buffer with the */
+ QString ByteBuffer;
+};
+
+inline KValueEditor::~KValueEditor() {}
+
+inline bool KValueEditor::isInEditMode() const { return InEditMode; }
+inline void KValueEditor::reset() { InEditMode = false; }
+
+}
+
+#endif
diff --git a/khexedit/lib/helper.h b/khexedit/lib/helper.h
new file mode 100644
index 0000000..600ac5b
--- /dev/null
+++ b/khexedit/lib/helper.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ helper.h - description
+ -------------------
+ begin : Fri Oct 03 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 KHEXEDIT_HELPER
+#define KHEXEDIT_HELPER
+
+// qt specific
+#include <qcolor.h>
+// lib specific
+#include <khechar.h>
+
+// temporary solution until syntax highlighting is implemented
+static inline QColor colorForChar( const KHE::KHEChar Byte )
+{
+ return Byte.isUndefined() ? Qt::yellow : Byte.isPunct() ? Qt::red : Byte.isPrint() ? Qt::black : Qt::blue;
+}
+
+#endif
diff --git a/khexedit/lib/kadds.h b/khexedit/lib/kadds.h
new file mode 100644
index 0000000..77c86f5
--- /dev/null
+++ b/khexedit/lib/kadds.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ kadds.h - description
+ -------------------
+ begin : Die Mai 20 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_KADDS_H
+#define KHE_KADDS_H
+
+namespace KHE
+{
+// some possibly usefull aditions to KDE
+
+// these are to emphasize that measuring unit is pixel and which direction
+typedef int KPixelX;
+typedef int KPixelY;
+
+class KSection;
+
+typedef KSection KPixelXs;
+typedef KSection KPixelYs;
+
+}
+
+#endif
diff --git a/khexedit/lib/kbigbuffer.cpp b/khexedit/lib/kbigbuffer.cpp
new file mode 100644
index 0000000..8505ef7
--- /dev/null
+++ b/khexedit/lib/kbigbuffer.cpp
@@ -0,0 +1,216 @@
+/***************************************************************************
+ kbigbuffer.cpp - description
+ -------------------
+ begin : Mit Jun 02 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. *
+ * *
+ ***************************************************************************/
+
+
+// c specific
+#include <stdlib.h>
+// lib specific
+#include "kbigbuffer.h"
+
+using namespace KHE;
+
+KBigBuffer::KBigBuffer( int NP, int PS )
+ : NoOfUsedPages( NP ),
+ NoOfFreePages( NP ),
+ PageSize( PS ),
+ FirstPage( -1 ),
+ LastPage( -1 ),
+ Size( 0 )
+{
+ IsOpen = false;
+
+// if( !filename.empty() )
+// open(filename);
+}
+
+
+KBigBuffer::~KBigBuffer()
+{
+ if( File.isOpen() )
+ close();
+}
+
+
+
+bool KBigBuffer::prepareRange( KSection /*Range*/ ) const
+{
+ return true;
+}
+
+const char *KBigBuffer::dataSet( KSection /*Section*/ ) const
+{
+ return 0;
+}
+
+
+char KBigBuffer::datum( unsigned int DatumOffset ) const
+{
+// std::cout << "reading datum " << DatumOffset << std::endl;
+ int OffsetInPage = DatumOffset - OffsetOfActualPage;
+ // there shouldn't be any need to check l
+ if( OffsetInPage >= 0 && OffsetInPage < (int)PageSize )
+ return ActualPage[OffsetInPage];
+
+ // load the page
+ unsigned int PageIndex = DatumOffset / PageSize;
+ ensurePageLoaded( PageIndex );
+ return ActualPage[DatumOffset-OffsetOfActualPage];
+}
+
+
+
+
+int KBigBuffer::insert( int /*Pos*/, const char*, int /*Length*/ )
+{
+ return 0;
+}
+
+int KBigBuffer::remove( KSection /*Section*/ )
+{
+ return 0;
+}
+
+unsigned int KBigBuffer::replace( KSection /*Section*/, const char*, unsigned int /*Length*/ )
+{
+ return 0;
+}
+
+int KBigBuffer::fill( char /*FillChar*/, int /*Length*/, unsigned int /*Pos*/ )
+{
+ return 0;
+}
+
+
+int KBigBuffer::move( int /*DestPos*/, KSection /*SourceSection*/ ) { return 0; }
+//int KBigBuffer::find( const char*, int /*Length*/, int /*Pos*/ ) const { return 0; }
+int KBigBuffer::find( const char*/*KeyData*/, int /*Length*/, KSection /*Section*/ ) const { return 0; }
+
+int KBigBuffer::rfind( const char*, int /*Length*/, int /*Pos*/ ) const { return 0; }
+
+
+
+bool KBigBuffer::open( const QString& FileName )
+{
+ // clear old data
+ if( isOpen() && !close() ) // only occurs if close somehow fails.
+ return false;
+
+ File.setName( FileName );
+ if( !File.open(IO_ReadOnly|IO_Raw) )
+ return false;
+
+// std::cout << "loading file " << FileName << std::endl;
+
+ int FileSize = File.size();
+ Size = FileSize;
+
+ // calculate necessary number of pages
+ int NoOfPages = FileSize/PageSize + 1;
+
+ // initialize Page pointers
+ Data.resize( NoOfPages );
+ for( KPageOfChar::iterator D=Data.begin(); D!=Data.end(); ++D )
+ *D = 0;
+
+ FirstPage = LastPage = 0;
+
+ return ensurePageLoaded( 0 );
+}
+
+
+bool KBigBuffer::close()
+{
+ if( !isOpen() )
+ return false;
+
+ File.close();
+
+ if( File.status() == IO_UnspecifiedError )
+ return false;
+
+// std::cout << "closing file " << std::endl;
+
+ // free pages
+ for( KPageOfChar::iterator D=Data.begin(); D!=Data.end(); ++D )
+ delete [] *D;
+
+ FirstPage = LastPage = -1;
+ NoOfFreePages = NoOfUsedPages;
+
+ return true;
+}
+
+
+bool KBigBuffer::ensurePageLoaded( unsigned int PageIndex ) const
+{
+ if( !isOpen() )
+ return false;
+ // page loaded?
+ if( Data[PageIndex] != 0 )
+ {
+ ActualPage = Data[PageIndex];
+ OffsetOfActualPage = PageIndex * PageSize;
+ return true;
+ }
+
+ // no page available?
+ if( NoOfFreePages < 1 )
+ {
+ // free the page which is the furthest away from the page we are loading
+ if( abs(FirstPage-PageIndex) > abs(LastPage-PageIndex) )
+ while( !freePage(FirstPage++) );
+ else
+ while( !freePage(LastPage--) );
+ }
+
+// std::cout << "loading page " << PageIndex << std::endl;
+ // create Page
+ Data[PageIndex] = new char[PageSize];
+ --NoOfFreePages;
+
+ // jump to position and read the page's data in
+ bool Success = File.at( (unsigned long)(PageIndex*PageSize) );
+ if( Success )
+ Success = File.readBlock( Data[PageIndex], PageSize ) > 0;
+
+ if( Success )
+ {
+ // correct bounds
+ if( (int)PageIndex < FirstPage )
+ FirstPage = PageIndex;
+
+ if( (int)PageIndex > LastPage )
+ LastPage = PageIndex;
+
+ ActualPage = Data[PageIndex];
+ OffsetOfActualPage = PageIndex * PageSize;
+ }
+
+ return Success;
+}
+
+
+bool KBigBuffer::freePage( unsigned int PageIndex ) const
+{
+ // check range and if is loaded at all
+ if( (unsigned int)PageIndex >= Data.size() || !Data[PageIndex] )
+ return false;
+// std::cout << "freeing page " << PageIndex << std::endl;
+ delete [] Data[PageIndex];
+ Data[PageIndex] = 0;
+ ++NoOfFreePages;
+ return true;
+}
diff --git a/khexedit/lib/kbigbuffer.h b/khexedit/lib/kbigbuffer.h
new file mode 100644
index 0000000..138e64b
--- /dev/null
+++ b/khexedit/lib/kbigbuffer.h
@@ -0,0 +1,119 @@
+/***************************************************************************
+ kbigbuffer.h - description
+ -------------------
+ begin : Mit Jun 02 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_KBIGBUFFER_H
+#define KHE_KBIGBUFFER_H
+
+// qt specific
+#include <qvaluevector.h>
+#include <qfile.h>
+// lib specific
+#include "kdatabuffer.h"
+#include "khexedit_export.h"
+
+namespace KHE {
+
+/** base class for all Data buffers that are used to display
+ * TODO: think about a way to inform KHexEdit that there has been
+ * a change in the buffer outside. what kind of changes are possible?
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KHEXEDIT_EXPORT KBigBuffer : public KDataBuffer
+{
+ typedef QValueVector<char *> KPageOfChar;
+
+ public:
+ /** default is only 50*4k = 200k memory image */
+ KBigBuffer( int NP = 50, int PS = 4096 );
+ virtual ~KBigBuffer();
+
+ public: // KDataBuffer API
+ virtual bool prepareRange( KSection Range ) const;
+ virtual const char *dataSet( KSection S ) const;
+ virtual char datum( unsigned int Offset ) const;
+ virtual int size() const;
+ virtual bool isReadOnly() const;
+ virtual bool isModified() const;
+
+ virtual int insert( int Pos, const char*, int Length );
+ virtual int remove( KSection S );
+ virtual unsigned int replace( KSection S, const char*, unsigned int InputLength );
+ virtual int move( int DestPos, KSection SourceSection );
+ virtual int fill( char FillChar, int Length = -1, unsigned int Pos = 0 );
+ virtual void setDatum( unsigned int Offset, const char Char );
+
+ virtual void setModified( bool M = true );
+
+ //virtual int find( const char*, int Length, int Pos = 0 ) const;
+ virtual int find( const char*KeyData, int Length, KSection Section ) const;
+ virtual int rfind( const char*, int Length, int Pos = -1 ) const;
+
+/* virtual int find( const QString &expr, bool cs, bool wo, bool forward = true, int *index = 0 ); */
+
+ public:
+ void setReadOnly( bool RO = true );
+ bool isOpen() const;
+ bool open (const QString& filename );
+ bool close();
+
+ protected:
+ bool ensurePageLoaded( unsigned int PageIndex ) const;
+ bool freePage( unsigned int PageIndex ) const;
+
+
+ protected:
+ /** */
+ mutable QFile File;
+ /** */
+ bool ReadOnly:1;
+ bool IsOpen:1;
+ bool AtEOF:1;
+ /** maximum number of pages which could be currently loaded */
+ unsigned int NoOfUsedPages;
+ /** number of actually not used pages (in terms of NoOfUsedPages) */
+ mutable int NoOfFreePages;
+ /** number of bytes in a page */
+ unsigned int PageSize;
+ /** first currently loaded page */
+ mutable int FirstPage;
+ /** last currently loaded page */
+ mutable int LastPage;
+ /** */
+ mutable KPageOfChar Data;
+ /** */
+ unsigned int Size;
+
+ /** current offset */
+ mutable unsigned int OffsetOfActualPage;
+ /** points to the actual page */
+ mutable char* ActualPage;
+};
+
+inline int KBigBuffer::size() const { return Size; }
+inline bool KBigBuffer::isReadOnly() const { return ReadOnly; }
+inline bool KBigBuffer::isModified() const { return false; }
+inline void KBigBuffer::setReadOnly( bool RO ) { ReadOnly = RO; }
+inline void KBigBuffer::setModified( bool ) {}
+
+inline void KBigBuffer::setDatum( unsigned int, const char ) {}
+
+inline bool KBigBuffer::isOpen() const { return File.isOpen(); }
+
+}
+
+#endif
diff --git a/khexedit/lib/kbordercoltextexport.cpp b/khexedit/lib/kbordercoltextexport.cpp
new file mode 100644
index 0000000..d46490f
--- /dev/null
+++ b/khexedit/lib/kbordercoltextexport.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ kbordercoltextexport.cpp - description
+ -------------------
+ begin : Sam Aug 30 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qstring.h>
+// lib specific
+#include "kbordercoltextexport.h"
+
+
+using namespace KHE;
+
+static const uint BorderColumnTEWidth = 3;
+
+
+int KBorderColTextExport::charsPerLine() const
+{
+ return BorderColumnTEWidth;
+}
+
+void KBorderColTextExport::printFirstLine( QString &T, int /*Line*/ ) const
+{
+ print( T );
+}
+
+void KBorderColTextExport::printNextLine( QString &T ) const
+{
+ print( T );
+}
+
+void KBorderColTextExport::print( QString &T ) const
+{
+ T.append( " | " );
+}
diff --git a/khexedit/lib/kbordercoltextexport.h b/khexedit/lib/kbordercoltextexport.h
new file mode 100644
index 0000000..4103f0b
--- /dev/null
+++ b/khexedit/lib/kbordercoltextexport.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ kbordercoltextexport.h - description
+ -------------------
+ begin : Sam Aug 30 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_KBORDERCOLTEXTEXPORT_H
+#define KHE_KBORDERCOLTEXTEXPORT_H
+
+#include "kcoltextexport.h"
+
+namespace KHE
+{
+
+class KBorderColTextExport : public KColTextExport
+{
+ public: // API
+ void printFirstLine( QString &T, int Line ) const;
+ void printNextLine( QString &T) const;
+ /** tells how much chars per line are needed */
+ int charsPerLine() const ;
+
+ protected:
+ void print( QString &T ) const;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kbordercolumn.cpp b/khexedit/lib/kbordercolumn.cpp
new file mode 100644
index 0000000..c590246
--- /dev/null
+++ b/khexedit/lib/kbordercolumn.cpp
@@ -0,0 +1,82 @@
+/***************************************************************************
+ kbordercolumn.cpp - description
+ -------------------
+ begin : Mit Mai 21 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qpainter.h>
+#include <qstyle.h>
+// lib specific
+#include "kcolumnsview.h"
+#include "kbordercolumn.h"
+
+
+using namespace KHE;
+
+static const KPixelX DefaultWidth = 9;
+static const KPixelX LineX = DefaultWidth / 2;
+
+
+KBorderColumn::KBorderColumn( KColumnsView *V, bool M )
+ : KColumn( V ),
+ Middle( M )
+{
+ setWidth( M?DefaultWidth:LineX-1 );
+}
+
+KBorderColumn::~KBorderColumn()
+{
+}
+
+
+void KBorderColumn::paintLine( QPainter *P )
+{
+ if( LineHeight > 0 )
+ {
+ KColumn::paintBlankLine( P );
+
+ if( Middle )
+ {
+ int GridColor = View->style().styleHint( QStyle::SH_Table_GridLineColor, View );
+ P->setPen( GridColor != -1 ? (QRgb)GridColor : View->colorGroup().mid() );
+ P->drawLine( LineX, 0, LineX, LineHeight-1 ) ;
+ }
+ }
+}
+
+
+void KBorderColumn::paintFirstLine( QPainter *P, KPixelXs , int )
+{
+ paintLine( P );
+}
+
+
+void KBorderColumn::paintNextLine( QPainter *P )
+{
+ paintLine( P );
+}
+
+void KBorderColumn::paintEmptyColumn( QPainter *P, KPixelXs Xs, KPixelYs Ys )
+{
+ KColumn::paintEmptyColumn( P,Xs,Ys );
+
+ KPixelX LX = x() + LineX;
+ if( Middle && Xs.includes(LX) )
+ {
+ int GridColor = View->style().styleHint( QStyle::SH_Table_GridLineColor, View );
+ P->setPen( GridColor != -1 ? (QRgb)GridColor : View->colorGroup().mid() );
+ P->drawLine( LX, Ys.start(), LX, Ys.end() ) ;
+ }
+}
diff --git a/khexedit/lib/kbordercolumn.h b/khexedit/lib/kbordercolumn.h
new file mode 100644
index 0000000..0a72c05
--- /dev/null
+++ b/khexedit/lib/kbordercolumn.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ kbordercolumn.h - description
+ -------------------
+ begin : Mit Mai 21 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_KBORDERCOLUMN_H
+#define KHE_KBORDERCOLUMN_H
+
+#include "kcolumn.h"
+
+namespace KHE
+{
+
+/** column that does nothing but draw a vertical line in the middle of the column
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KBorderColumn : public KColumn
+{
+ public:
+ KBorderColumn( KColumnsView *V, bool M );
+ ~KBorderColumn();
+
+ public: // KColumn-API
+ virtual void paintFirstLine( QPainter *P, KPixelXs Xs, int FirstLine );
+ virtual void paintNextLine( QPainter *P );
+ virtual void paintEmptyColumn( QPainter *P, KPixelXs Xs, KPixelYs Ys );
+
+ protected:
+ virtual void paintLine( QPainter *P );
+
+ protected:
+ /** true if we are between two columns and should show a line */
+ bool Middle;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kbuffercoltextexport.cpp b/khexedit/lib/kbuffercoltextexport.cpp
new file mode 100644
index 0000000..a4ee91f
--- /dev/null
+++ b/khexedit/lib/kbuffercoltextexport.cpp
@@ -0,0 +1,108 @@
+/***************************************************************************
+ kbuffercoltextexport.cpp - description
+ -------------------
+ begin : Sam Aug 30 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. *
+ * *
+ ***************************************************************************/
+
+
+// c specific
+#include <string.h>
+// lib specific
+#include "kbuffercolumn.h"
+#include "kbufferlayout.h"
+#include "kbuffercoltextexport.h"
+
+
+using namespace KHE;
+
+static const int DefaultTEByteSpacingWidth = 1;
+static const int TEGroupSpacingWidth = 3;
+
+QString KBufferColTextExport::whiteSpace( uint s )
+{
+ return QString().fill( ' ', s );
+}
+
+KBufferColTextExport::KBufferColTextExport( const KBufferColumn* BufferColumn, const char *D,
+ KCoordRange CR, int ByteWidth )
+ : Data( D ),
+ CoordRange( CR )
+{
+ NoOfBytesPerLine = BufferColumn->layout()->noOfBytesPerLine();
+ Pos = new int[NoOfBytesPerLine];
+
+ // TODO: remove this hack and make it more general
+ int ByteSpacingWidth = BufferColumn->byteSpacingWidth();
+ if( ByteSpacingWidth > 0 )
+ ByteSpacingWidth = DefaultTEByteSpacingWidth;
+
+ int SpacingTrigger = BufferColumn->noOfGroupedBytes()-1;
+ if( SpacingTrigger < 0 )
+ SpacingTrigger = NoOfBytesPerLine; // ensures to never trigger the group spacing
+
+ int N = 0;
+ int p = 0;
+ int gs = 0;
+ int *P = Pos;
+ for( ; P<&Pos[NoOfBytesPerLine]; ++P, ++p, ++gs )
+ {
+ *P = N;
+ N += ByteWidth;
+
+ // is there a space behind the actual byte (if it is not the last)?
+ if( gs == SpacingTrigger )
+ {
+ N += TEGroupSpacingWidth;
+ gs = -1;
+ }
+ else
+ N += ByteSpacingWidth;
+ }
+ N -= (gs==0)?TEGroupSpacingWidth:ByteSpacingWidth;
+
+ NoOfCharsPerLine = N;
+}
+
+
+KBufferColTextExport::~KBufferColTextExport()
+{
+ delete [] Pos;
+}
+
+
+int KBufferColTextExport::charsPerLine() const
+{
+ return NoOfCharsPerLine;
+}
+
+
+void KBufferColTextExport::printFirstLine( QString &T, int Line ) const
+{
+ PrintLine = Line;
+ PrintData = Data;
+ print( T );
+}
+
+
+void KBufferColTextExport::printNextLine( QString &T ) const
+{
+ print( T );
+}
+
+
+void KBufferColTextExport::print( QString &T ) const
+{
+ T.append( whiteSpace(NoOfCharsPerLine) );
+ ++PrintLine;
+}
+
diff --git a/khexedit/lib/kbuffercoltextexport.h b/khexedit/lib/kbuffercoltextexport.h
new file mode 100644
index 0000000..6cb161d
--- /dev/null
+++ b/khexedit/lib/kbuffercoltextexport.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ kbuffercoltextexport.h - description
+ -------------------
+ begin : Sam Aug 30 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_KBUFFERCOLTEXTEXPORT_H
+#define KHE_KBUFFERCOLTEXTEXPORT_H
+
+// qt specific
+#include <qstring.h>
+// lib specific
+#include "kcoltextexport.h"
+#include "kcoordrange.h"
+
+
+namespace KHE
+{
+
+class KBufferColumn;
+
+
+class KBufferColTextExport : public KColTextExport
+{
+ public:
+ KBufferColTextExport( const KBufferColumn* BF, const char *D, KCoordRange CR, int BytesWidth );
+ virtual ~KBufferColTextExport();
+
+ public: // API
+ void printFirstLine( QString &T, int Line ) const;
+ void printNextLine( QString &T ) const;
+ /** tells how much chars per line are needed */
+ int charsPerLine() const;
+
+
+ protected: // API to be reimplemented by subclasses
+ virtual void print( QString &T ) const;
+
+
+ protected:
+ static QString whiteSpace( uint s );
+
+ protected:
+ const char *Data;
+ KCoordRange CoordRange;
+
+ int NoOfBytesPerLine;
+
+ /** Line to print */
+ mutable int PrintLine;
+ /** Data to print */
+ mutable const char *PrintData;
+
+ /** buffered value of how many chars a line needs */
+ int NoOfCharsPerLine;
+ // positions where to paint the
+ int *Pos;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kbuffercolumn.cpp b/khexedit/lib/kbuffercolumn.cpp
new file mode 100644
index 0000000..4291e00
--- /dev/null
+++ b/khexedit/lib/kbuffercolumn.cpp
@@ -0,0 +1,700 @@
+/***************************************************************************
+ kbuffercolumn.cpp - description
+ -------------------
+ begin : Mit Mai 14 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. *
+ * *
+ ***************************************************************************/
+
+
+//#include <kdebug.h>
+
+// qt specific
+#include <qpainter.h>
+// lib specific
+#include "kcolumnsview.h"
+#include "kbuffercursor.h"
+#include "kbuffercolumn.h"
+#include "kbufferlayout.h"
+#include "kbufferranges.h"
+#include "helper.h"
+#include "kcharcodec.h"
+
+using namespace KHE;
+
+static const unsigned int StartsBefore = 1;
+static const unsigned int EndsLater = 2;
+static const char EmptyByte = ' ';
+
+static const KPixelX DefaultCursorWidth = 2;
+static const KPixelX DefaultByteSpacingWidth = 3;
+static const KPixelX DefaultGroupSpacingWidth = 9;
+static const int DefaultNoOfGroupedBytes = 4;
+
+KBufferColumn::KBufferColumn( KColumnsView *CV, KDataBuffer *B, KBufferLayout *L, KBufferRanges *R )
+ : KColumn( CV ),
+ Buffer( B ),
+ Layout( L ),
+ Ranges( R ),
+ DigitWidth( 0 ),
+ DigitBaseLine( 0 ),
+ VerticalGrid( false ),
+ ByteWidth( 0 ),
+ ByteSpacingWidth( DefaultByteSpacingWidth ),
+ GroupSpacingWidth( DefaultGroupSpacingWidth ),
+ NoOfGroupedBytes( DefaultNoOfGroupedBytes ),
+ PosX( 0L ),
+ PosRightX( 0L ),
+ LastPos( 0 )
+{
+}
+
+
+KBufferColumn::~KBufferColumn()
+{
+ delete [] PosX;
+ delete [] PosRightX;
+}
+
+
+
+void KBufferColumn::set( KDataBuffer *B )
+{
+ Buffer= B;
+}
+
+
+void KBufferColumn::resetXBuffer()
+{
+ delete [] PosX;
+ delete [] PosRightX;
+
+ LastPos = Layout->noOfBytesPerLine()-1;
+ PosX = new KPixelX[LastPos+1];
+ PosRightX = new KPixelX[LastPos+1];
+
+ if( PosX )
+ recalcX();
+}
+
+
+void KBufferColumn::setMetrics( KPixelX DW, KPixelY DBL )
+{
+ DigitBaseLine = DBL;
+ setDigitWidth( DW );
+}
+
+
+bool KBufferColumn::setDigitWidth( KPixelX DW )
+{
+ // no changes?
+ if( DigitWidth == DW )
+ return false;
+
+ DigitWidth = DW;
+ // recalculate depend sizes
+ recalcByteWidth();
+
+ if( PosX )
+ recalcX();
+ return true;
+}
+
+
+bool KBufferColumn::setSpacing( KPixelX BSW, int NoGB, KPixelX GSW )
+{
+ // no changes?
+ if( ByteSpacingWidth == BSW && NoOfGroupedBytes == NoGB && GroupSpacingWidth == GSW )
+ return false;
+
+ ByteSpacingWidth = BSW;
+ NoOfGroupedBytes = NoGB;
+ GroupSpacingWidth = GSW;
+
+ // recalculate depend sizes
+ recalcVerticalGridX();
+
+ if( PosX )
+ recalcX();
+ return true;
+}
+
+
+bool KBufferColumn::setByteSpacingWidth( KPixelX BSW )
+{
+ // no changes?
+ if( ByteSpacingWidth == BSW )
+ return false;
+
+ ByteSpacingWidth = BSW;
+
+ // recalculate depend sizes
+ recalcVerticalGridX();
+
+ if( PosX )
+ recalcX();
+ return true;
+}
+
+
+bool KBufferColumn::setNoOfGroupedBytes( int NoGB )
+{
+ // no changes?
+ if( NoOfGroupedBytes == NoGB )
+ return false;
+
+ NoOfGroupedBytes = NoGB;
+
+ if( PosX )
+ recalcX();
+ return true;
+}
+
+
+bool KBufferColumn::setGroupSpacingWidth( KPixelX GSW )
+{
+ // no changes?
+ if( GroupSpacingWidth == GSW )
+ return false;
+
+ GroupSpacingWidth = GSW;
+
+ // recalculate depend sizes
+ recalcVerticalGridX();
+
+ if( PosX )
+ recalcX();
+ return true;
+}
+
+
+void KBufferColumn::recalcByteWidth()
+{
+ ByteWidth = DigitWidth;
+ recalcVerticalGridX();
+}
+
+
+void KBufferColumn::recalcVerticalGridX()
+{
+ VerticalGridX = ByteWidth-1 + GroupSpacingWidth/2;
+}
+
+
+void KBufferColumn::recalcX()
+{
+ SpacingTrigger = noOfGroupedBytes() > 0 ? noOfGroupedBytes()-1 : LastPos+1; // last ensures to never trigger the spacing
+
+ KPixelX NewWidth = 0;
+ int p = 0;
+ int gs = 0;
+ KPixelX *PX = PosX;
+ KPixelX *PRX = PosRightX;
+ for( ; PX<&PosX[LastPos+1]; ++PX, ++PRX, ++p, ++gs )
+ {
+ *PX = NewWidth;
+ NewWidth += ByteWidth;
+ *PRX = NewWidth-1;
+
+ // is there a space behind the actual byte (if it is not the last)?
+ if( gs == SpacingTrigger )
+ {
+ NewWidth += GroupSpacingWidth;
+ gs = -1;
+ }
+ else
+ NewWidth += ByteSpacingWidth;
+ }
+ setWidth( PosRightX[LastPos]+1 );
+}
+
+
+// TODO: why are inlined functions not available as symbols when defined before their use
+//TODO: works not precisly for the byte rects but includes spacing and left and right
+/*inline*/ int KBufferColumn::posOfX( KPixelX PX ) const
+{
+ if( !PosX )
+ return NoByteFound;
+
+ // translate
+ PX -= x();
+ // search backwards for the first byte that is equalleft to x
+ for( int p=LastPos; p>=0; --p )
+ if( PosX[p] <= PX )
+ return p;
+
+ return 0; //NoByteFound;
+}
+
+
+int KBufferColumn::magPosOfX( KPixelX PX ) const
+{
+ if( !PosX )
+ return NoByteFound;
+
+ // translate
+ PX -= x();
+ // search backwards for the first byte that is equalleft to x
+ for( int p=LastPos; p>=0; --p )
+ if( PosX[p] <= PX )
+ {
+ // are we close to the right?
+ if( PosRightX[p]-PX < DigitWidth/2 ) // TODO: perhaps cache also the middle xpos's
+ ++p;
+ return p;
+ }
+
+ return 0; //NoByteFound;
+}
+
+
+KSection KBufferColumn::posOfX( KPixelX PX, KPixelX PW ) const
+{
+ if( !PosX )
+ return KSection();
+
+ // translate
+ PX -= x();
+ int PRX = PX + PW - 1;
+
+ KSection P;
+ // search backwards for the first byte that is equalleft to x
+ for( int p=LastPos; p>=0; --p )
+ if( PosX[p] <= PRX )
+ {
+ P.setEnd( p );
+ for( ; p>=0; --p )
+ if( PosX[p] <= PX )
+ {
+ P.setStart( p );
+ break;
+ }
+ break;
+ }
+
+ return P;
+}
+
+
+KPixelX KBufferColumn::xOfPos( int Pos ) const { return x() + (PosX?PosX[Pos]:0); }
+KPixelX KBufferColumn::rightXOfPos( int Pos ) const { return x() + (PosRightX?PosRightX[Pos]:0); }
+
+
+int KBufferColumn::posOfRelX( KPixelX PX ) const
+{
+ if( !PosX )
+ return NoByteFound;
+
+ // search backwards for the first byte that is equalleft to x
+ for( int p=LastPos; p>=0; --p )
+ if( PosX[p] <= PX )
+ return p;
+
+ return 0; //NoByteFound;
+}
+
+
+KSection KBufferColumn::posOfRelX( KPixelX PX, KPixelX PW ) const
+{
+ if( !PosX )
+ return KSection();
+
+ int PRX = PX + PW - 1;
+
+ KSection P;
+ // search backwards for the first byte that is equalleft to x
+ for( int p=LastPos; p>=0; --p )
+ if( PosX[p] <= PRX )
+ {
+ P.setEnd( p );
+ for( ; p>=0; --p )
+ if( PosX[p] <= PX )
+ {
+ P.setStart( p );
+ break;
+ }
+ break;
+ }
+
+ return P;
+}
+
+
+KPixelX KBufferColumn::relXOfPos( int Pos ) const { return PosX ? PosX[Pos] : 0; }
+KPixelX KBufferColumn::relRightXOfPos( int Pos ) const { return PosRightX ? PosRightX[Pos] : 0; }
+
+
+KPixelXs KBufferColumn::wideXPixelsOfPos( KSection Positions ) const
+{
+ return KPixelXs( Positions.start()>0?rightXOfPos(Positions.start()-1)+1:xOfPos(Positions.start()),
+ Positions.end()<LastPos?xOfPos(Positions.end()+1)-1:rightXOfPos(Positions.end()) );
+}
+
+
+KPixelXs KBufferColumn::relWideXPixelsOfPos( KSection Positions ) const
+{
+ return KPixelXs( Positions.start()>0?relRightXOfPos(Positions.start()-1)+1:relXOfPos(Positions.start()),
+ Positions.end()<LastPos?relXOfPos(Positions.end()+1)-1:relRightXOfPos(Positions.end()) );
+}
+
+
+void KBufferColumn::preparePainting( KPixelXs Xs )
+{
+ Xs.restrictTo( XSpan );
+ // translate
+ Xs.moveBy( -x() );
+
+
+ // store the values
+ PaintX = Xs.start();
+ PaintW = Xs.width();
+
+ // get line positions to paint
+ PaintPositions = posOfRelX( PaintX, PaintW );
+}
+
+
+void KBufferColumn::paintFirstLine( QPainter *P, KPixelXs Xs, int FirstLine )
+{
+ preparePainting( Xs );
+
+ PaintLine = FirstLine;
+
+// kdDebug(1501) << "paintFirstLine:"<<cx<<","<<cw<<"|" <<PaintX<<","<<PaintW << ")\n";
+
+// paintPositions( P, PaintLine++, PaintPositions );
+ paintLine( P, PaintLine++ );
+}
+
+
+void KBufferColumn::paintNextLine( QPainter *P )
+{
+// paintPositions( P, PaintLine++, PaintPositions );
+ paintLine( P, PaintLine++ );
+}
+
+
+void KBufferColumn::paintLine( QPainter *P, int Line ) // TODO: could be removed???
+{
+// kdDebug(1501) << "paintLine line: "<<Line<<" Start: "<<PaintPositions.start()<<" End: "<<PaintPositions.end() << "\n";
+ // no bytes to paint?
+// if( !Layout->hasContent(Line) )
+// return;
+
+ paintPositions( P, Line, PaintPositions );
+}
+
+
+void KBufferColumn::paintPositions( QPainter *P, int Line, KSection Pos )
+{
+ const QColorGroup &CG = View->colorGroup();
+
+ // clear background
+ unsigned int BlankFlag = (Pos.start()!=0?StartsBefore:0) | (Pos.end()!=LastPos?EndsLater:0);
+ paintRange( P, CG.base(), Pos, BlankFlag );
+
+ // Go through the lines TODO: handle first and last line more effeciently
+ // check for leading and trailing spaces
+ KSection Positions( Layout->firstPos(KBufferCoord( Pos.start(), Line )),
+ Layout->lastPos( KBufferCoord( Pos.end(), Line )) );
+
+ // no bytes to paint?
+ if( !Layout->hasContent(Line) )
+ return;
+
+ // check for leading and trailing spaces
+ KSection Indizes( Layout->indexAtCoord(KBufferCoord( Positions.start(), Line )), Positions.width(), false );
+
+ unsigned int SelectionFlag;
+ unsigned int MarkingFlag;
+ KSection Selection;
+ KSection Marking;
+ bool HasMarking = Ranges->hasMarking();
+ bool HasSelection = Ranges->hasSelection();
+
+ while( Positions.isValid() )
+ {
+ KSection PositionsPart( Positions ); // set of positions to paint next
+ KSection IndizesPart( Indizes ); // set of indizes to paint next
+ // falls Marking nicht mehr gebuffert und noch zu erwarten
+ if( HasMarking && Marking.endsBefore(IndizesPart.start()) )
+ {
+ // erhebe nächste Markierung im Bereich
+ HasMarking = isMarked( IndizesPart, &Marking, &MarkingFlag );
+ }
+ // falls Selection nicht mehr gebuffert und noch zu erwarten
+ if( HasSelection && Selection.endsBefore(IndizesPart.start()) )
+ {
+ // erhebe nächste Selection im Bereich
+ HasSelection = isSelected( IndizesPart, &Selection, &SelectionFlag );
+ }
+
+ if( Marking.start() == IndizesPart.start() )
+ {
+ IndizesPart.setEnd( Marking.end() );
+ PositionsPart.setEndByWidth( Marking.width() );
+ if( PositionsPart.end() == Layout->lastPos(Line) ) MarkingFlag &= ~EndsLater;
+ if( PositionsPart.start() == Layout->firstPos(Line)) MarkingFlag &= ~StartsBefore;
+ paintMarking( P, PositionsPart, IndizesPart.start(), MarkingFlag );
+
+ }
+ else if( Selection.includes(IndizesPart.start()) )
+ {
+ if( Selection.startsBehind(IndizesPart.start()) )
+ SelectionFlag |= StartsBefore;
+ bool MarkingBeforeEnd = HasMarking && Marking.start() <= Selection.end();
+
+ IndizesPart.setEnd( MarkingBeforeEnd ? Marking.start()-1 : Selection.end() );
+ PositionsPart.setEndByWidth( IndizesPart.width() );
+
+ if( MarkingBeforeEnd )
+ SelectionFlag |= EndsLater;
+ if( PositionsPart.end() == Layout->lastPos(Line) ) SelectionFlag &= ~EndsLater;
+ if( PositionsPart.start() == Layout->firstPos(Line) ) SelectionFlag &= ~StartsBefore;
+
+ paintSelection( P, PositionsPart, IndizesPart.start(), SelectionFlag );
+ }
+ else
+ {
+ // calc end of plain text
+ if( HasMarking )
+ IndizesPart.setEnd( Marking.start()-1 );
+ if( HasSelection )
+ IndizesPart.restrictEndTo( Selection.start()-1 );
+
+ PositionsPart.setEndByWidth( IndizesPart.width() );
+ paintPlain( P, PositionsPart, IndizesPart.start() );
+ }
+ Indizes.setStartBehind( IndizesPart );
+ Positions.setStartBehind( PositionsPart );
+ }
+ // we don't paint grids as default, perhaps we never will though it works
+ // paintGrid( P, Positions ); // TODO: get some unmodified Positions (see three lines before)
+}
+
+
+void KBufferColumn::paintPlain( QPainter *P, KSection Positions, int Index )
+{
+ // paint all the bytes affected
+ for( int p=Positions.start(); p<=Positions.end(); ++p,++Index )
+ {
+ KPixelX x = relXOfPos( p );
+
+ // draw the byte
+ P->translate( x, 0 );
+ char Byte = Buffer->datum( Index );
+ KHEChar B = Codec->decode( Byte );
+ drawByte( P, Byte, B, colorForChar(B) );
+
+ P->translate( -x, 0 );
+ }
+}
+
+
+void KBufferColumn::paintSelection( QPainter *P, KSection Positions, int Index, int Flag )
+{
+ const QColorGroup &CG = View->colorGroup();
+
+ paintRange( P, CG.highlight(), Positions, Flag );
+
+ const QColor &HTC = CG.highlightedText();
+ // paint all the bytes affected
+ for( int p=Positions.start(); p<=Positions.end(); ++p,++Index )
+ {
+ KPixelX x = relXOfPos( p );
+
+ // draw the byte
+ P->translate( x, 0 );
+ char Byte = Buffer->datum( Index );
+ KHEChar B = Codec->decode( Byte );
+ drawByte( P, Byte, B, HTC );
+
+ P->translate( -x, 0 );
+ }
+}
+
+
+void KBufferColumn::paintMarking( QPainter *P, KSection Positions, int Index, int Flag )
+{
+ const QColorGroup &CG = View->colorGroup();
+
+ paintRange( P, CG.text(), Positions, Flag );
+
+ const QColor &BC = CG.base();
+ // paint all the bytes affected
+ for( int p=Positions.start(); p<=Positions.end(); ++p,++Index )
+ {
+ KPixelX x = relXOfPos( p );
+
+ // draw the byte
+ P->translate( x, 0 );
+ char Byte = Buffer->datum( Index );
+ KHEChar B = Codec->decode( Byte );
+ drawByte( P, Byte, B, BC );
+
+ P->translate( -x, 0 );
+ }
+}
+
+
+// TODO: smarter calculation
+void KBufferColumn::paintGrid( QPainter *P, KSection Range )
+{
+ int st = 0; // counter for spacing triggering
+ P->setPen( Qt::black );
+ // paint all the bytes affected
+ for( int p=Range.start(); p<=Range.end(); ++p,++st )
+ {
+ KPixelX x = relXOfPos( p );
+
+ // draw the byte
+ P->translate( x, 0 );
+
+ // spacing behind byte and vertical grid enabled?
+ if( st == SpacingTrigger && p != LastPos )
+ P->drawLine( VerticalGridX, 0, VerticalGridX, LineHeight-1 ) ;
+
+ P->translate( -x, 0 );
+ }
+}
+
+
+void KBufferColumn::paintRange( QPainter *P, const QColor &Color, KSection Positions, int Flag )
+{
+ KPixelX RangeX = Flag & StartsBefore ? relRightXOfPos( Positions.start()-1 ) + 1 : relXOfPos( Positions.start() );
+ KPixelX RangeW = (Flag & EndsLater ? relXOfPos( Positions.end()+1 ): relRightXOfPos( Positions.end() ) + 1) - RangeX;
+
+ P->fillRect( RangeX,0,RangeW,LineHeight, QBrush(Color,Qt::SolidPattern) );
+}
+
+
+void KBufferColumn::paintByte( QPainter *P, int Index )
+{
+ char Byte = ( Index > -1 ) ? Buffer->datum( Index ) : EmptyByte;
+ KHEChar B = Codec->decode( Byte );
+
+ const QColorGroup &CG = View->colorGroup();
+ QColor Color = CG.text();
+ QBrush Brush( CG.base(), Qt::SolidPattern );
+
+ if( Index > -1 )
+ {
+ if( Ranges->markingIncludes(Index) )
+ {
+ Brush.setColor( CG.text() );
+ Color = CG.base();
+ }
+ else if( Ranges->selectionIncludes(Index) )
+ {
+ Brush.setColor( CG.highlight() );
+ Color = CG.highlightedText();
+ }
+ else
+ {
+ Brush.setColor( CG.base() );
+ Color = colorForChar( B );
+ }
+ }
+
+ P->fillRect( 0,0,ByteWidth,LineHeight, Brush );
+
+ if( Index > -1 )
+ drawByte( P, Byte, B, Color );
+}
+
+
+void KBufferColumn::paintFramedByte( QPainter *P, int Index, KFrameStyle FrameStyle )
+{
+ paintByte( P, Index );
+ char Byte = ( Index > -1 ) ? Buffer->datum( Index ) : EmptyByte;
+ KHEChar B = Codec->decode( Byte );
+
+ P->setPen( colorForChar(B) );
+ if( FrameStyle == Frame )
+ P->drawRect( 0, 0, ByteWidth, LineHeight );
+ else if( FrameStyle == Left )
+ P->drawLine( 0, 0, 0, LineHeight-1 );
+ else
+ P->drawLine( ByteWidth-1,0,ByteWidth-1,LineHeight-1 );
+}
+
+
+void KBufferColumn::paintCursor( QPainter *P, int Index )
+{
+ char Byte = ( Index > -1 ) ? Buffer->datum( Index ) : EmptyByte;
+ KHEChar B = Codec->decode( Byte );
+ P->fillRect( 0, 0, ByteWidth, LineHeight, QBrush(colorForChar(B),Qt::SolidPattern) );
+}
+
+
+void KBufferColumn::drawByte( QPainter *P, char /*Byte*/, KHEChar B, const QColor &Color ) const
+{
+ P->setPen( Color );
+ P->drawText( 0, DigitBaseLine, B );
+}
+
+
+bool KBufferColumn::isSelected( KSection Range, KSection *Selection, unsigned int *Flag ) const
+{
+ KSection S;
+ unsigned int F = 0;
+ const KSection *OS = Ranges->firstOverlappingSelection( Range );
+ if( !OS )
+ return false;
+ S = *OS;
+
+ // does selection start before asked range?
+ if( Range.start() > S.start() )
+ {
+ S.setStart( Range.start() );
+ F |= StartsBefore;
+ }
+
+ // does selection go on behind asked range?
+ if( Range.end() < S.end() )
+ {
+ S.setEnd( Range.end() );
+ F |= EndsLater;
+ }
+
+ *Selection = S;
+ *Flag = F;
+ return true;
+}
+
+
+bool KBufferColumn::isMarked( KSection Range, KSection *Marking, unsigned int *Flag ) const
+{
+ KSection M;
+ unsigned int F = 0;
+ const KSection *OM = Ranges->overlappingMarking( Range );
+ if( !OM )
+ return false;
+ M = *OM;
+
+ // does selection start before asked range?
+ if( Range.start() > M.start() )
+ {
+ M.setStart( Range.start() );
+ F |= StartsBefore;
+ }
+
+ // does selection go on behind asked range?
+ if( Range.end() < M.end() )
+ {
+ M.setEnd( Range.end() );
+ F |= EndsLater;
+ }
+
+ *Marking = M;
+ *Flag = F;
+ return true;
+}
diff --git a/khexedit/lib/kbuffercolumn.h b/khexedit/lib/kbuffercolumn.h
new file mode 100644
index 0000000..76ed8bc
--- /dev/null
+++ b/khexedit/lib/kbuffercolumn.h
@@ -0,0 +1,253 @@
+/***************************************************************************
+ kbuffercolumn.h - description
+ -------------------
+ begin : Mit Mai 14 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_KBUFFERCOLUMN_H
+#define KHE_KBUFFERCOLUMN_H
+
+// lib specific
+#include "khe.h"
+#include "kdatabuffer.h"
+#include "khechar.h"
+#include "kcolumn.h"
+#include "kbufferlayout.h"
+#include "ksection.h"
+
+class QPainter;
+class QColor;
+
+namespace KHE
+{
+
+// class KHexEdit;
+class KBufferRanges;
+class KCharCodec;
+
+const int NoByteFound = -1;
+
+/** base class of all buffer column displayers
+ * holds all information about the vertical layout of a buffer column
+ * knows how to paint the data and the editing things (focus, cursor, selection)
+ * but does not offer
+ *
+ *@author Friedrich W. H. Kossebauint KBufferColumn::posOfX( KPixelX PX, bool *ToTheRightFlag ) const
+ */
+class KBufferColumn : public KColumn
+{
+ public:
+ enum KFrameStyle { Frame, Left, Right };
+ public:
+ KBufferColumn( KColumnsView/*KHexEdit*/ *HE, KDataBuffer *B, KBufferLayout *L, KBufferRanges *R );
+ virtual ~KBufferColumn();
+
+
+ public: // KColumn-API
+ virtual void paintFirstLine( QPainter *P, KPixelXs Xs, int FirstLine );
+ virtual void paintNextLine( QPainter *P );
+
+ public:
+ void preparePainting( KPixelXs Xs );
+
+ public:
+ void paintLine( QPainter *P, int Line );
+ void paintPositions( QPainter *P, int Line, KSection Positions );
+ /** paints a cursor based on the type of the byte.
+ * @param Index Index of the byte to paint the cursor for. If -1 a space is used as char.
+ */
+ void paintCursor( QPainter *P, int Index );
+ /** paints the byte with background.
+ * @param Index Index of the byte to paint. If -1 only the background is painted.
+ */
+ void paintByte( QPainter *P, int Index );
+ /** paints the byte with background and a frame around.
+ * @param Index Index of the byte to paint the frame for. If -1 a space is used as char.
+ * @param Style the style of the framing
+ */
+ void paintFramedByte( QPainter *P, int Index, KFrameStyle Style );
+
+
+ public: // modification access
+ /** sets the spacing in the hex column
+ * @param ByteSpacingW spacing between the bytes in pixels
+ * @param NewNoOfGroupedBytes numbers of grouped bytes, 0 means no grouping
+ * @param GroupSpacingW spacing between the groups in pixels
+ * returns true if there was a change
+ */
+ bool setSpacing( KPixelX ByteSpacingW, int NewNoOfGroupedBytes = 0, KPixelX GroupSpacingW = 0 );
+ /** sets the spacing between the bytes in the hex column
+ * @param ByteSpacingW spacing between the bytes in pixels
+ * returns true if there was a change
+ */
+ bool setByteSpacingWidth( KPixelX ByteSpacingW );
+ /** sets the number of grouped bytes in the hex column
+ * @param NewNoOfGroupedBytes numbers of grouped bytes, 0 means no grouping
+ * returns true if there was a change
+ */
+ bool setNoOfGroupedBytes( int NewNoOfGroupedBytes );
+ /** sets the spacing between the groups of bytes in the hex column
+ * @param GroupSpacingW spacing between the groups in pixels
+ * returns true if there was a change
+ */
+ bool setGroupSpacingWidth( KPixelX GroupSpacingW );
+ /** sets width of digits and recalculates depend sizes
+ * returns true if there was a change
+ */
+ bool setDigitWidth( KPixelX DW );
+ /** sets the metrics of the used font
+ * @param NewDigitWidth the new width of a digit
+ * @param NewDigitBaseLine the new baseline of the digits
+ */
+ void setMetrics( KPixelX NewDigitWidth, KPixelY NewDigitBaseLine );
+ /** */
+ void set( KDataBuffer *B );
+ /** creates new buffer for x-values; to be called on any change of NoOfBytesPerLine or metrics */
+ void resetXBuffer();
+ /** sets the codec to be used by the char column. */
+ void setCodec( KCharCodec *C );
+
+ public: // functional logic
+ /** returns byte positions covered by pixels with absolute x-coord x */
+ KSection posOfX( KPixelX x, KPixelX w ) const;
+ /** returns byte pos at pixel with absolute x-coord x */
+ int posOfX( KPixelX x ) const;
+ /** returns byte pos at pixel with absolute x-coord x, and sets the flag to true if we are closer to the right */
+ int magPosOfX( KPixelX PX ) const;
+ /** returns absolute x-coord of byte at position Pos */
+ KPixelX xOfPos( int Pos ) const;
+ /** returns right absolute x-coord of byte at position Pos */
+ KPixelX rightXOfPos( int Pos ) const;
+ /** returns byte pos at pixel with relative x-coord x */
+ int posOfRelX( KPixelX x ) const;
+ /** returns byte positions covered by pixels with relative x-coord x */
+ KSection posOfRelX( KPixelX x, KPixelX w ) const;
+ /** returns relative x-coord of byte at position Pos */
+ KPixelX relXOfPos( int Pos ) const;
+ /** returns right relative x-coord of byte at position Pos */
+ KPixelX relRightXOfPos( int Pos ) const;
+ /** returns the positions that overlap with the absolute x-coords */
+ KSection visiblePositions( KPixelX x, KPixelX w ) const;
+ /** returns the */
+ KPixelXs wideXPixelsOfPos( KSection Positions ) const;
+ /** */
+ KPixelXs relWideXPixelsOfPos( KSection Positions ) const;
+
+ public: // value access
+ KPixelX byteWidth() const;
+ KPixelX digitWidth() const;
+ KPixelX groupSpacingWidth() const;
+ KPixelX byteSpacingWidth() const;
+ int noOfGroupedBytes() const;
+
+ int firstPos() const;
+ int lastPos() const;
+ KSection visiblePositions() const;
+ const KBufferLayout *layout() const;
+ KCharCodec* codec() const;
+
+ protected:
+ /** */
+ void recalcX();
+ void recalcVerticalGridX();
+
+
+ protected: // API to be refined
+ /** default implementation simply prints the byte as ASCII */
+ virtual void drawByte( QPainter *P, char Byte, KHEChar B, const QColor &Color ) const;
+ /** default implementation sets byte width to one digit width */
+ virtual void recalcByteWidth();
+
+
+ protected:
+ void paintGrid( QPainter *P, KSection Range );
+ void paintPlain( QPainter *P, KSection Positions, int Index );
+ void paintSelection( QPainter *P, KSection Positions, int Index, int Flag );
+ void paintMarking( QPainter *P, KSection Positions, int Index, int Flag );
+ void paintRange( QPainter *P, const QColor &Color, KSection Positions, int Flag );
+
+ bool isSelected( KSection Range, KSection *Selection, unsigned int *Flag ) const;
+ bool isMarked( KSection Range, KSection *Marking, unsigned int *Flag ) const;
+
+
+ protected:
+ /** pointer to the buffer */
+ KDataBuffer *Buffer;
+ /** pointer to the layout */
+ const KBufferLayout *Layout;
+ /** pointer to the ranges */
+ KBufferRanges *Ranges;
+ /** */
+ KCharCodec *Codec;
+
+ /** */
+ KPixelX DigitWidth;
+ /** */
+ KPixelY DigitBaseLine;
+ /** */
+ KPixelX VerticalGridX;
+ /** */
+ bool VerticalGrid;
+
+ protected: // individual data
+ /** total width of byte display in pixel */
+ KPixelX ByteWidth;
+ /** width of inserting cursor in pixel */
+ KPixelX CursorWidth;
+ /** size of the line margin */
+ KPixelX ByteSpacingWidth;
+ /** width of spacing in pixel */
+ KPixelX GroupSpacingWidth;
+
+ /** number of grouped bytes */
+ int NoOfGroupedBytes;
+
+ /** pointer to array with buffered positions (relative to column position)
+ * a spacing gets assigned to the left byte -> ...c|c|c |c|c...
+ */
+ KPixelX *PosX;
+ KPixelX *PosRightX;
+ /** index of right position */
+ int LastPos;
+
+
+ protected: // buffering drawing data
+ KSection PaintPositions;
+ int PaintLine;
+ KPixelX PaintX;
+ KPixelX PaintW;
+ int SpacingTrigger;
+};
+
+
+inline KPixelX KBufferColumn::byteWidth() const { return ByteWidth; }
+inline KPixelX KBufferColumn::digitWidth() const { return DigitWidth; }
+inline KPixelX KBufferColumn::byteSpacingWidth() const { return ByteSpacingWidth; }
+inline KPixelX KBufferColumn::groupSpacingWidth() const { return GroupSpacingWidth; }
+
+inline int KBufferColumn::noOfGroupedBytes() const { return NoOfGroupedBytes; }
+
+inline int KBufferColumn::firstPos() const { return PaintPositions.start(); }
+inline int KBufferColumn::lastPos() const { return PaintPositions.end(); }
+inline KSection KBufferColumn::visiblePositions() const { return PaintPositions; }
+
+inline const KBufferLayout *KBufferColumn::layout() const { return Layout; }
+
+
+inline void KBufferColumn::setCodec( KCharCodec *C ) { Codec = C; }
+inline KCharCodec* KBufferColumn::codec() const { return Codec; }
+
+}
+
+#endif
diff --git a/khexedit/lib/kbuffercoord.h b/khexedit/lib/kbuffercoord.h
new file mode 100644
index 0000000..997551a
--- /dev/null
+++ b/khexedit/lib/kbuffercoord.h
@@ -0,0 +1,293 @@
+/***************************************************************************
+ kbuffercoord.h - description
+ -------------------
+ begin : Don Mai 29 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_KBUFFERCOORD_H
+#define KHE_KBUFFERCOORD_H
+
+
+namespace KHE
+{
+
+/**
+ * a class which represents a coord in a 2-dim. system
+ *
+ * It consists of a line number and a position in the line.
+ * The coord starts at (0,0). Line numbers increase downwards, positions to the right.
+ * With any of both at a negative number the coord is invalid.
+ * TODO: change as much as possible params to unsigned integer
+ *
+ * @author Friedrich W. H. Kossebau
+ */
+class KBufferCoord
+{
+ public:
+ /** creates a coord with 0,0 */
+ KBufferCoord();
+ KBufferCoord( int P, int L );
+ KBufferCoord( int Index, int LineWidth, bool /*dummy*/ );
+ KBufferCoord( const KBufferCoord &C );
+ KBufferCoord &operator=( const KBufferCoord &c );
+ ~KBufferCoord();
+
+
+ public: // logic
+ bool operator==( const KBufferCoord &c ) const;
+ bool operator!=( const KBufferCoord &c ) const;
+ bool operator<( const KBufferCoord &c ) const;
+ bool operator<=( const KBufferCoord &c ) const;
+ bool operator>( const KBufferCoord &c ) const;
+ bool operator>=( const KBufferCoord &c ) const;
+
+ /** tests if the coord is prior in the same line than the given coord.
+ * If at least one of both is invalid the result is undefined.
+ * @return true if the pos is left to the pos of C and both are in the same line, otherwise false.
+ */
+ bool isPriorInLineThan( const KBufferCoord &C ) const;
+ /** tests if the coord is later in the same line than the given coord.
+ * If at least one of both is invalid the result is undefined.
+ * @return true if the pos is right to the pos of C and both are in the same line, otherwise false
+ */
+ bool isLaterInLineThan( const KBufferCoord &C ) const;
+ /** @return true if the line is below L, otherwise false */
+ bool isBelow( int L ) const;
+ /** @return true if the line is above L, otherwise false */
+ bool isAbove( int L ) const;
+ /** @return true if the coord is at (0,0) */
+ bool isAtStart() const;
+ /** @return true if the pos is greater than 0, otherwise false */
+ bool isBehindLineStart() const;
+ /** @return true if the pos is smaller than MaxPos, otherwise false */
+ bool isBeforeLineEnd( int MaxPos ) const;
+
+ /** calculates the index the coord is at with a given line width
+ * If the coord is invalid the result is undefined.
+ * @param LineWidth given width of line
+ * @return index the coord is at
+ */
+ int indexByLineWidth( int LineWidth ) const;
+
+ public:
+ /** set the coord by calculating it for an index with a given line width
+ * @param Index index in the buffer
+ * @param LineWidth given line width
+ */
+ void setByIndexNWidth( int Index, int LineWidth );
+ /** sets both position and line */
+ void set( int P, int L );
+ /** sets the position */
+ void setPos( int P );
+ /** sets the line */
+ void setLine( int L );
+
+ /** moves the coord one position to the left. If the coord is invalid the result is undefined. */
+ void goLeft();
+ /** moves the coord a given number of positions to the left.
+ * If the coord is invalid the result is undefined or the position smaller then the given number
+ * the behaviour is undefined.
+ * @param P number of positions
+ */
+ void goLeft( unsigned int P );
+ /** moves the coord one position to the left, or if the position is already at the line start
+ * to the given position in the previous line. If the coord is invalid the result is undefined.
+ * @param MaxPos maximal allowed position
+ */
+ void goCLeft( int MaxPos );
+ /** moves the coord one position to the right. If the coord is invalid the result is undefined. */
+ void goRight();
+ /** moves the coord a given number of positions to the right. If the coord is invalid the result is undefined.
+ * @param P number of positions
+ */
+ void goRight( unsigned int P );
+ /** moves the coord one position to the right, or if the position has already reached or passed MaxPos
+ * to the first position in the next line. If the coord is invalid the result is undefined.
+ * @param MaxPos maximal allowed position
+ */
+ void goCRight( int MaxPos );
+ /** sets coord to (0,0) */
+ void gotoStart();
+ void gotoEndOfPreviousLine( int LastPos );
+ /** sets the coord to the start of the next line.
+ * If the coord is invalid the behaviour is undefined.
+ */
+ void gotoStartOfNextLine();
+ /** sets the position to the start of the line or
+ * if the line is the same as that of the given coord to the position of it.
+ * If one or more of the coords is invalid the behaviour is undefined.
+ * @param C a possible line start coord
+ */
+ void goLineStart( const KBufferCoord &C );
+ /** sets the position to the given pos or
+ * if the line is the same as that of the given coord to the position of that.
+ * If one or more of the coords is invalid the behaviour is undefined.
+ * @param L last position in normal line
+ * @param C a possible line end coord
+ */
+ void goLineEnd( int L, const KBufferCoord &C );
+ /** moves the coord 1 lines upwards. There is no check whether the first line is overstepped. */
+ void goUp();
+ /** moves the coord L lines downwards. */
+ void goDown();
+ /** moves the coord L lines upwards. There is no check whether the first line is overstepped.
+ * @param L number of lines
+ */
+ void goUp( unsigned int L );
+ /** moves the coord L lines downwards.
+ * @param L number of lines
+ */
+ void goDown( unsigned int L );
+
+ public: // state value access
+ /** @return the pos in the line */
+ int pos() const;
+ /** @return the line number */
+ int line() const;
+ /** @return true if the coord is valid */
+ bool isValid() const;
+
+ private: // member variables
+ /** Position in Line */
+ int Pos;
+ /** Line */
+ int Line;
+};
+
+
+inline KBufferCoord::KBufferCoord() : Pos( 0 ), Line( 0 ) {}
+inline KBufferCoord::KBufferCoord( int P, int L ) : Pos( P ), Line( L ) {}
+inline KBufferCoord::KBufferCoord( int Index, int LineWidth, bool )
+{
+ Line = Index / LineWidth;
+ Pos = Index - Line*LineWidth;
+}
+
+inline KBufferCoord::KBufferCoord( const KBufferCoord &C ) : Pos( C.Pos ), Line( C.Line ) {}
+inline KBufferCoord &KBufferCoord::operator=( const KBufferCoord &C ) { Pos = C.Pos; Line = C.Line; return *this; }
+inline KBufferCoord::~KBufferCoord() {}
+
+inline bool KBufferCoord::operator==( const KBufferCoord &C ) const { return Pos == C.Pos && Line == C.Line; }
+inline bool KBufferCoord::operator!=( const KBufferCoord &C ) const { return !(*this == C); }
+
+inline bool KBufferCoord::operator<( const KBufferCoord &C ) const
+{ return Line < C.Line || (Line == C.Line && Pos<C.Pos); }
+inline bool KBufferCoord::operator<=( const KBufferCoord &C ) const
+{ return Line < C.Line || (Line == C.Line && Pos<=C.Pos); }
+inline bool KBufferCoord::operator>( const KBufferCoord &C ) const
+{ return Line > C.Line || (Line == C.Line && Pos>C.Pos); }
+inline bool KBufferCoord::operator>=( const KBufferCoord &C ) const
+{ return Line > C.Line || (Line == C.Line && Pos>=C.Pos); }
+
+inline int KBufferCoord::pos() const { return Pos; }
+inline int KBufferCoord::line() const { return Line; }
+inline bool KBufferCoord::isValid() const { return Line >= 0 && Pos >= 0; }
+
+inline void KBufferCoord::setByIndexNWidth( int Index, int LineWidth )
+{
+ Line = Index / LineWidth;
+ Pos = Index - Line*LineWidth;
+}
+
+inline void KBufferCoord::set( int P, int L )
+{
+ Pos = P;
+ Line = L;
+}
+inline void KBufferCoord::setPos( int P ) { Pos = P; }
+inline void KBufferCoord::setLine( int L ) { Line = L; }
+
+inline void KBufferCoord::goCRight( int MaxPos )
+{
+ if( isBeforeLineEnd(MaxPos) )
+ goRight();
+ else
+ gotoStartOfNextLine();
+}
+inline void KBufferCoord::goCLeft( int MaxPos )
+{
+ if( isBehindLineStart() )
+ goLeft();
+ else
+ gotoEndOfPreviousLine( MaxPos );
+}
+
+inline void KBufferCoord::goRight() { ++Pos; }
+inline void KBufferCoord::goLeft() { --Pos; }
+inline void KBufferCoord::goRight( unsigned int P ) { Pos += P; }
+inline void KBufferCoord::goLeft( unsigned int P ) { Pos -= P; }
+
+inline void KBufferCoord::gotoStart() { Pos = Line = 0; }
+
+inline void KBufferCoord::gotoEndOfPreviousLine( int LastPos )
+{
+ --Line;
+ Pos = LastPos;
+}
+
+inline void KBufferCoord::gotoStartOfNextLine()
+{
+ ++Line;
+ Pos = 0;
+}
+
+
+inline void KBufferCoord::goLineStart( const KBufferCoord &C )
+{
+ Pos = ( Line == C.Line ) ? C.Pos : 0;
+}
+
+inline void KBufferCoord::goLineEnd( int L, const KBufferCoord &C )
+{
+ Pos = ( Line == C.Line ) ? C.Pos : L;
+}
+
+inline void KBufferCoord::goUp() { --Line; }
+inline void KBufferCoord::goDown() { ++Line; }
+inline void KBufferCoord::goUp( unsigned int L ) { Line -= L; }
+inline void KBufferCoord::goDown( unsigned int L ) { Line += L; }
+
+
+inline int KBufferCoord::indexByLineWidth( int LineWidth ) const
+{
+ return Line * LineWidth + Pos;
+}
+
+
+inline bool KBufferCoord::isPriorInLineThan( const KBufferCoord &C ) const
+{
+ return Line == C.Line && Pos < C.Pos;
+}
+
+inline bool KBufferCoord::isLaterInLineThan( const KBufferCoord &C ) const
+{
+ return Line == C.Line && Pos > C.Pos;
+}
+
+inline bool KBufferCoord::isBelow( int L ) const { return Line > L; }
+inline bool KBufferCoord::isAbove( int L ) const { return Line < L; }
+
+inline bool KBufferCoord::isBehindLineStart() const { return Pos > 0; }
+inline bool KBufferCoord::isBeforeLineEnd( int MaxPos ) const { return Pos < MaxPos; }
+
+inline bool KBufferCoord::isAtStart() const { return Pos == 0 && Line == 0; }
+
+inline KBufferCoord operator+( const KBufferCoord &C, int p )
+{
+ return KBufferCoord( C.pos()+p, C.line() );
+}
+
+}
+
+#endif
diff --git a/khexedit/lib/kbuffercursor.cpp b/khexedit/lib/kbuffercursor.cpp
new file mode 100644
index 0000000..0255d2d
--- /dev/null
+++ b/khexedit/lib/kbuffercursor.cpp
@@ -0,0 +1,365 @@
+/***************************************************************************
+ kbuffercursor.cpp - description
+ -------------------
+ begin : Don Mai 29 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. *
+ * *
+ ***************************************************************************/
+
+
+//#include <kdebug.h>
+
+// lib specific
+#include "kbufferlayout.h"
+#include "kbuffercursor.h"
+
+using namespace KHE;
+
+KBufferCursor::KBufferCursor( const KBufferLayout *L )
+ : Layout( L ),
+ Index( 0 ),
+ Coord( 0, 0 ),
+ Behind( false ),
+ AppendPosEnabled( false )
+{
+}
+
+KBufferCursor::~KBufferCursor()
+{
+}
+
+
+bool KBufferCursor::operator==( const KBufferCursor &C ) const
+{
+ return Index == C.Index && Behind == C.Behind ;
+}
+
+
+void KBufferCursor::setAppendPosEnabled( bool APE )
+{
+ if( AppendPosEnabled == APE )
+ return;
+
+ AppendPosEnabled = APE;
+ // reposition Cursor
+ int Length = Layout->length();
+ // behind buffer end, not end of line and not empty?
+ if( realIndex() >= Length && Coord.pos() < Layout->noOfBytesPerLine()-1 && Length > 0 )
+ {
+ if( AppendPosEnabled )
+ {
+ ++Index;
+ Coord.goRight();
+ Behind = false;
+ }
+ else
+ {
+ --Index;
+ Coord.goLeft();
+ Behind = true;
+ }
+ }
+}
+
+
+void KBufferCursor::gotoPreviousByte()
+{
+ if( Behind )
+ Behind = false;
+ else if( Index > 0 )
+ {
+ --Index;
+ Coord.goCLeft( Layout->noOfBytesPerLine()-1 );
+ }
+}
+
+
+void KBufferCursor::gotoPreviousByte( int D )
+{
+ if( Behind )
+ {
+ --D;
+ Behind = false;
+ }
+ if( D > Index )
+ {
+ if( Index == 0 )
+ return;
+ gotoStart();
+ }
+ gotoIndex( Index - D );
+}
+
+
+void KBufferCursor::gotoNextByte()
+{
+ int Length = Layout->length();
+
+ if( Index < Length )
+ {
+ if( Index == Length-1 )
+ stepToEnd();
+ else
+ {
+ ++Index;
+ Coord.goCRight( Layout->noOfBytesPerLine()-1 );
+ Behind = false;
+ }
+ }
+}
+
+
+void KBufferCursor::gotoNextByte( int D ) // TODO: think about consistency with gotoNextByte!!!
+{
+ if( Behind )
+ {
+ ++D;
+ Behind = false;
+ }
+ // would we end behind the end?
+ if( Index+D >= Layout->length() )
+ gotoEnd();
+ else
+ gotoIndex( Index + D );
+}
+
+
+void KBufferCursor::gotoNextByteInLine()
+{
+ int Length = Layout->length();
+
+ if( Index < Length )
+ {
+ if( Index == Length-1 )
+ stepToEnd();
+ else
+ {
+ ++Index;
+
+ if( Coord.pos() < Layout->noOfBytesPerLine()-1 )
+ Coord.goRight();
+ else
+ Behind = true;
+ }
+ }
+}
+
+
+void KBufferCursor::gotoUp()
+{
+ // can we even go up?
+ if( Coord.isBelow(Layout->startLine()) )
+ {
+ Coord.goUp();
+ if( Coord.isPriorInLineThan(Layout->start()) )
+ {
+ Index = 0;
+ Coord.setPos( Layout->startPos() );
+ Behind = false;
+ }
+ else
+ {
+ Index -= Layout->noOfBytesPerLine();
+ if( Behind && !atLineEnd() )
+ {
+ ++Index;
+ Coord.goRight();
+ Behind = false;
+ }
+ }
+ }
+}
+
+
+void KBufferCursor::gotoDown()
+{
+ if( Coord.isAbove(Layout->finalLine()) )
+ {
+ Coord.goDown();
+ // behind End?
+ if( Coord.isLaterInLineThan(Layout->final()) )
+ gotoEnd();
+ else
+ Index += Layout->noOfBytesPerLine();
+ }
+}
+
+
+void KBufferCursor::gotoLineStart()
+{
+ int OldIndex = Index;
+ Index = Layout->indexAtLineStart( Coord.line() );
+ Coord.goLeft( OldIndex-Index );
+ Behind = false;
+}
+
+
+void KBufferCursor::gotoLineEnd()
+{
+ if( Index < Layout->length() )
+ {
+ int OldIndex = Index;
+ Index = Layout->indexAtLineEnd( Coord.line() );
+ Coord.goRight( Index-OldIndex );
+
+ stepToEnd();
+ }
+}
+
+
+void KBufferCursor::gotoStart()
+{
+ Index = 0;
+ Coord = Layout->start();
+ Behind = false;
+}
+
+
+void KBufferCursor::gotoEnd()
+{
+ int Length = Layout->length();
+ if( Length > 0 )
+ {
+ Index = Length-1;
+ Coord = Layout->final();
+
+ stepToEnd();
+ }
+ else
+ gotoStart();
+}
+
+
+void KBufferCursor::gotoCIndex( int i )
+{
+ if( Layout->length() > 0 )
+ {
+ Index = Layout->correctIndex( i );
+ Coord = Layout->coordOfIndex( Index );
+ if( i > Index )
+ stepToEnd();
+ else
+ Behind = false;
+ }
+ else
+ gotoStart();
+}
+
+
+void KBufferCursor::gotoCCoord( const KBufferCoord &C )
+{
+ if( Layout->length() > 0 )
+ {
+ Coord = Layout->correctCoord( C );
+ Index = Layout->indexAtCoord( Coord );
+ if( C > Coord )
+ stepToEnd();
+ else
+ Behind = false;
+ }
+ else
+ gotoStart();
+}
+
+
+void KBufferCursor::stepToEnd()
+{
+ if( AppendPosEnabled && (Coord.pos() < Layout->noOfBytesPerLine()-1) )
+ {
+ ++Index;
+ Coord.goRight();
+ Behind = false;
+ }
+ else
+ Behind = true;
+}
+
+
+void KBufferCursor::gotoIndex( int i )
+{
+ Index = i;
+ Coord = Layout->coordOfIndex( Index );
+ Behind = false;
+}
+
+
+void KBufferCursor::gotoRealIndex()
+{
+ if( Behind )
+ {
+ ++Index;
+ Coord = Layout->coordOfIndex( Index );
+ Behind = false;
+ }
+}
+
+
+void KBufferCursor::gotoCoord( const KBufferCoord &C )
+{
+ Index = Layout->indexAtCoord( C );
+ Coord = C;
+ Behind = false;
+}
+
+
+void KBufferCursor::updateCoord()
+{
+ Coord = Layout->coordOfIndex( Index );
+}
+
+// page down should be: one page minus one line
+// -> if in the very first line page down will put the cursor on the same page into the last line
+void KBufferCursor::gotoPageUp()
+{
+ int NoOfLinesPerPage = Layout->noOfLinesPerPage();
+ int NewIndex = Index - NoOfLinesPerPage * Layout->noOfBytesPerLine();
+ if( NewIndex < 0 )
+ gotoStart();
+ else
+ {
+ Index = NewIndex;
+ Coord.goUp( NoOfLinesPerPage );
+ if( Behind && !atLineEnd() )
+ {
+ ++Index;
+ Coord.goRight();
+ Behind = false;
+ }
+ }
+}
+
+
+void KBufferCursor::gotoPageDown()
+{
+ int NoOfLinesPerPage = Layout->noOfLinesPerPage();
+ int NewIndex = Index + NoOfLinesPerPage * Layout->noOfBytesPerLine();
+ if( NewIndex >= Layout->length() )
+ gotoEnd();
+ else
+ {
+ Index = NewIndex;
+ Coord.goDown( NoOfLinesPerPage );
+ }
+}
+
+
+int KBufferCursor::validIndex() const { return Index < Layout->length() ? Index : -1; }
+int KBufferCursor::indexAtLineStart() const { return Layout->indexAtLineStart( Coord.line() ); }
+int KBufferCursor::indexAtLineEnd() const { return Layout->indexAtLineEnd( Coord.line() ); }
+
+
+bool KBufferCursor::atStart() const { return Index == 0; }
+bool KBufferCursor::atEnd() const { return Index == Layout->length() - 1; }
+bool KBufferCursor::atAppendPos() const { return realIndex() >= Layout->length(); }
+
+
+bool KBufferCursor::atLineStart() const { return Layout->atLineStart( Coord ); }
+bool KBufferCursor::atLineEnd() const { return Layout->atLineEnd( Coord ); }
diff --git a/khexedit/lib/kbuffercursor.h b/khexedit/lib/kbuffercursor.h
new file mode 100644
index 0000000..855b3e8
--- /dev/null
+++ b/khexedit/lib/kbuffercursor.h
@@ -0,0 +1,172 @@
+/***************************************************************************
+ kbuffercursor.h - description
+ -------------------
+ begin : Don Mai 29 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_KBUFFERCURSOR_H
+#define KHE_KBUFFERCURSOR_H
+
+#include "kbuffercoord.h"
+
+
+namespace KHE
+{
+
+class KBufferLayout;
+
+
+/**@short navigates through the buffer in an abstract way, based on the layout
+ *
+ * The cursor is allowed to access every coord that has content as
+ * described in the layout. It holds the coord of the actual position
+ * and the according index in the data array.
+ *
+ * To enable the cursor to be placed behind the last position in a line
+ * (e.g, to mark all data in the line without placing the cursor to the
+ * beginning of the next line) there is a flag Behind that should be read
+ * as that the real index the cursor is at is the current one + 1
+ * (as returned by realIndex())
+ *
+ * For appending new data to the buffer there is also the need to be able
+ * to place the cursor at a position behind the last byte. This can be
+ * enabled by calling setAppendPosEnabled(true). If the cursor is placed to
+ * this position it gets the (real) index of the last byte + 1. As this
+ * index does not point to an existing byte validIndex() returns -1.
+ * Check for atAppendPos() to see whether cursor is at this position.
+ *
+ * If the buffer is empty there is no navigation possible, of course.
+ * The cursor will be placed to coord 0/0 with index 1, Behind=false.
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+class KBufferCursor
+{
+ public:
+ KBufferCursor( const KBufferLayout *L );
+ ~KBufferCursor();
+
+
+ public:
+ bool operator==( const KBufferCursor &c ) const;
+ bool operator!=( const KBufferCursor &c ) const { return !(*this == c); }
+
+ public: // modificator
+ void setAppendPosEnabled( bool APE=true );
+
+ public: // state value access
+ /** the index that is drawn at the actual coord */
+ int index() const;
+ /** the pos of the actual coord */
+ int pos() const;
+ /** the line of the actual coord */
+ int line() const;
+ /** the actual coord */
+ KBufferCoord coord() const;
+ /** true if the cursor is located to the right of the actual coord but still shown at the coord */
+ bool isBehind() const;
+ /** returns the real index. That is if the cursor is tagged as "behind" the current index
+ * it's real index is the next one.
+ * Attention: this could be outside the data's range if the cursor is behind the last byte!
+ */
+ int realIndex() const;
+ /** returns the true index if it is valid index that is it is inside the data's range.
+ * Otherwise -1 is returned
+ */
+ int validIndex() const;
+
+ //bool isValid() const;
+ bool appendPosEnabled() const;
+
+ public: // index calculation service
+ /** returns the index at the start of the cursor's line */
+ int indexAtLineStart() const;
+ /** returns the index at the end of the cursor's line */
+ int indexAtLineEnd() const;
+
+ public: // navigation commands
+ void gotoIndex( int I );
+ void gotoCoord( const KBufferCoord &C );
+ void gotoCIndex( int I );
+ void gotoCCoord( const KBufferCoord &C );
+ void gotoRealIndex();
+
+ void gotoPreviousByte();
+ void gotoNextByte();
+ void gotoPreviousByte( int D );
+ void gotoNextByte( int D );
+ void gotoNextByteInLine();
+ void gotoUp();
+ void gotoDown();
+ void gotoLineStart();
+ void gotoLineEnd();
+ void gotoStart();
+ void gotoEnd();
+ void gotoPageUp();
+ void gotoPageDown();
+
+ /** puts the cursor behind the actual position if it isn't already*/
+ void stepBehind();
+ void updateCoord();
+
+
+ public: // logical state access
+ bool atStart() const;
+ bool atEnd() const;
+ /** could only be true in InsertMode: Cursor is behind the last byte */
+ bool atAppendPos() const;
+ bool atLineStart() const;
+ bool atLineEnd() const;
+
+
+ protected:
+ /** if newpos allowed steps at a coord behind the last existing
+ * or, if that is at a line end, behind the line
+ * does not check for empty content!
+ */
+ void stepToEnd();
+
+ private:
+ /** layout, tells how the column is organized */
+ const KBufferLayout *Layout;
+
+ /** Position in buffer */
+ int Index;
+ /** Position and Line */
+ KBufferCoord Coord;
+
+ /** tells whether the cursor is actually behind the actual position.
+ * This is used for selection to the end of a line or of the whole buffer.
+ */
+ bool Behind : 1;
+
+ /** tells whether there could be a position behind the end of the layout */
+ bool AppendPosEnabled : 1;
+};
+
+
+inline int KBufferCursor::index() const { return Index; }
+inline int KBufferCursor::pos() const { return Coord.pos(); }
+inline int KBufferCursor::line() const { return Coord.line(); }
+inline KBufferCoord KBufferCursor::coord() const { return Coord; }
+inline bool KBufferCursor::isBehind() const { return Behind; }
+inline int KBufferCursor::realIndex() const { return Behind ? Index + 1 : Index; }
+
+inline void KBufferCursor::stepBehind() { Behind = true; }
+
+//inline bool KBufferCursor::isValid() const { return Index != -1; }
+
+}
+
+#endif
diff --git a/khexedit/lib/kbufferdrag.cpp b/khexedit/lib/kbufferdrag.cpp
new file mode 100644
index 0000000..199982c
--- /dev/null
+++ b/khexedit/lib/kbufferdrag.cpp
@@ -0,0 +1,237 @@
+/***************************************************************************
+ kbufferdrag.cpp - description
+ -------------------
+ begin : Mon Jul 07 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qcstring.h>
+#include <qtextcodec.h>
+// kde specific
+#include <kglobal.h>
+#include <klocale.h>
+// lib specific
+#include "kbordercoltextexport.h"
+#include "koffsetcoltextexport.h"
+#include "kvaluecoltextexport.h"
+#include "kcharcoltextexport.h"
+#include "kcharcodec.h"
+#include "kbufferdrag.h"
+
+
+using namespace std;
+using namespace KHE;
+
+static const char OctetStream[] = "application/octet-stream";
+static const char TextPlainUTF8[] = "text/plain;charset=UTF-8";
+static const char TextPlain[] = "text/plain";
+static const char TextPlainLocalStub[] = "text/plain;charset=";
+
+//static const char *BaseTypes[3] = { OctetStream, TextPlainUTF8, TextPlain };
+
+// creates the name for the local text/plain
+static const char *localTextPlain()
+{
+ static QCString TextPlainLocal;
+
+ if( TextPlainLocal.isNull() )
+ {
+ TextPlainLocal = QCString(KGlobal::locale()->encoding()).lower();
+ // remove the whitespaces
+ int s;
+ while( (s=TextPlainLocal.find(' ')) >= 0 )
+ TextPlainLocal.remove( s, 1 );
+
+ TextPlainLocal.prepend( TextPlainLocalStub );
+ }
+
+ return TextPlainLocal;
+}
+
+// tries to create a codec by the given charset description
+static QTextCodec* codecForCharset( const QCString& Desc )
+{
+ int i = Desc.find( "charset=" );
+ if( i >= 0 )
+ {
+ QCString CharSetName = Desc.mid( i+8 );
+ // remove any further attributes
+ if( (i=CharSetName.find( ';' )) >= 0 )
+ CharSetName = CharSetName.left( i );
+
+ // try to find codec
+ return QTextCodec::codecForName( CharSetName );
+ }
+ // no charset=, use locale
+ return KGlobal::locale()->codecForEncoding();
+}
+
+
+
+KBufferDrag::KBufferDrag( const QByteArray &D, KCoordRange Range,
+ const KOffsetColumn *OC, const KValueColumn *HC, const KCharColumn *TC,
+ QChar SC, QChar UC, const QString &CN,
+ QWidget *Source, const char *Name )
+ :QDragObject( Source, Name ),
+ CoordRange( Range ),
+ NoOfCol( 0 ),
+ SubstituteChar( SC ),
+ UndefinedChar( UC ),
+ CodecName( CN )
+{
+ setData( D );
+
+ // print column wise?
+ if( HC || TC )
+ {
+ if( OC )
+ {
+ Columns[NoOfCol++] = new KOffsetColTextExport( OC );
+ Columns[NoOfCol++] = new KBorderColTextExport();
+ }
+ if( HC )
+ Columns[NoOfCol++] = new KValueColTextExport( HC, Data.data(), CoordRange );
+ if( TC )
+ {
+ if( HC ) Columns[NoOfCol++] = new KBorderColTextExport();
+ Columns[NoOfCol++] = new KCharColTextExport( TC, Data.data(), CoordRange, CodecName );
+ }
+ }
+}
+
+
+KBufferDrag::~KBufferDrag()
+{
+ for( uint i=0; i<NoOfCol; ++i )
+ delete Columns[i];
+}
+
+
+
+void KBufferDrag::setData( const QByteArray &D )
+{
+ Data = D;
+}
+
+
+const char *KBufferDrag::format( int i ) const
+{
+ return( i == 0 ? OctetStream :
+ i == 1 ? TextPlainUTF8 :
+ i == 2 ? TextPlain :
+ i == 3 ? localTextPlain() :
+ 0 );
+}
+
+
+QByteArray KBufferDrag::encodedData( const char *Format ) const
+{
+ if( Format != 0 )
+ {
+ // octet stream wanted?
+ if( qstrcmp(Format,OctetStream) == 0 )
+ return( Data );
+
+ // plain text wanted?
+ if( qstrncmp(Format,TextPlain,10) == 0 )
+ {
+ QCString Output;
+ QTextCodec *TextCodec = codecForCharset( QCString(Format).lower() );
+ if( TextCodec == 0 )
+ return Output;
+
+ QString Text;
+ // plain copy?
+ if( NoOfCol == 0 )
+ {
+ // duplicate the data and substitute all non-printable items with a space
+ KCharCodec *CharCodec = KCharCodec::createCodec( CodecName );
+ static const QChar Tab('\t');
+ static const QChar Return('\n');
+ uint Size = Data.size();
+ Text.setLength( Size );
+
+ for( uint i=0; i<Size; ++i )
+ {
+ KHEChar B = CharCodec->decode( Data[i] );
+
+ Text.at(i) = B.isUndefined() ? KHEChar(UndefinedChar) :
+ (!B.isPrint() && B != Tab && B != Return ) ? KHEChar(SubstituteChar) : B;
+ }
+ // clean up
+ delete CharCodec;
+ }
+ // formatted copy
+ else
+ {
+ // initialize: one for the line's newline \n
+ uint NeededChars = 1;
+ for( uint i=0; i<NoOfCol; ++i )
+ NeededChars += Columns[i]->charsPerLine();
+ // scale with the number of lines
+ NeededChars *= CoordRange.lines();
+ // find out needed size
+ Text.reserve( NeededChars );
+
+ // now fill
+ int l = CoordRange.start().line();
+ for( uint i=0; i<NoOfCol; ++i )
+ Columns[i]->printFirstLine( Text, l );
+ Text.append('\n');
+ for( ++l; l<=CoordRange.end().line(); ++l )
+ {
+ for( uint i=0; i<NoOfCol; ++i )
+ Columns[i]->printNextLine( Text );
+ Text.append('\n');
+ }
+ }
+ // generate the ouput
+ Output = TextCodec->fromUnicode( Text );
+ // fix end
+ //if( TextCodec->mibEnum() != 1000 )
+ //{
+ // Don't include NUL in size (QCString::resize() adds NUL)
+ // ((QByteArray&)Output).resize( Output.length() );
+ //}
+ return Output;
+ }
+ }
+
+ // return empty dummy
+ return QByteArray();
+}
+
+
+
+bool KBufferDrag::canDecode( const QMimeSource* Source )
+{
+ bool c =( Source->provides(OctetStream) /*|| Source->provides(TextPlain)*/ );
+ return c;
+// return( Source->provides(OctetStream) /*|| Source->provides(TextPlain)*/ );
+}
+
+
+bool KBufferDrag::decode( const QMimeSource* Source, QByteArray &Dest )
+{
+// Dest = Source->encodedData( MediaString );
+// return Dest.size() != 0;
+
+ bool CanDecode = Source->provides( OctetStream );
+ if( CanDecode )
+ Dest = Source->encodedData( OctetStream );
+
+ return CanDecode;
+}
+
+#include "kbufferdrag.moc"
diff --git a/khexedit/lib/kbufferdrag.h b/khexedit/lib/kbufferdrag.h
new file mode 100644
index 0000000..86c498f
--- /dev/null
+++ b/khexedit/lib/kbufferdrag.h
@@ -0,0 +1,76 @@
+/***************************************************************************
+ kbufferdrag.h - description
+ -------------------
+ begin : Mon Jul 07 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_KBUFFERDRAG_H
+#define KHE_KBUFFERDRAG_H
+
+// qt specific
+#include <qdragobject.h>
+// lib specific
+#include "khe.h"
+#include "kcoordrange.h"
+#include "kcoltextexport.h"
+
+namespace KHE
+{
+
+// class KBorderColumn;
+class KOffsetColumn;
+class KValueColumn;
+class KCharColumn;
+
+typedef KColTextExport* KColTextExportPtr;
+/**
+ *@author Friedrich W. H. Kossebau
+ */
+class KBufferDrag : public QDragObject
+{
+ Q_OBJECT
+
+ public:
+ // TODO: make this call somewhat more generic
+ KBufferDrag( const QByteArray &, KCoordRange Range,
+ const KOffsetColumn *OC, const KValueColumn *HC, const KCharColumn *TC,
+ QChar SC, QChar UC, const QString &CN,
+ QWidget *Source = 0, const char *Name = 0 );
+ ~KBufferDrag();
+
+ public: // QDragObject API
+ virtual const char *format( int i ) const;
+ virtual QByteArray encodedData( const char* ) const;
+
+ public:
+ virtual void setData( const QByteArray &);
+
+ public:
+ static bool canDecode( const QMimeSource* Source );
+ static bool decode( const QMimeSource* Source, QByteArray &Dest );
+
+ protected:
+ QByteArray Data;
+ KCoordRange CoordRange;
+ /** collection of all the columns. All columns will be autodeleted. */
+ KColTextExportPtr Columns[5];
+ uint NoOfCol;
+ QChar SubstituteChar;
+ QChar UndefinedChar;
+ const QString &CodecName;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kbufferlayout.cpp b/khexedit/lib/kbufferlayout.cpp
new file mode 100644
index 0000000..a2ea9a0
--- /dev/null
+++ b/khexedit/lib/kbufferlayout.cpp
@@ -0,0 +1,240 @@
+/***************************************************************************
+ kbufferlayout.cpp - description
+ -------------------
+ begin : Thu Jun 12 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. *
+ * *
+ ***************************************************************************/
+
+
+#include "kbufferlayout.h"
+
+using namespace KHE;
+
+
+
+KBufferLayout::KBufferLayout( int NoBpL, int SO, int L )
+ : NoOfBytesPerLine( NoBpL ),
+ StartOffset( SO ),
+ Length( L )
+{
+ calcStart();
+ calcEnd();
+}
+
+
+KBufferLayout::~KBufferLayout()
+{
+}
+
+
+bool KBufferLayout::setStartOffset( int SO )
+{
+ // rejecting <0
+ if( SO < 0 )
+ SO = 0;
+
+ if( StartOffset == SO )
+ return false;
+
+ StartOffset = SO;
+
+ calcStart();
+ calcEnd();
+ return true;
+}
+
+
+bool KBufferLayout::setNoOfBytesPerLine( int N )
+{
+ // rejecting <1
+ if( N < 1 )
+ N = 1;
+
+ // no changes?
+ if( NoOfBytesPerLine == N )
+ return false;
+
+ NoOfBytesPerLine = N;
+
+ calcStart();
+ calcEnd();
+ return true;
+}
+
+
+bool KBufferLayout::setLength( int L )
+{
+ // rejecting < 0
+ if( L < 0 )
+ L = 0;
+
+ // no changes?
+ if( Length == L )
+ return false;
+
+ Length = L;
+
+ calcEnd();
+ return true;
+}
+
+
+void KBufferLayout::setNoOfLinesPerPage( int N )
+{
+ NoOfLinesPerPage = N;
+}
+
+
+void KBufferLayout::calcStart()
+{
+ ContentCoords.setStart( KBufferCoord(StartOffset,NoOfBytesPerLine,false) );
+}
+
+
+void KBufferLayout::calcEnd()
+{
+ ContentCoords.setEnd( (Length>0)?KBufferCoord(Length-1+StartOffset,NoOfBytesPerLine,false):
+ KBufferCoord(-1,ContentCoords.start().line()) );
+}
+
+
+int KBufferLayout::indexAtCLineStart( int L ) const
+{
+ return ( L <= ContentCoords.start().line() ) ? 0:
+ ( L > ContentCoords.end().line() ) ? Length-1:
+ L * NoOfBytesPerLine - StartOffset;
+}
+
+
+int KBufferLayout::indexAtCLineEnd( int L ) const
+{
+ return ( L < ContentCoords.start().line() ) ? 0:
+ ( L >= ContentCoords.end().line() ) ? Length-1:
+ (L+1)*NoOfBytesPerLine-StartOffset-1;
+}
+
+
+int KBufferLayout::indexAtCCoord( const KBufferCoord &C ) const
+{
+ int Index = indexAtCoord( C );
+
+ return ( Index <= 0 ) ? 0:
+ ( Index >= Length ) ? Length-1:
+ Index;
+}
+
+
+int KBufferLayout::lineAtCIndex( int Index ) const
+{
+ return ( Index <= 0 ) ? ContentCoords.start().line():
+ ( Index >= Length ) ? ContentCoords.end().line():
+ lineAtIndex(Index);
+}
+
+
+KBufferCoord KBufferLayout::coordOfCIndex( int Index ) const
+{
+ return ( Index <= 0 ) ? ContentCoords.start():
+ ( Index >= Length ) ? ContentCoords.end():
+ coordOfIndex(Index);
+}
+
+
+int KBufferLayout::indexAtLineStart( int L ) const
+{
+ return ( L == ContentCoords.start().line() ) ? 0 : L*NoOfBytesPerLine-StartOffset;
+}
+
+
+int KBufferLayout::indexAtLineEnd( int L ) const
+{
+ return ( L == ContentCoords.end().line() ) ? Length-1 : (L+1)*NoOfBytesPerLine-StartOffset-1;
+}
+
+
+int KBufferLayout::indexAtCoord( const KBufferCoord &C ) const
+{
+ return C.indexByLineWidth( NoOfBytesPerLine ) - StartOffset;
+}
+
+int KBufferLayout::lineAtIndex( int Index ) const
+{
+ return (Index+StartOffset)/NoOfBytesPerLine;
+}
+
+KBufferCoord KBufferLayout::coordOfIndex( int Index ) const
+{
+ return KBufferCoord( Index+StartOffset, NoOfBytesPerLine, false );
+}
+
+
+
+int KBufferLayout::correctIndex( int I ) const
+{
+ return ( I <= 0 ) ? 0:
+ ( I >= Length ) ? Length-1:
+ I;
+}
+
+
+KBufferCoord KBufferLayout::correctCoord( const KBufferCoord &C ) const
+{
+ return ( C <= ContentCoords.start() ) ? ContentCoords.start():
+ ( C >= ContentCoords.end() ) ? ContentCoords.end():
+ ( C.pos() >= NoOfBytesPerLine ) ? KBufferCoord( NoOfBytesPerLine-1, C.line() ):
+ C;
+}
+
+
+bool KBufferLayout::atLineStart( const KBufferCoord &C ) const
+{
+ return ( C.line() == ContentCoords.start().line() ) ? C.pos() == ContentCoords.start().pos():
+ C.pos() == 0;
+}
+
+bool KBufferLayout::atLineEnd( const KBufferCoord &C ) const
+{
+ return ( C.line() == ContentCoords.end().line() ) ? C.pos() == ContentCoords.end().pos():
+ C.pos() == NoOfBytesPerLine-1;
+}
+
+
+KSection KBufferLayout::positions( int Line ) const
+{
+ return KSection( firstPos(Line), lastPos(Line) );
+}
+
+
+int KBufferLayout::firstPos( const KBufferCoord &C ) const
+{
+ return ( ContentCoords.start().isLaterInLineThan(C) ) ? ContentCoords.start().pos() : C.pos();
+}
+
+int KBufferLayout::lastPos( const KBufferCoord &C ) const
+{
+ return ( ContentCoords.end().isPriorInLineThan(C) ) ? ContentCoords.end().pos() : C.pos();
+}
+
+int KBufferLayout::firstPos( int Line ) const
+{
+ return Line == ContentCoords.start().line() ? ContentCoords.start().pos() : 0;
+}
+
+int KBufferLayout::lastPos( int Line ) const
+{
+ return ( Line == ContentCoords.end().line() ) ? ContentCoords.end().pos() : NoOfBytesPerLine-1;
+}
+
+bool KBufferLayout::hasContent( int Line ) const
+{
+ return ContentCoords.includesLine( Line );
+}
diff --git a/khexedit/lib/kbufferlayout.h b/khexedit/lib/kbufferlayout.h
new file mode 100644
index 0000000..c243225
--- /dev/null
+++ b/khexedit/lib/kbufferlayout.h
@@ -0,0 +1,196 @@
+/***************************************************************************
+ kbufferlayout.h - description
+ -------------------
+ begin : Thu Jun 12 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_KBUFFERLAYOUT_H
+#define KHE_KBUFFERLAYOUT_H
+
+// lib specific
+#include "kcoordrange.h"
+#include "ksection.h"
+
+namespace KHE {
+
+/**@short the logical layout of a plain buffer view
+ *
+ * Given the values for
+ * * length of the buffer,
+ * * number of bytes per line,
+ * * a possible (relative) offset in the display, and
+ * * the number of lines per page jump
+ * the following values are calculated:
+ * * starting line of display,
+ * * starting position in this line,
+ * * final line of display,
+ * * final position in this line, and
+ * * the total number of lines (is final line +1 or 0)
+ *
+ * This layout sees the buffer as a continous stream of byte,
+ * thus uses each line after the start from the begin to the end.
+ *
+ * If the buffer is empty the end coord will be set one pos left to the start coord
+ * to easen the cursor handling.
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+class KBufferLayout
+{
+ public:
+ KBufferLayout( int NoBpL, int SO, int L );
+ //KBufferLayout();
+ ~KBufferLayout();
+
+
+ public: // given values
+ /** */
+ int startOffset() const;
+ /** returns number of bytes per line */
+ int noOfBytesPerLine() const;
+ /** returns the length of the displayed data (equals Buffer->size()) */
+ int length() const;
+ /** returns number of lines per visual page */
+ int noOfLinesPerPage() const;
+
+ public: // calculated values
+ int startLine() const;
+ int startPos() const;
+ /** returns the coord of the start */
+ KBufferCoord start() const;
+
+ int finalLine() const;
+ int finalPos() const;
+ /** returns the coord of the end */
+ KBufferCoord final() const;
+
+ /** tells how much lines this layout needs (incl. blank leading lines due to StartOffset) */
+ int noOfLines() const;
+
+
+ public: // value calculation service
+ /** calculates the index of the coord
+ * If the coord is before the first coord the first index is returned,
+ * if the coord is behind the last coord the last index is returned
+ */
+ int indexAtCCoord( const KBufferCoord &C ) const;
+ /** calculates the index of the first pos in line.
+ * If the line is below the first line the first index is returned,
+ * if the line is above the last line the last index is returned
+ */
+ int indexAtCLineStart( int L ) const;
+ /** calculates the index of last pos in line
+ * If the line is below the first line the first index is returned,
+ * if the line is above the last line the last index is returned
+ */
+ int indexAtCLineEnd( int L ) const;
+ /** calculates the line in which index is found
+ * If the index is below the first index the first line is returned,
+ * if the index is above the last index the last line is returned
+ */
+ int lineAtCIndex( int Index ) const;
+ /** calculates the coord in which index is found
+ * If the index is below the first index the first coord is returned,
+ * if the index is above the last index the last coord is returned
+ */
+ KBufferCoord coordOfCIndex( int Index ) const;
+
+ /** calculates the index of coord. if coord is invalid the behaviour is undefinded */
+ int indexAtCoord( const KBufferCoord &C ) const;
+ /** calculates the index of the first pos in line. if line is invalid the behaviour is undefinded */
+ int indexAtLineStart( int L ) const;
+ /** calculates the index of last pos in line. if line is invalid the behaviour is undefinded */
+ int indexAtLineEnd( int L ) const;
+ /** calculates the line in which index is found. if index is invalid the behaviour is undefinded */
+ int lineAtIndex( int Index ) const;
+ /** calculates the coord in which index is found. if index is invalid the behaviour is undefinded */
+ KBufferCoord coordOfIndex( int Index ) const;
+
+ /** returns the used positions in line */
+ KSection positions( int Line ) const;
+ /** returns the first Pos in line. if line is invalid the behaviour is undefinded */
+ int firstPos( int Line ) const;
+ /** returns the last Pos in line. if line is invalid the behaviour is undefinded */
+ int lastPos( int Line ) const;
+ /** returns the valid Pos or the first Pos in line. if coord is invalid the behaviour is undefinded */
+ int firstPos( const KBufferCoord &C ) const;
+ /** returns the valid Pos or the last Pos in line. if coord is invalid the behaviour is undefinded */
+ int lastPos( const KBufferCoord &C ) const;
+ /** returns true if the line has content */
+ bool hasContent( int Line ) const;
+ /** returns true if the coord is the first in it's line. if coord is invalid the behaviour is undefinded */
+ bool atLineStart( const KBufferCoord &C ) const;
+ /** returns true if the coord is the last in it's line. if coord is invalid the behaviour is undefinded */
+ bool atLineEnd( const KBufferCoord &C ) const;
+
+ /** returns the index if valid or the nearest valid index */
+ int correctIndex( int I ) const;
+ /** returns the coord if valid or the nearest valid coord */
+ KBufferCoord correctCoord( const KBufferCoord &C ) const;
+
+
+ public: // modification access; return true if changes
+ /** sets StartOffset, returns true if changed */
+ bool setStartOffset( int SO );
+ /** sets number of bytes per line, returns true if changed */
+ bool setNoOfBytesPerLine( int N );
+ /** sets number of lines per page */
+ void setNoOfLinesPerPage( int N );
+ /** sets length of data to display, returns true if changed */
+ bool setLength( int L );
+
+
+ protected:
+ /** calculates the start coord by startoffset and number of bytes per line */
+ void calcStart();
+ /** calculates the final coord by startoffset, length, and number of bytes per line */
+ void calcEnd();
+
+
+ protected:
+ /** how many chars per line */
+ int NoOfBytesPerLine;
+ /** starting offset of the displayed data */
+ int StartOffset;
+ /** length of the displayed buffer */
+ int Length;
+ /** number of lines that are moved by page up/down */
+ int NoOfLinesPerPage;
+
+ protected: // calculated values, buffered
+ /** coord in which the start offset is (starting with 0) */
+// KBufferCoord Start;
+ /** coord in which the last byte is (starting with 0) */
+// KBufferCoord Final;
+ /** */
+ KCoordRange ContentCoords;
+};
+
+
+inline int KBufferLayout::startOffset() const { return StartOffset; }
+inline int KBufferLayout::noOfBytesPerLine() const { return NoOfBytesPerLine; }
+inline int KBufferLayout::length() const { return Length; }
+
+inline KBufferCoord KBufferLayout::final() const { return ContentCoords.end(); }
+inline KBufferCoord KBufferLayout::start() const { return ContentCoords.start(); }
+inline int KBufferLayout::startPos() const { return start().pos(); }
+inline int KBufferLayout::finalPos() const { return final().pos(); }
+inline int KBufferLayout::startLine() const { return start().line(); }
+inline int KBufferLayout::finalLine() const { return final().line(); }
+inline int KBufferLayout::noOfLinesPerPage() const { return NoOfLinesPerPage; }
+inline int KBufferLayout::noOfLines() const { return Length==0?0:final().line()+1; }
+
+}
+
+#endif
diff --git a/khexedit/lib/kbufferranges.cpp b/khexedit/lib/kbufferranges.cpp
new file mode 100644
index 0000000..57fb9c4
--- /dev/null
+++ b/khexedit/lib/kbufferranges.cpp
@@ -0,0 +1,307 @@
+/***************************************************************************
+ kbufferranges.cpp - description
+ -------------------
+ begin : Sun Jun 22 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. *
+ * *
+ ***************************************************************************/
+
+
+//#include <kdebug.h>
+
+// lib specific
+#include "kbufferranges.h"
+
+
+using namespace KHE;
+
+KBufferRanges::KBufferRanges( KBufferLayout *L )
+ : Modified( false ),
+ Layout( L )
+{
+}
+
+
+KBufferRanges::~KBufferRanges()
+{
+}
+
+
+void KBufferRanges::reset()
+{
+ Selection.cancel();
+ FirstWordSelection.unset();
+ Marking.unset();
+ ChangedRanges.clear();
+}
+
+
+void KBufferRanges::setMarking( KSection M )
+{
+ if( Marking == M )
+ return;
+
+ Marking = M;
+ addChangedRange( M );
+}
+
+
+void KBufferRanges::removeFurtherSelections()
+{
+ for( int i = 1; i < noOfSelections(); ++i )
+ removeSelection( i );
+}
+
+
+void KBufferRanges::setSelection( KSection S )
+{
+ bool Changed = Selection.isValid();
+ if( Changed )
+ addChangedRange( Selection );
+ Selection = S;
+ addChangedRange( Selection );
+}
+
+void KBufferRanges::setSelectionStart( int StartIndex )
+{
+ bool Changed = Selection.isValid();
+ if( Changed )
+ addChangedRange( Selection );
+
+ Selection.setStart( StartIndex );
+}
+
+
+void KBufferRanges::setSelectionEnd( int EndIndex )
+{
+ KSection OldSelection = Selection;
+ Selection.setEnd( EndIndex );
+
+ // TODO: think about rather building a diff of the sections
+ if( !OldSelection.isValid() )
+ {
+ addChangedRange( Selection );
+ return;
+ }
+ if( !Selection.isValid() )
+ {
+ addChangedRange( OldSelection );
+ return;
+ }
+
+ if( OldSelection == Selection )
+ return;
+ int CS_;
+ int CE_;
+ // changes at the end?
+ if( Selection.start() == OldSelection.start() )
+ {
+ CS_ = OldSelection.end()+1;
+ CE_ = Selection.end();
+ if( CE_ < CS_ )
+ {
+ CS_ = Selection.end()+1;
+ CE_ = OldSelection.end();
+ }
+ }
+ // changes at the start?
+ else if( Selection.end() == OldSelection.end() )
+ {
+ CS_ = OldSelection.start();
+ CE_ = Selection.start()-1;
+ if( CE_ < CS_ )
+ {
+ CS_ = Selection.start();
+ CE_ = OldSelection.start()-1;
+ }
+ }
+ // change over the anchor
+ else
+ {
+ CS_ = OldSelection.start();
+ CE_ = Selection.end();
+ if( CE_ < CS_ )
+ {
+ CS_ = Selection.start();
+ CE_ = OldSelection.end();
+ }
+ }
+ KSection C( CS_, CE_ );
+
+ bool Changed = C.isValid();
+ if( Changed )
+ addChangedRange( C );
+ return;
+}
+
+
+void KBufferRanges::removeSelection( int id )
+{
+ if( id > 0 )
+ return;
+
+ bool Changed = Selection.isValid();
+ if( Changed )
+ addChangedRange( Selection );
+
+ Selection.cancel();
+ FirstWordSelection.unset();
+}
+
+
+bool KBufferRanges::overlapsSelection( int FirstIndex, int LastIndex, int *SI, int *EI ) const
+{
+ if( Selection.overlaps(KSection(FirstIndex,LastIndex)) )
+ {
+ *SI = Selection.start();
+ *EI = Selection.end();
+ return true;
+ }
+ return false;
+}
+
+
+bool KBufferRanges::overlapsMarking( int FirstIndex, int LastIndex, int *SI, int *EI ) const
+{
+ if( Marking.overlaps(KSection(FirstIndex,LastIndex)) )
+ {
+ *SI = Marking.start();
+ *EI = Marking.end();
+ return true;
+ }
+ return false;
+}
+
+
+const KSection *KBufferRanges::firstOverlappingSelection( KSection Range ) const
+{
+ if( Selection.overlaps(Range) )
+ return &Selection;
+
+ return 0L;
+}
+
+
+const KSection *KBufferRanges::overlappingMarking( KSection Range ) const
+{
+ if( Marking.overlaps(Range) )
+ return &Marking;
+
+ return 0L;
+}
+
+/*
+bool KBufferRanges::overlapsChanges( int FirstIndex, int LastIndex, int *SI, int *EI ) const
+{
+ for( KCoordRangeList::const_iterator S=ChangedRanges.begin(); S!=ChangedRanges.end(); ++S )
+ {
+ if( (*S).overlaps(KBuff(FirstIndex,LastIndex)) )
+ {
+ *SI = (*S).start();
+ *EI = (*S).end();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool KBufferRanges::overlapsChanges( KSection Indizes, KSection *ChangedRange ) const
+{
+ for( KSectionList::const_iterator S=ChangedRanges.begin(); S!=ChangedRanges.end(); ++S )
+ {
+ if( (*S).overlaps(Indizes) )
+ {
+ *ChangedRange = *S;
+ return true;
+ }
+ }
+
+ return false;
+}
+*/
+bool KBufferRanges::overlapsChanges( const KCoordRange &Range, KCoordRange *ChangedRange ) const
+{
+ // TODO: add a lastusedrange pointer for quicker access
+ for( KCoordRangeList::const_iterator R=ChangedRanges.begin(); R!=ChangedRanges.end(); ++R )
+ {
+ if( (*R).overlaps(Range) )
+ {
+ *ChangedRange = *R;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+void KBufferRanges::addChangedRange( int SI, int EI )
+{
+ addChangedRange( KSection(SI,EI) );
+}
+
+
+void KBufferRanges::addChangedRange( KSection S )
+{
+ addChangedRange( KCoordRange(Layout->coordOfIndex(S.start()),Layout->coordOfIndex(S.end())) );
+}
+
+
+void KBufferRanges::addChangedRange( const KCoordRange &NewRange )
+{
+ ChangedRanges.addCoordRange( NewRange );
+
+ Modified = true;
+}
+
+
+void KBufferRanges::removeMarking()
+{
+ bool Changed = Marking.isValid();
+ if( Changed )
+ addChangedRange( Marking );
+
+ Marking.unset();
+}
+
+
+void KBufferRanges::resetChangedRanges()
+{
+ ChangedRanges.clear();
+ Modified = false;
+}
+
+
+void KBufferRanges::setFirstWordSelection( KSection Section )
+{
+ FirstWordSelection = Section;
+ setSelection( FirstWordSelection );
+}
+
+ void KBufferRanges::ensureWordSelectionForward( bool Forward )
+ {
+ // in the anchor not on the right side?
+ if( Selection.isForward() != Forward )
+ {
+ if( Forward )
+ {
+ setSelectionEnd( FirstWordSelection.start() );
+ Selection.setForward();
+ }
+ else
+ {
+ setSelectionEnd( FirstWordSelection.end()+1 );
+ Selection.setBackward();
+ }
+ }
+ }
+
diff --git a/khexedit/lib/kbufferranges.h b/khexedit/lib/kbufferranges.h
new file mode 100644
index 0000000..ed2cbce
--- /dev/null
+++ b/khexedit/lib/kbufferranges.h
@@ -0,0 +1,130 @@
+/***************************************************************************
+ kbufferranges.h - description
+ -------------------
+ begin : Sun Jun 22 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_KBUFFERRANGES_H
+#define KHE_KBUFFERRANGES_H
+
+// lib specific
+#include "kbufferlayout.h"
+#include "kselection.h"
+#include "ksectionlist.h"
+#include "kcoordrangelist.h"
+
+namespace KHE
+{
+
+/** a class to control all the ranges like marking and selections
+ * holds also all modified ranges and merges them so a repaint can take its info from here
+ *
+ * @author Friedrich W. H. Kossebau
+ */
+class KBufferRanges
+{
+ public:
+ KBufferRanges( KBufferLayout *L );
+ ~KBufferRanges();
+
+ public: // modifcation access
+ void setMarking( KSection M );
+ void setSelectionStart( int StartIndex );
+ void setSelectionEnd( int StartIndex );
+ void setSelection( KSection S );
+ /** */
+ void setFirstWordSelection( KSection S );
+ /** */
+ void ensureWordSelectionForward( bool Forward );
+
+ /** removes marking and returns true if something changed */
+ void removeMarking();
+ /** removes selection with id and returns true if something changed */
+ void removeSelection( int id = 0 );
+ /** removes all but the standard selection and returns true if something changed */
+ void removeFurtherSelections();
+
+ void addChangedRange( KSection S );
+ void addChangedRange( int SI, int EI );
+ void addChangedRange( const KCoordRange &NewRange );
+ void resetChangedRanges();
+
+ void setModified( bool M = true );
+ /** removes all ranges */
+ void reset();
+
+ public: // value access
+ int noOfSelections() const;
+ int selectionStart() const;
+ int selectionEnd() const;
+ KSection selection() const;
+ KSection firstWordSelection() const;
+ int selectionLength() const;
+ bool isModified() const;
+
+ public: // calculated logic access
+ bool hasSelection() const;
+ bool hasMarking() const;
+ bool selectionStarted() const;
+ bool selectionJustStarted() const;
+ bool hasFirstWordSelection() const;
+ bool selectionIncludes( int Index ) const;
+ bool markingIncludes( int Index ) const;
+ // TODO: next three are deprecated
+ bool overlapsSelection( int FirstIndex, int LastIndex, int *SI, int *EI ) const;
+ bool overlapsMarking( int FirstIndex, int LastIndex, int *SI, int *EI ) const;
+// bool overlapsChanges( int FirstIndex, int LastIndex, int *SI, int *EI ) const;
+// bool overlapsChanges( KSection Indizes, KSection *ChangedRange ) const;
+ bool overlapsChanges( const KCoordRange &Range, KCoordRange *ChangedRange ) const;
+ const KSection *firstOverlappingSelection( KSection Range ) const;
+ const KSection *overlappingMarking( KSection Range ) const;
+
+
+ protected:
+ /** true if something changed */
+ bool Modified;
+
+ KSection Marking;
+ KSelection Selection;
+ /** memories first selected word on wordwise selection */
+ KSection FirstWordSelection;
+
+ KCoordRangeList ChangedRanges;
+
+ KBufferLayout *Layout;
+};
+
+
+inline int KBufferRanges::noOfSelections() const { return 1; }
+
+inline int KBufferRanges::selectionStart() const { return Selection.start(); }
+inline int KBufferRanges::selectionEnd() const { return Selection.end(); }
+inline KSection KBufferRanges::selection() const { return Selection; }
+inline KSection KBufferRanges::firstWordSelection() const { return FirstWordSelection; }
+inline int KBufferRanges::selectionLength() const { return Selection.width(); }
+inline bool KBufferRanges::isModified() const { return Modified; }
+
+inline bool KBufferRanges::hasSelection() const { return Selection.isValid(); }
+inline bool KBufferRanges::selectionStarted() const { return Selection.started(); }
+inline bool KBufferRanges::selectionJustStarted() const { return Selection.justStarted(); }
+inline bool KBufferRanges::hasFirstWordSelection() const { return FirstWordSelection.isValid(); }
+inline bool KBufferRanges::hasMarking() const { return Marking.isValid(); }
+inline bool KBufferRanges::selectionIncludes( int Index ) const { return Selection.includes( Index ); }
+inline bool KBufferRanges::markingIncludes( int Index ) const { return Marking.includes( Index ); }
+
+inline void KBufferRanges::setModified( bool M ) { Modified = M; }
+
+}
+
+#endif
diff --git a/khexedit/lib/kbytecodec.h b/khexedit/lib/kbytecodec.h
new file mode 100644
index 0000000..fc4e1b3
--- /dev/null
+++ b/khexedit/lib/kbytecodec.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ kbytecodec.h - description
+ -------------------
+ begin : Sam Mai 17 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_KBYTECODEC_H
+#define KHE_KBYTECODEC_H
+
+#include "khe.h"
+#include <qstring.h>
+
+namespace KHE
+{
+
+/** class that is able to convert codings to and from
+ * hexadecimal, decimal, octal, and binary
+ *
+ * the buffer will be always filled up to CodingWidth, if not using shortCodingFunction
+ * a closing '\0' will be always added
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KByteCodec
+{
+ public:
+ static KByteCodec *createCodec( KCoding C );
+
+
+ protected: // hiding, as this class should never be instanciated
+ KByteCodec() {}
+
+ public: // API to be implemented
+ /** */
+ virtual unsigned int encodingWidth() const = 0;
+ /** */
+ virtual unsigned char digitsFilledLimit() const = 0;
+
+ /** encodes the Char and writes the result to */
+ virtual void encode( QString &Digits, unsigned int Pos, const unsigned char Char ) const = 0;
+ /** */
+ virtual void encodeShort( QString &Digits, unsigned int Pos, const unsigned char Char ) const = 0;
+
+ /** */
+ virtual bool appendDigit( unsigned char *Byte, const unsigned char Digit ) const = 0;
+ /** */
+ virtual void removeLastDigit( unsigned char *Byte ) const = 0;
+ /** */
+ virtual bool isValidDigit( const unsigned char Digit ) const = 0;
+ /** */
+ virtual bool turnToValue( unsigned char *Digit ) const = 0;
+
+
+ public:
+ /** */
+ uint decode( unsigned char *Char, const QString &Digits, uint Pos ) const;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kbytesedit.cpp b/khexedit/lib/kbytesedit.cpp
new file mode 100644
index 0000000..40b57a1
--- /dev/null
+++ b/khexedit/lib/kbytesedit.cpp
@@ -0,0 +1,162 @@
+/***************************************************************************
+ kbytesedit.cpp - description
+ -------------------
+ begin : Die Jul 9 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kplainbuffer.h"
+#include "kbytesedit.h"
+#include "kbufferranges.h"
+#include "kbuffercursor.h"
+
+using namespace KHE;
+
+
+KBytesEdit::KBytesEdit( char *D, int DS_, int RS_, bool KM, QWidget *Parent, const char *Name, WFlags F )
+ : KHexEdit( 0L, Parent, Name, F ),
+ AutoDelete( false )
+{
+ setData( D, DS_, RS_, KM );
+}
+
+KBytesEdit::KBytesEdit( char *D, int DS_, QWidget *Parent, const char *Name, WFlags F )
+ : KHexEdit( 0L, Parent, Name, F ),
+ AutoDelete( false )
+{
+ setData( D, DS_ );
+}
+
+
+KBytesEdit::KBytesEdit( QWidget *Parent, const char *Name, WFlags F )
+ : KHexEdit( 0L, Parent, Name, F ),
+ AutoDelete( false )
+{
+ setDataBuffer( new KPlainBuffer() );
+}
+
+KBytesEdit::~KBytesEdit()
+{
+ clean();
+}
+
+void KBytesEdit::setReadOnly( bool RO )
+{
+ KPlainBuffer *Buffer = dynamic_cast<KPlainBuffer *>(DataBuffer);
+ if( Buffer )
+ Buffer->setReadOnly( RO );
+ KHexEdit::setReadOnly( RO );
+}
+
+
+void KBytesEdit::setAutoDelete( bool AD )
+{
+ AutoDelete = AD;
+}
+
+
+char *KBytesEdit::data() const
+{
+ KPlainBuffer *Buffer = dynamic_cast<KPlainBuffer *>(DataBuffer);
+ return Buffer ? Buffer->data() : 0L;
+}
+
+
+void KBytesEdit::setData( char *D, int S, int RS_, bool KM )
+{
+ KPlainBuffer *NewBuffer = new KPlainBuffer( D, S, RS_, KM );
+ if( DataBuffer )
+ {
+ // take the settings
+ NewBuffer->setReadOnly( DataBuffer->isReadOnly() );
+ clean();
+ }
+ else
+ NewBuffer->setReadOnly( isReadOnly() );
+
+ setDataBuffer( NewBuffer );
+}
+
+
+int KBytesEdit::dataSize() const
+{
+ KPlainBuffer *Buffer = dynamic_cast<KPlainBuffer *>(DataBuffer);
+ return Buffer ? Buffer->size() : -1;
+}
+
+
+int KBytesEdit::maxDataSize() const
+{
+ KPlainBuffer *Buffer = dynamic_cast<KPlainBuffer *>(DataBuffer);
+ return Buffer ? Buffer->maxSize() : -1;
+}
+
+
+void KBytesEdit::setMaxDataSize( int MS )
+{
+ KPlainBuffer *Buffer = dynamic_cast<KPlainBuffer *>(DataBuffer);
+ if( Buffer )
+ Buffer->setMaxSize( MS );
+}
+
+
+bool KBytesEdit::keepsMemory() const
+{
+ KPlainBuffer *Buffer = dynamic_cast<KPlainBuffer *>(DataBuffer);
+ return Buffer ? Buffer->keepsMemory() : false;
+}
+
+
+void KBytesEdit::setKeepsMemory( bool KM )
+{
+ KPlainBuffer *Buffer = dynamic_cast<KPlainBuffer *>(DataBuffer);
+ if( Buffer )
+ Buffer->setKeepsMemory( KM );
+}
+
+
+bool KBytesEdit::isAutoDelete() const { return AutoDelete; }
+
+
+void KBytesEdit::repaintRange( int i1, int i2 )
+{
+ bool ChangeCursor = !(CursorPaused) && KSection(i1,i2).includes( BufferCursor->index() );
+ if( ChangeCursor )
+ pauseCursor();
+
+ BufferRanges->addChangedRange( i1, i2 );
+
+ repaintChanged();
+
+ if( ChangeCursor )
+ unpauseCursor();
+}
+
+
+void KBytesEdit::clean()
+{
+ if( DataBuffer )
+ {
+ if( AutoDelete )
+ {
+ char *D = data();
+ if( D )
+ delete [] D;
+ }
+ delete DataBuffer;
+ }
+}
+
+
+#include "kbytesedit.moc"
diff --git a/khexedit/lib/kbytesedit.h b/khexedit/lib/kbytesedit.h
new file mode 100644
index 0000000..daf8b6e
--- /dev/null
+++ b/khexedit/lib/kbytesedit.h
@@ -0,0 +1,163 @@
+/***************************************************************************
+ kbytesedit.h - description
+ -------------------
+ begin : Die Jul 9 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_KBYTESEDIT_H
+#define KHE_KBYTESEDIT_H
+
+
+#include "khexedit.h"
+
+#include <khexedit_export.h>
+
+namespace KHE
+{
+
+class KDataBuffer;
+class KBytesEditPrivate;
+
+/** the beginner's hex edit widget ;)
+ *
+ * It hides the concept of the KDataBuffer and accepts a pure pointer
+ * to a reasonable large array of bytes
+ *
+ * 1. used as viewer
+ * a) static data ranges -> no changes for data pointer and length
+ * possible changes are told to the widget by repaintRange
+ * b) changing data ranges -> data pointer and length might change
+ * changes told by
+ * * resetData( char *, int size, bool repaint );
+ * *
+ * 2. used as editor
+ * a) static data ranges
+ * data pointer stays the same
+ * b) changing data ranges
+ * pointer to the data changes in charge of the widget:
+ * given pointer and intermediate pointer are possibly invalid
+ * problem: who cares about the array if the data is deleted?
+ * -> solved by setAutoDelete()
+ *
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+//TODO: give the bytes edit widget an empty buffer as default
+class KHEXEDIT_EXPORT KBytesEdit : public KHexEdit
+{
+ Q_OBJECT
+ //_PROPERTY( char * Data READ data )
+ Q_PROPERTY( int DataSize READ dataSize )
+ Q_PROPERTY( int MaxDataSize READ maxDataSize WRITE setMaxDataSize )
+ Q_PROPERTY( bool AutoDelete READ isAutoDelete WRITE setAutoDelete DESIGNABLE false )
+
+
+ public:
+ /** creates a new widget to view/edit data
+ * @param D pointer to memory
+ * @param S size of used memory
+ * @param RS_ real size of the memory
+ * @param KM keep the memory on resize (RS_ is then the maximum size)
+ * @param Parent parent widget
+ * @param Name name for this widget
+ * @param F flags
+ */
+ KBytesEdit( char *D, int DS_, int RS_, bool KM, QWidget *Parent = 0, const char *Name = 0, WFlags F = 0 );
+ /** hands over to the editor a new byte array.
+ * If there exists an old one and autodelete is set the old one gets deleted.
+ * @param D pointer to memory
+ * @param S size of used memory
+ * @param RS_ real size of the memory
+ * @param KM keep the memory on resize (RS_ is the maximum size)
+ */
+ KBytesEdit( char *D, int DS_, QWidget *Parent = 0, const char *Name = 0, WFlags F = 0 );
+ /** hands over to the editor a new byte array.
+ * If there exists an old one and autodelete is set the old one gets deleted.
+ * @param D pointer to memory
+ * @param S size of used memory
+ * @param RS_ real size of the memory
+ * @param KM keep the memory on resize (RS_ is the maximum size)
+ */
+ KBytesEdit( QWidget *Parent = 0, const char *Name = 0, WFlags F = 0 );
+ virtual ~KBytesEdit();
+
+
+ public: // value access
+ /** returns the pointer to the actual byte array. This can be but must not be the one
+ * that was given in the constructor.
+ */
+ char *data() const;
+ /** returns the size of the actual byte array */
+ int dataSize() const;
+ /** returns the maximal allowed size for the byte array */
+ int maxDataSize () const;
+ /** returns whether autodelete is set for the byte array */
+ bool isAutoDelete() const;
+ /** returns whether the memory of the byte array is kept */
+ bool keepsMemory() const;
+
+ public: // logic value service
+
+ public: // modification access
+
+ public slots:
+ /** hands over to the editor a new byte array.
+ * If there exists an old one and autodelete is set the old one gets deleted.
+ * @param D pointer to memory
+ * @param S size of used memory
+ * @param RS_ real size of the memory
+ * @param KM keep the memory on resize (RS_ is the maximum size)
+ */
+ void setData( char *D, int S, int RS_ = -1, bool KM = true );
+
+ /** sets whether the given array should be handled read only or not */
+ virtual void setReadOnly( bool RO = true );
+ /** sets the maximal size of the actual byte array. If the actual array is already larger
+ * it will not be modified but there can be only done non-inserting actions
+ * until the array's is below the limit
+ */
+ void setMaxDataSize( int MS );
+ /** sets whether the array should be deleted on the widget's end or if a new array is set.
+ * Default is false
+ */
+ void setAutoDelete( bool AD = true );
+ /** sets whether the memory given by setData or in the constructor should be kept on resize
+ */
+ void setKeepsMemory( bool KM = true );
+
+ /** repaint the indizes from i1 to i2 */
+ void repaintRange( int i1, int i2 );
+
+ protected:
+ /** deletes the databuffer */
+ void clean();
+
+
+ protected slots:
+
+
+ protected:
+ /** */
+ bool AutoDelete:1;
+ /** */
+ KBytesEditPrivate *d;
+
+ private: // Disabling copy constructor and operator= - not useful
+ KBytesEdit( const KBytesEdit & );
+ KBytesEdit &operator=( const KBytesEdit & );
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kcharcodec.h b/khexedit/lib/kcharcodec.h
new file mode 100644
index 0000000..9d1b628
--- /dev/null
+++ b/khexedit/lib/kcharcodec.h
@@ -0,0 +1,55 @@
+/***************************************************************************
+ kcharcodec.h - description
+ -------------------
+ begin : Do Nov 25 2004
+ copyright : (C) 2004 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_KCHARCODEC_H
+#define KHE_KCHARCODEC_H
+
+// qt specific
+#include <qstringlist.h>
+// lib specific
+#include "khe.h"
+#include "khechar.h"
+#include "khexedit_export.h"
+
+
+namespace KHE
+{
+
+class KHEXEDIT_EXPORT KCharCodec
+{
+ public:
+ /** */
+ static KCharCodec* createCodec( KEncoding E );
+ /** */
+ static KCharCodec* createCodec( const QString &Name );
+
+ static const QStringList &codecNames();
+
+ public: // API to be implemented
+ virtual KHEChar decode( char Byte ) const = 0;
+ virtual bool encode( char *D, const QChar &C ) const = 0;
+ virtual const QString& name() const = 0;
+
+ protected:
+ /** */
+ static QStringList CodecNames;
+};
+
+}
+
+#endif
+
diff --git a/khexedit/lib/kcharcoltextexport.cpp b/khexedit/lib/kcharcoltextexport.cpp
new file mode 100644
index 0000000..bc4a60e
--- /dev/null
+++ b/khexedit/lib/kcharcoltextexport.cpp
@@ -0,0 +1,71 @@
+/***************************************************************************
+ kcharcoltextexport.cpp - description
+ -------------------
+ begin : Wed Sep 03 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kbufferlayout.h"
+#include "kcharcolumn.h"
+#include "kcharcodec.h"
+#include "kcharcoltextexport.h"
+
+using namespace KHE;
+
+
+KCharColTextExport::KCharColTextExport( const KCharColumn* TC, const char *D, KCoordRange CR, const QString &CodecName )
+ : KBufferColTextExport( TC, D, CR, 1 ),
+ CharCodec( KCharCodec::createCodec(CodecName) ),
+ SubstituteChar( TC->substituteChar() ),
+ UndefinedChar( TC->undefinedChar() )
+{
+}
+
+
+KCharColTextExport::~KCharColTextExport()
+{
+ delete CharCodec;
+}
+
+
+void KCharColTextExport::print( QString &T ) const
+{
+ int p = 0;
+ int pEnd = NoOfBytesPerLine;
+ // correct boundaries
+ if( PrintLine == CoordRange.start().line() )
+ p = CoordRange.start().pos();
+ if( PrintLine == CoordRange.end().line() )
+ pEnd = CoordRange.end().pos()+1;
+
+ // draw individual chars
+ uint e = 0;
+ for( ; p<pEnd; ++p, ++PrintData )
+ {
+ // get next position
+ uint t = Pos[p];
+ // clear spacing
+ T.append( whiteSpace(t-e) );
+
+ // print char
+ KHEChar B = CharCodec->decode( *PrintData );
+
+ T.append( B.isUndefined() ? KHEChar(UndefinedChar) : !B.isPrint() ? KHEChar(SubstituteChar) : B );
+ e = t + 1;
+ }
+
+ T.append( whiteSpace(NoOfCharsPerLine-e) );
+
+ ++PrintLine;
+}
diff --git a/khexedit/lib/kcharcoltextexport.h b/khexedit/lib/kcharcoltextexport.h
new file mode 100644
index 0000000..05a570c
--- /dev/null
+++ b/khexedit/lib/kcharcoltextexport.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ kcharcoltextexport.h - description
+ -------------------
+ begin : Wed Sep 3 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_KCHARCOLTEXTEXPORT_H
+#define KHE_KCHARCOLTEXTEXPORT_H
+
+// lib specific
+#include "khe.h"
+#include "kbuffercoltextexport.h"
+
+
+namespace KHE
+{
+
+class KCharColumn;
+class KCharCodec;
+
+
+class KCharColTextExport : public KBufferColTextExport
+{
+ public:
+ KCharColTextExport( const KCharColumn* BF, const char *D, KCoordRange CR, const QString &CodecName );
+ virtual ~KCharColTextExport();
+
+ protected: //API
+ virtual void print( QString &T ) const;
+
+ protected:
+ KCharCodec *CharCodec;
+ QChar SubstituteChar;
+ QChar UndefinedChar;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kcharcolumn.cpp b/khexedit/lib/kcharcolumn.cpp
new file mode 100644
index 0000000..9ecbd5a
--- /dev/null
+++ b/khexedit/lib/kcharcolumn.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ kcharcolumn.cpp - description
+ -------------------
+ begin : Mit Sep 3 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. *
+ * *
+ ***************************************************************************/
+
+
+// c specific
+#include <ctype.h>
+// qt specific
+#include <qpainter.h>
+// kde specific
+#include <kcharsets.h>
+#include <klocale.h>
+#include <kglobal.h>
+// lib specific
+#include "kcolumnsview.h"
+#include "kbuffercursor.h"
+#include "kbufferlayout.h"
+#include "kbufferranges.h"
+#include "kcharcolumn.h"
+
+using namespace KHE;
+
+static const bool DefaultShowUnprintable = false;
+static const QChar DefaultSubstituteChar = (char)'.';
+static const QChar DefaultUndefinedChar = (char)'?';
+
+
+KCharColumn::KCharColumn( KColumnsView *CV, KDataBuffer *B, KBufferLayout *L, KBufferRanges *R )
+ : KBufferColumn( CV, B, L, R ),
+ ShowUnprintable( DefaultShowUnprintable ),
+ SubstituteChar( DefaultSubstituteChar ),
+ UndefinedChar( DefaultUndefinedChar )
+{
+ setSpacing( 0, 0, 0 );
+}
+
+
+KCharColumn::~KCharColumn()
+{
+}
+
+void KCharColumn::drawByte( QPainter *P, char /*Byte*/, KHEChar B, const QColor &Color ) const
+{
+ // make a drawable String out of it
+ QString BS( B.isUndefined() ? KHEChar(UndefinedChar) : ( !(ShowUnprintable || B.isPrint()) ? KHEChar(SubstituteChar) : B ));
+
+ P->setPen( Color );
+ P->drawText( 0, DigitBaseLine, BS );
+}
diff --git a/khexedit/lib/kcharcolumn.h b/khexedit/lib/kcharcolumn.h
new file mode 100644
index 0000000..1e875b0
--- /dev/null
+++ b/khexedit/lib/kcharcolumn.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ kcharcolumn.h - description
+ -------------------
+ begin : Mit Sep 3 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_KCHARCOLUMN_H
+#define KHE_KCHARCOLUMN_H
+
+// qt specific
+#include <qstring.h>
+// lib specific
+#include "kbuffercolumn.h"
+
+class QPainter;
+class QColor;
+
+
+namespace KHE
+{
+
+
+/** buffer column that interprets the bytes as chars
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+class KCharColumn : public KBufferColumn
+{
+ public:
+ KCharColumn( KColumnsView *CV, KDataBuffer *B, KBufferLayout *L, KBufferRanges *R );
+ virtual ~KCharColumn();
+
+
+ public: // modification access
+ /** 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
+ */
+ bool setShowUnprintable( bool SU = true );
+ /** sets the substitute character for "unprintable" chars
+ * returns true if there was a change
+ */
+ bool setSubstituteChar( QChar SC );
+ /** sets the undefined character for "undefined" chars
+ * returns true if there was a change
+ */
+ bool setUndefinedChar( QChar UC );
+
+
+ public: // value access
+ /** returns true if "unprintable" chars (>32) are displayed in the char column
+ * with their corresponding character, default is false
+ */
+ bool showUnprintable() const;
+ /** returns the actually used substitute character for "unprintable" chars, default is '.' */
+ QChar substituteChar() const;
+ /** returns the actually used undefined character for "undefined" chars, default is '?' */
+ QChar undefinedChar() const;
+
+
+ protected: // KBufferColumn API
+ virtual void drawByte( QPainter *P, char Byte, KHEChar B, const QColor &Color ) const;
+
+ protected:
+ /** */
+ bool ShowUnprintable;
+ /** */
+ QChar SubstituteChar;
+ /** */
+ QChar UndefinedChar;
+};
+
+
+inline bool KCharColumn::showUnprintable() const { return ShowUnprintable; }
+inline QChar KCharColumn::substituteChar() const { return SubstituteChar; }
+inline QChar KCharColumn::undefinedChar() const { return UndefinedChar; }
+
+inline bool KCharColumn::setSubstituteChar( QChar SC )
+{
+ if( SubstituteChar == SC )
+ return false;
+ SubstituteChar = SC;
+ return true;
+}
+
+inline bool KCharColumn::setUndefinedChar( QChar UC )
+{
+ if( UndefinedChar == UC )
+ return false;
+ UndefinedChar = UC;
+ return true;
+}
+
+inline bool KCharColumn::setShowUnprintable( bool SU )
+{
+ if( ShowUnprintable == SU )
+ return false;
+ ShowUnprintable = SU;
+ return true;
+}
+
+}
+
+#endif
diff --git a/khexedit/lib/kcoltextexport.h b/khexedit/lib/kcoltextexport.h
new file mode 100644
index 0000000..d0b3918
--- /dev/null
+++ b/khexedit/lib/kcoltextexport.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ kcoltextexport.h - description
+ -------------------
+ begin : Sam Aug 30 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_KCOLTEXTEXPORT_H
+#define KHE_KCOLTEXTEXPORT_H
+
+class QString;
+
+namespace KHE
+{
+/**
+ * interface for the text export of columns
+ * @author Friedrich W. H. Kossebau <Friedrich.W.H@Kossebau.de>
+ */
+class KColTextExport
+{
+ public: // API
+ virtual void printFirstLine( QString &T, int Line ) const = 0;
+ virtual void printNextLine( QString &T ) const = 0;
+ /** tells how much chars per line are needed */
+ virtual int charsPerLine() const = 0;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kcolumn.cpp b/khexedit/lib/kcolumn.cpp
new file mode 100644
index 0000000..f9b0ce5
--- /dev/null
+++ b/khexedit/lib/kcolumn.cpp
@@ -0,0 +1,60 @@
+/***************************************************************************
+ kcolumn.cpp - description
+ -------------------
+ begin : Mit Mai 21 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qpainter.h>
+// lib specific
+#include "kcolumnsview.h"
+#include "kcolumn.h"
+
+using namespace KHE;
+
+
+KColumn::KColumn( KColumnsView *V )
+ : View( V ),
+ Visible( true ), //TODO: would false be better?
+ LineHeight( V->lineHeight() ),
+ XSpan( 0,0,true )
+{
+ V->addColumn( this );
+}
+
+
+void KColumn::paintFirstLine( QPainter *P, KPixelXs, int /*FirstLine*/ )
+{
+ paintBlankLine( P );
+}
+
+
+void KColumn::paintNextLine( QPainter *P )
+{
+ paintBlankLine( P );
+}
+
+
+void KColumn::paintBlankLine( QPainter *P ) const
+{
+ if( LineHeight > 0 )
+ P->fillRect( 0,0,width(),LineHeight, View->backgroundBrush() );
+}
+
+
+void KColumn::paintEmptyColumn( QPainter *P, KPixelXs Xs, KPixelYs Ys )
+{
+ Xs.restrictTo( XSpan );
+ P->fillRect( Xs.start(), Ys.start(), Xs.width(), Ys.width(), View->backgroundBrush() );
+}
diff --git a/khexedit/lib/kcolumn.h b/khexedit/lib/kcolumn.h
new file mode 100644
index 0000000..37c3118
--- /dev/null
+++ b/khexedit/lib/kcolumn.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ kcolumn.h - description
+ -------------------
+ begin : Mit Mai 21 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_KCOLUMN_H
+#define KHE_KCOLUMN_H
+
+
+// lib specific
+#include "kadds.h"
+#include "ksection.h"
+
+class QPainter;
+
+namespace KHE
+{
+
+class KColumnsView;
+
+/** base class for columns of the KColumnsView
+ *
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KColumn
+{
+// friend class KColumnsView;
+ public:
+ KColumn( KColumnsView *V );
+ virtual ~KColumn() {}
+
+
+ public: // API to be reimplemented in the subclasses
+ /** Before an update of the columns view each column that intersects with the area to be painted
+ * will be called with this function. As often multiple lines of a column are affected
+ * for each lines the same values (like first and last char positions) might be calculated.
+ * This function enables a one-time-calculation for such data that must be stored in some
+ * class members, though.
+ * @param P painter variable
+ * @param cx
+ * @param cw
+ * @param FirstLine no of the first of the range of lines to paint
+ */
+ virtual void paintFirstLine( QPainter *P, KPixelXs Xs, int FirstLine );
+ /** the actual painting call for a column's line.
+ * The default implementation simply paints the background
+ */
+ virtual void paintNextLine( QPainter *P );
+
+ /** */
+ virtual void paintEmptyColumn( QPainter *P, KPixelXs Xs, KPixelYs Ys );
+
+ public: // modification access
+ /** sets starting point of the column */
+ void setX( KPixelX NewX );
+ /** sets visibily */
+ void setVisible( bool V );
+ /** buffer actual line height in column */
+ void setLineHeight( KPixelY H );
+
+ public: // value access
+ /** left offset x in pixel */
+ KPixelX x() const;
+ /** total width in pixel */
+ KPixelX width() const;
+ /** right offset x in pixel */
+ KPixelX rightX() const;
+ /** should Column be displayed? */
+ bool isVisible() const;
+ /** convinience: returns width if visible else 0 */
+ KPixelX visibleWidth() const;
+
+ public: // functional logic
+ /** true if column overlaps with pixels between x-positions x1, x2 */
+ bool overlaps( KPixelXs Xs ) const;
+
+ protected:
+ /** sets width of the column */
+ void setWidth( KPixelX W );
+ /** */
+ void paintBlankLine( QPainter *P ) const;
+
+ protected: // general column data
+ /** pointer to the view */
+ KColumnsView *View;
+ /** should Column be displayed? */
+ bool Visible;
+
+ /** buffered value */
+ KPixelY LineHeight;
+
+ /** left offset x in pixel */
+ KPixelXs XSpan;
+};
+
+
+inline KPixelX KColumn::x() const { return XSpan.start(); }
+inline KPixelX KColumn::rightX() const { return XSpan.end(); }
+inline KPixelX KColumn::width() const { return XSpan.width(); }
+inline bool KColumn::isVisible() const { return Visible; }
+inline KPixelX KColumn::visibleWidth() const { return Visible ? XSpan.width(): 0; }
+
+inline void KColumn::setX( KPixelX NewX ) { XSpan.moveToStart( NewX ); }
+inline void KColumn::setWidth( KPixelX W ) { XSpan.setEndByWidth( W ); }
+inline void KColumn::setVisible( bool V ) { Visible = V; }
+inline void KColumn::setLineHeight( KPixelY H ) { LineHeight = H; }
+
+inline bool KColumn::overlaps( KPixelXs Xs ) const { return XSpan.overlaps(Xs); }
+
+}
+
+#endif
diff --git a/khexedit/lib/kcolumnsview.cpp b/khexedit/lib/kcolumnsview.cpp
new file mode 100644
index 0000000..1c93af8
--- /dev/null
+++ b/khexedit/lib/kcolumnsview.cpp
@@ -0,0 +1,236 @@
+/***************************************************************************
+ kcolumnsview.cpp - description
+ -------------------
+ begin : Mit Mai 21 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. *
+ * *
+ ***************************************************************************/
+
+
+//#include <kdebug.h>
+
+// qt specific
+#include <qpainter.h>
+// lib specific
+#include "kcolumn.h"
+#include "kcolumnsview.h"
+
+
+using namespace KHE;
+
+static bool DefaultHorizontalGrid = false;
+
+KColumnsView::KColumnsView( /*bool R,*/ QWidget *Parent, const char *Name, WFlags Flags )
+ : QScrollView( Parent, Name, Flags | WRepaintNoErase /*| WStaticContents*/ ),
+ NoOfLines( 0 ),
+ LineHeight( 0 ),
+ TotalWidth( 0 ),
+ HorizontalGrid( DefaultHorizontalGrid ),
+// Reversed( R ),
+ d( 0 )
+{
+ viewport()->setBackgroundMode( PaletteBase );
+ setBackgroundMode( PaletteBackground, PaletteBase );
+ viewport()->setFocusProxy( this );
+
+ Columns.setAutoDelete( true );
+}
+
+KColumnsView::~KColumnsView()
+{
+}
+
+
+void KColumnsView::setNoOfLines( int NewNoOfLines )
+{
+ NoOfLines = NewNoOfLines;
+}
+
+
+void KColumnsView::setLineHeight( KPixelY LH )
+{
+ LineHeight = LH;
+ for( KColumn *C=Columns.first(); C; C=Columns.next() )
+ C->setLineHeight( LineHeight );
+ verticalScrollBar()->setLineStep( LineHeight );
+
+ updateLineBufferSize();
+}
+
+
+void KColumnsView::updateWidths()
+{
+ TotalWidth = 0;
+ for( KColumn *C=Columns.first(); C; C=Columns.next() )
+ {
+ C->setX( TotalWidth );
+ TotalWidth += C->visibleWidth();
+ }
+
+ updateLineBufferSize();
+}
+
+
+void KColumnsView::updateLineBufferSize()
+{
+ int w = totalWidth();
+ int h = LineHeight;
+
+ if( w != LineBuffer.width() || h != LineBuffer.height() )
+ LineBuffer.resize( w, h );
+}
+
+
+int KColumnsView::noOfLinesPerPage() const
+{
+ if( !viewport() || LineHeight == 0 )
+ return 1;
+// int NoOfLinesPerPage = (visibleHeight()-1) / LineHeight; // -1 ensures to get always the last visible line
+ int NoOfLinesPerPage = (viewport()->height()-1) / LineHeight; // -1 ensures to get always the last visible line
+
+ if( NoOfLinesPerPage == 0 )
+ // ensure to move down at least one line
+ NoOfLinesPerPage = 1;
+ return NoOfLinesPerPage;
+}
+
+
+void KColumnsView::addColumn( KColumn *C )
+{
+// if( Reversed )
+// Columns.prepend( C );
+// else
+ Columns.append( C );
+
+ updateWidths();
+}
+
+
+void KColumnsView::removeColumn( KColumn *C )
+{
+ Columns.remove( C );
+
+ updateWidths();
+}
+
+
+void KColumnsView::updateView()
+{
+ resizeContents( totalWidth(), totalHeight() );
+ updateContents();
+}
+
+
+void KColumnsView::repaintView()
+{
+ resizeContents( totalWidth(), totalHeight() );
+ repaintContents( false );
+}
+
+
+void KColumnsView::paintEmptyArea( QPainter *P, int cx ,int cy, int cw, int ch)
+{
+ P->fillRect( cx, cy, cw, ch, backgroundBrush() );
+}
+
+
+void KColumnsView::drawContents( QPainter *P, int cx, int cy, int cw, int ch )
+{
+ //kdDebug(1501) << "drawContents(" << cx<<","<<cw<<"#"<<cy<<","<<ch<<")\n";
+ KPixelXs AffectedXs( cx, cw, true );
+ // content to be shown?
+ if( AffectedXs.startsBefore(TotalWidth) )
+ {
+ KPixelYs AffectedYs( cy, ch, true );
+
+ // collect affected columns
+ QPtrList<KColumn> RedrawColumns;
+ for( KColumn *C=Columns.first(); C; C=Columns.next() )
+ if( C->isVisible() && C->overlaps(AffectedXs) )
+ RedrawColumns.append( C );
+
+ // any lines to be drawn?
+ if( NoOfLines > 0 )
+ {
+ // calculate affected lines
+ KSection AffectedLines = visibleLines( AffectedYs );
+ AffectedLines.restrictEndTo( NoOfLines - 1 );
+
+ if( AffectedLines.isValid() )
+ {
+ QPainter Paint;
+ Paint.begin( &LineBuffer, this );
+
+ // starting painting with the first line
+ KColumn *C = RedrawColumns.first();
+ Paint.translate( C->x(), 0 );
+
+ for( ; C; C=RedrawColumns.next() )
+ {
+ C->paintFirstLine( &Paint, AffectedXs, AffectedLines.start() );
+ Paint.translate( C->width(), 0 );
+ }
+
+ // Go through the other lines
+ KPixelY y = AffectedLines.start() * LineHeight;
+ int l = AffectedLines.start();
+ while( true )
+ {
+ Paint.end();
+ P->drawPixmap( cx, y, LineBuffer, cx, 0, cw, LineHeight ); // bitBlt directly impossible: lack of real coord
+
+ // copy to screen
+// bitBlt( viewport(), cx - contentsX(), y - contentsY(),
+// &LineBuffer, cx, 0, cw, LineHeight );
+
+ ++l;
+ y += LineHeight;
+
+ if( l > AffectedLines.end() )
+ break;
+
+ // to avoid flickers we first paint to the linebuffer
+ Paint.begin( &LineBuffer, this );
+
+ KColumn *C = RedrawColumns.first();
+ Paint.translate( C->x(), 0 );
+
+ for( ; C; C=RedrawColumns.next() )
+ {
+ C->paintNextLine( &Paint );
+ Paint.translate( C->width(), 0 );
+ }
+
+ if( HorizontalGrid && cx < TotalWidth )
+ Paint.drawLine( cx, LineHeight-1, TotalWidth-1, LineHeight-1 ); // TODO: use a additional TotalHeight?
+ }
+ }
+ }
+
+ // draw empty columns?
+ AffectedYs.setStart( totalHeight() );
+ if( AffectedYs.isValid() )
+ {
+ for( KColumn *C = RedrawColumns.first(); C; C=RedrawColumns.next() )
+ C->paintEmptyColumn( P, AffectedXs, AffectedYs );
+ }
+ }
+
+ // Paint empty rects
+ AffectedXs.setStart( TotalWidth );
+ if( AffectedXs.isValid() )
+ paintEmptyArea( P, AffectedXs.start(), cy, AffectedXs.width(), ch );
+}
+
+// Implemented to get rid of a compiler warning
+void KColumnsView::drawContents( QPainter * ) {}
+
+#include "kcolumnsview.moc"
diff --git a/khexedit/lib/kcolumnsview.h b/khexedit/lib/kcolumnsview.h
new file mode 100644
index 0000000..aa3521d
--- /dev/null
+++ b/khexedit/lib/kcolumnsview.h
@@ -0,0 +1,168 @@
+/***************************************************************************
+ kcolumnsview.h - description
+ -------------------
+ begin : Mit Mai 21 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_KCOLUMNSVIEW_H
+#define KHE_KCOLUMNSVIEW_H
+
+// qt specific
+#include <qptrlist.h>
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qscrollview.h>
+// lib specific
+#include "kadds.h"
+#include "ksection.h" // TODO: think about moving this out of the public API
+
+namespace KHE
+{
+
+class KColumn;
+class KColumnsViewPrivate;
+
+/** general class for widgets with columns that display different aspects of the same data
+ * with the same lineheight for all lines
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KColumnsView : public QScrollView
+{
+ Q_OBJECT
+
+ friend class KColumn;
+
+ public:
+ KColumnsView( /*bool R = false,*/ QWidget *parent=0, const char *name=0, WFlags Flags=0 );
+ virtual ~KColumnsView();
+
+ public: // drawing
+ virtual void paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch );
+ virtual void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
+
+ public: // data-wise sizes
+ /** returns the number of all lines */
+ int noOfLines() const;
+ /** returns number of fully visible lines, at least 1 (as needed by page down/up)
+ * doesn't care about the total height being smaller than the display height
+ */
+ int noOfLinesPerPage() const;
+
+ public: // pixel-wise sizes
+ /** returns the height of each line */
+ KPixelY lineHeight() const;
+ /** returns the size of all visible columns together */
+ QSize totalViewSize() const;
+ /** returns the width of all visible columns together */
+ KPixelX totalWidth() const;
+ /** returns the height of all lines together */
+ KPixelY totalHeight() const;
+
+ public: // services
+ /** gives the index of the line that would include y in pixel coord.
+ * y is not forced to be inside the total height.
+ */
+ uint lineAt( KPixelY y ) const;
+ /** gives the index of the first and the last line that would be visible
+ * these lines might not contain anything
+ */
+ KSection visibleLines() const;
+ /** gives the index of the first and the last line that would be visible in the given pixel range
+ * these lines might not contain anything
+ */
+ KSection visibleLines( KPixelYs YPixels ) const;
+
+
+ protected:
+ /** called by KColumn */
+ void addColumn( KColumn *C );
+ void removeColumn( KColumn *C );
+
+
+ protected: //
+ /** sets height of all lines and propagates this information to all columns
+ * doesn't update the content size
+ * @param NewLineHeight height in pixels
+ */
+ virtual void setLineHeight( KPixelY NewLineHeight );
+ /** sets the number of lines
+ * doesn't update the content size
+ * @param NewNoOfLines new number of lines to display
+ */
+ virtual void setNoOfLines( int NewNoOfLines );
+
+ protected: // recalculations
+ /** recalculates the positions of the columns and the total width */
+ void updateWidths();
+ /** ensures that the line buffer has the size of the whole line */
+ void updateLineBufferSize();
+
+ protected: // painting
+ void updateView();
+ void repaintView();
+
+ private:
+ /** hiding it*/
+ void drawContents( QPainter* );
+
+
+ protected: // calculated
+ /** collection of all the columns. All columns will be autodeleted. */
+ QPtrList<KColumn> Columns;
+ /** the number of lines which the column view has */
+ int NoOfLines;
+ /** the height of each line in pixels */
+ KPixelY LineHeight;
+ /** the width of all visible columns together */
+ KPixelX TotalWidth;
+// /** width that is used by columns that are not resizeable (if shown) */
+// KPixelX ReservedWidth;
+
+ protected:
+ // TODO: do we really want this?
+ bool HorizontalGrid;
+ /** Buffer where each line is drawn to before it is copied onto the screen */
+ QPixmap LineBuffer;
+// bool Reversed;
+
+ private:
+ KColumnsViewPrivate *d;
+};
+
+
+inline int KColumnsView::noOfLines() const { return NoOfLines; }
+inline KPixelY KColumnsView::lineHeight() const { return LineHeight; }
+inline uint KColumnsView::lineAt( KPixelY y ) const { return LineHeight!=0 ? y / LineHeight : 0; }
+inline KSection KColumnsView::visibleLines() const
+{
+ KPixelY cy = contentsY();
+ KPixelY ch = visibleHeight();
+ return KSection( lineAt(cy), lineAt(cy+ch-1) );
+}
+
+inline KSection KColumnsView::visibleLines( KPixelYs YPixels ) const
+{
+ return KSection( lineAt(YPixels.start()), lineAt(YPixels.end()) );
+}
+
+inline KPixelY KColumnsView::totalHeight() const { return NoOfLines*LineHeight; }
+inline KPixelX KColumnsView::totalWidth() const { return TotalWidth; }
+
+inline QSize KColumnsView::totalViewSize() const { return QSize( totalWidth(), totalHeight() ); }
+
+}
+
+#endif
diff --git a/khexedit/lib/kcoordrange.h b/khexedit/lib/kcoordrange.h
new file mode 100644
index 0000000..0d5b186
--- /dev/null
+++ b/khexedit/lib/kcoordrange.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ kcoordrange.h - description
+ -------------------
+ begin : Sun 03.08.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_KCOORDRANGE_H
+#define KHE_KCOORDRANGE_H
+
+// lib specific
+#include "krange.h"
+#include "kbuffercoord.h"
+#include "ksection.h"
+
+namespace KHE
+{
+
+template<>
+inline const KBufferCoord KRange<KBufferCoord>::null() const { return KBufferCoord(-1,-1);}
+
+typedef KRange<KBufferCoord> KBasicCoordRange;
+
+/** describes a range in the buffercoord
+ *@author Friedrich W. H. Kossebau
+ */
+class KCoordRange : public KRange<KBufferCoord>
+{
+ public:
+ /**
+ * @param SC start coord
+ * @param EC end coord
+ */
+ KCoordRange( KBufferCoord SC, KBufferCoord EC );
+ /**
+ * @param Pos start and end pos
+ * @param Lines start and end line
+ */
+ KCoordRange( KSection Pos, KSection Lines );
+ KCoordRange();
+ ~KCoordRange();
+
+ public:
+ KCoordRange &operator=( const KCoordRange &S );
+
+ public:
+ bool operator==( const KCoordRange &S ) const;
+
+ public:
+ /** calculates the number of coords that are covered if a line has the given length.
+ * If the range is invalid the behaviour is undefined.
+ * @param LineLength
+ * @return the number of points covered if a line has a length of LineLength.
+ */
+ int width( int LineLength ) const;
+ /** calculates the number of lines that are covered by the range.
+ * If the range is invalid the behaviour is undefined.
+ * @return number of lines covered
+ */
+ int lines() const;
+ /** tests if the given line is included by the range.
+ * If the range is invalid or the line < 0 the behaviour is undefined.
+ * @param Line index of line
+ * @return @c true if Line is included, otherwise @c false
+ */
+ bool includesLine( int Line ) const;
+};
+
+
+inline KCoordRange::KCoordRange( KBufferCoord SC, KBufferCoord EC ) : KBasicCoordRange(SC,EC) {}
+inline KCoordRange::KCoordRange( KSection Pos, KSection Lines )
+ : KBasicCoordRange( KBufferCoord(Pos.start(),Lines.start()), KBufferCoord(Pos.end(),Lines.end()) ) {}
+inline KCoordRange::KCoordRange() {}
+inline KCoordRange::~KCoordRange() {}
+
+inline bool KCoordRange::operator==( const KCoordRange &R ) const { return KBasicCoordRange::operator==(R); }
+
+inline KCoordRange &KCoordRange::operator=( const KCoordRange &R ) { KBasicCoordRange::operator=(R); return *this; }
+
+inline int KCoordRange::width( int LineLength ) const { return LineLength*(lines()-1) + End.pos() - Start.pos()+1; }
+inline int KCoordRange::lines() const { return End.line() - Start.line() + 1; }
+inline bool KCoordRange::includesLine( int Line ) const { return Line >= Start.line() && Line <= End.line(); }
+}
+
+#endif
diff --git a/khexedit/lib/kcoordrangelist.cpp b/khexedit/lib/kcoordrangelist.cpp
new file mode 100644
index 0000000..3028c7d
--- /dev/null
+++ b/khexedit/lib/kcoordrangelist.cpp
@@ -0,0 +1,78 @@
+/***************************************************************************
+ kcoordrangelist.cpp - description
+ -------------------
+ begin : Mon Jun 30 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kcoordrangelist.h"
+
+using namespace KHE;
+
+KCoordRangeList::KCoordRangeList()
+{
+}
+
+
+KCoordRangeList::~KCoordRangeList()
+{
+}
+
+
+void KCoordRangeList::addCoordRange( KCoordRange NewCoordRange )
+{
+ if( !NewCoordRange.isValid() )
+ return;
+ // we try to insert it by ascending indizes
+ // if sections are overlapping we combine them
+ iterator S = begin();
+ for( ; S!=end(); ++S )
+ {
+ // is next CoordRange behind the new CoordRange?
+ if( NewCoordRange.endsBefore(*S) )
+ {
+ // put the new before it
+ insert( S, NewCoordRange );
+ return;
+ }
+
+ // does the next CoordRange overlap?
+ if( (*S).overlaps(NewCoordRange) )
+ {
+ // Start of the combined sections is the smaller one
+ NewCoordRange.extendStartTo( (*S).start() );
+ // next we search all the overlapping sections and keep the highest end index
+ KBufferCoord End((*S).end());
+ iterator LS = S;
+ for( ++LS; LS!=end(); ++LS )
+ {
+ if( !(*LS).overlaps(NewCoordRange) )
+ break;
+ End = (*LS).end();
+ }
+ // the higher end is the end of the combined CoordRange
+ NewCoordRange.extendEndTo( End );
+ // remove all overlapping sections
+ S = erase( S, LS );
+ // and instead insert the combined one
+ insert( S, NewCoordRange );
+ return;
+ }
+ }
+
+ // all others are before the new?
+ if( S == end() )
+ // add it at the end
+ append( NewCoordRange );
+}
diff --git a/khexedit/lib/kcoordrangelist.h b/khexedit/lib/kcoordrangelist.h
new file mode 100644
index 0000000..187ec7f
--- /dev/null
+++ b/khexedit/lib/kcoordrangelist.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ kcoordrangelist.h - description
+ -------------------
+ begin : Wed Aug 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_KCOORDRANGELIST_H
+#define KHE_KCOORDRANGELIST_H
+
+// qt specific
+#include <qvaluelist.h>
+// lib specific
+#include "kcoordrange.h"
+
+namespace KHE {
+
+typedef QValueList<KCoordRange> KCoordRangeBasicList;
+/**
+@author Friedrich W. H. Kossebau
+*/
+class KCoordRangeList : public KCoordRangeBasicList
+{
+ public:
+ KCoordRangeList();
+ ~KCoordRangeList();
+
+ public:
+ void addCoordRange( KCoordRange S );
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kcursor.cpp b/khexedit/lib/kcursor.cpp
new file mode 100644
index 0000000..3150751
--- /dev/null
+++ b/khexedit/lib/kcursor.cpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+ kcursor.cpp - description
+ -------------------
+ begin : Mit Jun 26 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. *
+ * *
+ ***************************************************************************/
+
+
+#include "kcursor.h"
+
+using namespace KHE;
+
+KCursor::KCursor()
+: CursorX( 0 ),
+ CursorW( -1 )
+{
+}
+
+
+KCursor::~KCursor()
+{
+}
+
+
+
+void KCursor::setSize( KPixelX Width, KPixelY Height )
+{
+ if( Width != OnPixmap.width() || Height != OnPixmap.height() )
+ {
+ OnPixmap.resize( Width, Height );
+ OffPixmap.resize( Width, Height );
+ }
+}
+
+
+void KCursor::setShape( KPixelX X, KPixelX W )
+{
+ CursorX = X;
+ CursorW = W;
+}
diff --git a/khexedit/lib/kcursor.h b/khexedit/lib/kcursor.h
new file mode 100644
index 0000000..428c7ed
--- /dev/null
+++ b/khexedit/lib/kcursor.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ kbuffercolumn.h - description
+ -------------------
+ begin : Mit Jun 26 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_KCURSOR_H
+#define KHE_KCURSOR_H
+
+
+#include <qpixmap.h>
+
+#include "kadds.h"
+
+namespace KHE
+{
+
+/**
+ *@author Friedrich W. H. Kossebau
+ */
+class KCursor
+{
+ public:
+ KCursor();
+ virtual ~KCursor();
+
+ public:
+ /** sets size of the full cursor */
+ void setSize( KPixelX Width, KPixelY Height );
+ /** sets the shape of the cursor to be drawn */
+ void setShape( KPixelX X, KPixelX W );
+
+ public: // access
+ const QPixmap &onPixmap() const;
+ const QPixmap &offPixmap() const;
+ KPixelX cursorX() const;
+ KPixelX cursorW() const;
+
+
+ protected:
+ QPixmap OnPixmap;
+ QPixmap OffPixmap;
+
+ KPixelX CursorX;
+ KPixelX CursorW;
+};
+
+
+inline const QPixmap &KCursor::onPixmap() const { return OnPixmap; }
+inline const QPixmap &KCursor::offPixmap() const { return OffPixmap; }
+
+inline KPixelX KCursor::cursorX() const { return CursorX; }
+inline KPixelX KCursor::cursorW() const { return CursorW; }
+
+}
+
+#endif
diff --git a/khexedit/lib/kdatabuffer.cpp b/khexedit/lib/kdatabuffer.cpp
new file mode 100644
index 0000000..054d792
--- /dev/null
+++ b/khexedit/lib/kdatabuffer.cpp
@@ -0,0 +1,51 @@
+/***************************************************************************
+ kdatabuffer.cpp - description
+ -------------------
+ begin : Fri Aug 01 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. *
+ * *
+ ***************************************************************************/
+
+
+// c specific
+#include <ctype.h>
+// lib specific
+#include "kdatabuffer.h"
+
+using namespace KHE;
+
+
+int KDataBuffer::insert( int Pos, const char* D, int Length )
+{
+ return replace( Pos,0,D,Length );
+}
+
+
+int KDataBuffer::remove( KSection Remove )
+{
+ replace( Remove, 0, 0 );
+ return Remove.width(); // TODO: check if this is true
+}
+
+int KDataBuffer::copyTo( char* Dest, int Pos, int Length ) const
+{
+ return copyTo( Dest, KSection(Pos,Length,false) );
+}
+
+
+
+int KDataBuffer::copyTo( char* Dest, KSection Source ) const
+{
+ Source.restrictEndTo( size()-1 );
+ for( int i=Source.start(); i<=Source.end(); ++i )
+ *Dest++ = datum( i );
+ return Source.width();
+}
diff --git a/khexedit/lib/kdatabuffer.h b/khexedit/lib/kdatabuffer.h
new file mode 100644
index 0000000..e9733d8
--- /dev/null
+++ b/khexedit/lib/kdatabuffer.h
@@ -0,0 +1,246 @@
+/***************************************************************************
+ kdatabuffer.h - description
+ -------------------
+ begin : Mit Mai 14 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_KDATABUFFER_H
+#define KHE_KDATABUFFER_H
+
+
+// lib specific
+#include "ksection.h"
+#include "khexedit_export.h"
+
+namespace KHE
+{
+
+/** could it be useful to hide the data access behind an iterator? *
+class KDataBufferIterator
+{
+ public:
+ bool hasNext();
+ char next();
+ protected:
+
+ protected:
+ char *
+ int Length;
+}
+
+bool KDataBufferIterator::hasNext()
+{
+}
+// this function should be simple as possible
+char KDataBufferIterator::next()
+{
+ // if next span is empty
+ if( )
+ return *NextChar++;
+}
+*/
+/** base class for all Data buffers that are used to display
+ * TODO: think about a way to inform KHexEdit that there has been
+ * a change in the buffer outside. what kind of changes are possible?
+ *
+ * Operations on the data:
+ *
+ * Finding: is implemented stateless. FindNext has to be done by perhaps a FindManager
+ * Replacing: not available. Implement within a ReplaceManager
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KHEXEDIT_EXPORT KDataBuffer
+{
+ friend class KDataBufferIterator;
+
+
+ protected:
+ KDataBuffer();
+ public:
+ virtual ~KDataBuffer();
+
+
+ public: // data access API
+ /** locates working range
+ * The idea behind is to tell buffer which range will be requested in the following time,
+ * so that e.g. the corresponding pages will be loaded in advance
+ * TODO: do we really need this? Where will this lead to real enhancements?
+ * @param Range
+ * @return @c true if successfull, @c false otherwise
+ */
+ virtual bool prepareRange( KSection Range ) const = 0;
+ /** convenience function, same as above */
+ bool prepareRange( int Offset, int Length ) const;
+
+ /** creates an iterator to */
+ //virtual KDataBufferIterator *iterator() const = 0;
+ /** expects pointer to memory, should be in prepared range
+ * it is only expected to be a valid pointer until any further call
+ * to this or any modifying function
+ * @param Section
+ * @return pointer to
+ */
+ virtual const char *dataSet( KSection Section ) const = 0;
+ /** convenience function, same as above */
+ const char *dataSet( int Offset, int Length ) const;
+
+ /** requests a single byte
+ * if the offset is not valid the behaviout is undefined
+ * @param Offset offset of the datum requested
+ */
+ virtual char datum( unsigned int Offset ) const = 0;
+
+ /**
+ * @return the size of the data
+ */
+ virtual int size() const = 0;
+
+
+ public: // state read API
+ /**
+ * @return @c true if the buffer can only be read, @c false if writing is allowed
+ */
+ virtual bool isReadOnly() const;
+ /**
+ * @return @c true if the buffer has been modified, @c false otherwise
+ */
+ virtual bool isModified() const = 0;
+
+
+ public: // modification API
+ /** inserts bytes copied from the given source at Position.
+ * The original data beginnung at the position is moved
+ * with the buffer enlarged as needed
+ * If the buffer is readOnly this is a noop and returns 0.
+ * @param Pos
+ * @param Source data source
+ * @param SourceLength number of bytes to copy
+ * @return length of inserted data
+ */
+ virtual int insert( int Pos, const char* Source, int SourceLength );
+
+ /** removes beginning with position as much as possible
+ * @param Section
+ * @return length of removed data
+ */
+ virtual int remove( KSection Section );
+ /** convenience function, behaves as above */
+ int remove( int Pos, int Length );
+
+ /** replaces as much as possible
+ * @param DestSection
+ * @param Source
+ * @param SourceLength
+ * @return length of replacced data
+ */
+ virtual unsigned int replace( KSection DestSection, const char* Source, unsigned int SourceLength ) = 0;
+ /** convenience function, behaves as above */
+ unsigned int replace( unsigned int Pos, unsigned int RemoveLength,
+ const char* Source, unsigned int SourceLength );
+
+ /** moves a part of the data to a new position, while floating the other data around
+ * when moving to a higher place the length of the block must be taken into account
+ * if the new positions extend beyond the buffers end the section is moved to the end.
+ * @param DesPos position of the data where the section should be moved behind
+ * @param SourceSection data section to be moved
+ * @return new pos of moved data or old, if failed
+ */
+ virtual int move( int DestPos, KSection SourceSection ) = 0;
+
+ /**
+ * fills the buffer with the FillChar. If the buffer is to small it will be extended as much as possible.
+ * @param FillChar char to use
+ * @param Length number of chars to fill. If Length is -1, the current buffer length is used.
+ * @param Pos position where the filling starts
+ * @return number of filled characters
+ */
+ virtual int fill( const char FillChar, int Length = -1, unsigned int Pos = 0 ) = 0;
+
+ /** sets a single byte
+ * if the offset is not valid the behaviour is undefined
+ * @param Offset offset of the datum requested
+ * @param Char new byte value
+ */
+ virtual void setDatum( unsigned int Offset, const char Char ) = 0;
+
+ /** sets the modified flag for the buffer
+ * @param M
+ */
+ virtual void setModified( bool M ) = 0;
+
+
+ public: // service functions
+ /** copies the data of the section into a given array Dest. If the section extends the buffers range
+ * the section is limited to the buffer's end. If the section is invalid the behaviour is undefined.
+ * @param Dest pointer to a char array large enough to hold the copied section
+ * @param Source
+ * @return number of copied bytes
+ */
+ virtual int copyTo( char* Dest, KSection Source ) const;
+ /** convenience function, behaves as above */
+ int copyTo( char* Dest, int Pos, int n ) const;
+
+
+ public: // finding API
+ /** searches beginning with byte at Pos.
+ * @param
+ * @param Length length of search string
+ * @param Pos the position to start the search
+ * @return index of the first or -1
+ */
+ //virtual int find( const char*, int Length, int Pos = 0 ) const = 0;
+ /** searches for a given data string
+ * The section limits the data within which the key has to be found
+ * If the end of the section is lower then the start the search continues at the start???
+ * @param
+ * @param Length length of search string
+ * @param Section section within the keydata is to be found
+ * @return index of the first occurence or -1
+ */
+ virtual int find( const char*KeyData, int Length, KSection Section ) const = 0;
+ /** searches backward beginning with byte at Pos.
+ * @param
+ * @param Length length of search string
+ * @param Pos the position to start the search. If -1 the search starts at the end.
+ * @return index of the first or -1
+ */
+ virtual int rfind( const char*, int Length, int Pos = -1 ) const = 0;
+
+/* virtual int find( const QString &expr, bool cs, bool wo, bool forward = true, int *index = 0 ); */
+};
+
+
+inline KDataBuffer::KDataBuffer() {}
+inline KDataBuffer::~KDataBuffer() {}
+
+inline bool KDataBuffer::prepareRange( int Offset, int Length ) const
+{ return prepareRange( KSection(Offset,Offset+Length-1) ); }
+
+inline const char *KDataBuffer::dataSet( int Offset, int Length ) const
+{ return dataSet( KSection(Offset,Offset+Length-1) ); }
+
+inline int KDataBuffer::remove( int Pos, int Length )
+{ return remove( KSection(Pos,Pos+Length-1) ); }
+
+inline unsigned int KDataBuffer::replace( unsigned int Pos, unsigned int RemoveLength,
+ const char* D, unsigned int InputLength )
+{ return replace( KSection(Pos,Pos+RemoveLength-1), D, InputLength ); }
+
+inline bool KDataBuffer::isReadOnly() const { return false; }
+
+}
+
+#endif
diff --git a/khexedit/lib/kfixedsizebuffer.cpp b/khexedit/lib/kfixedsizebuffer.cpp
new file mode 100644
index 0000000..2945620
--- /dev/null
+++ b/khexedit/lib/kfixedsizebuffer.cpp
@@ -0,0 +1,272 @@
+/***************************************************************************
+ kfixedsizebuffer.cpp - description
+ -------------------
+ begin : Mit Jun 03 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. *
+ * *
+ ***************************************************************************/
+
+//#include <kdebug.h>
+// c specific
+#include <string.h>
+// lib specific
+#include "kfixedsizebuffer.h"
+
+using namespace KHE;
+
+KFixedSizeBuffer::KFixedSizeBuffer( char *D, unsigned int S, char FUC )
+ : Data( D ),
+ Size( S ),
+ FillUpChar( FUC ),
+ ReadOnly( true ),
+ Modified( false ),
+ AutoDelete( false )
+{
+}
+
+KFixedSizeBuffer::KFixedSizeBuffer( unsigned int S, char FUC )
+ : Data( new char[S] ),
+ Size( S ),
+ FillUpChar( FUC ),
+ ReadOnly( false ),
+ Modified( false ),
+ AutoDelete( true )
+{
+ reset( 0, S );
+}
+
+KFixedSizeBuffer::~KFixedSizeBuffer()
+{
+ if( AutoDelete )
+ delete [] Data;
+}
+
+
+
+int KFixedSizeBuffer::insert( int Pos, const char* D, int InputLength )
+{
+ // check all parameters
+ if( Pos >= (int)Size || InputLength == 0 )
+ return 0;
+ if( Pos + InputLength > (int)Size )
+ InputLength = Size - Pos;
+
+ unsigned int BehindInsertPos = Pos + InputLength;
+ // fmove right data behind the input range
+ memmove( &Data[BehindInsertPos], &Data[Pos], Size-BehindInsertPos );
+ // insert input
+ memcpy( &Data[Pos], D, InputLength );
+
+ Modified = true;
+ return InputLength;
+}
+
+
+int KFixedSizeBuffer::remove( KSection Remove )
+{
+ if( Remove.start() >= (int)Size || Remove.width() == 0 )
+ return 0;
+
+ Remove.restrictEndTo( Size-1 );
+
+ int RemoveLength = Remove.width();
+ int BehindRemovePos = Remove.end()+1;;
+ // fmove right data behind the input range
+ memmove( &Data[Remove.start()], &Data[BehindRemovePos], Size-BehindRemovePos );
+ // clear freed space
+ reset( Size-RemoveLength, RemoveLength );
+
+ Modified = true;
+ return RemoveLength;
+}
+
+
+unsigned int KFixedSizeBuffer::replace( KSection Remove, const char* D, unsigned int InputLength )
+{
+ // check all parameters
+ if( Remove.startsBehind( Size-1 ) || (Remove.width()==0 && InputLength==0) )
+ return 0;
+
+ Remove.restrictEndTo( Size-1 );
+ if( Remove.start() + InputLength > Size )
+ InputLength = Size - Remove.start();
+
+ int SizeDiff = InputLength - Remove.width();
+
+ // is input longer than removed?
+ if( SizeDiff > 0 )
+ {
+ unsigned int BehindInsertPos = Remove.start() + InputLength;
+ // fmove right data behind the input range
+ memmove( &Data[BehindInsertPos], &Data[Remove.end()+1], Size-BehindInsertPos );
+ }
+ // is input smaller than removed?
+ else if( SizeDiff < 0 )
+ {
+ unsigned int BehindRemovePos = Remove.end()+1;
+ // fmove right data behind the input range
+ memmove( &Data[Remove.start()+InputLength], &Data[BehindRemovePos], Size-BehindRemovePos );
+ // clear freed space
+ reset( Size+SizeDiff, -SizeDiff );
+ }
+ // insert input
+ memcpy( &Data[Remove.start()], D, InputLength );
+
+ Modified = true;
+ return InputLength;
+}
+
+
+int KFixedSizeBuffer::move( int DestPos, KSection SourceSection )
+{
+ // check all parameters
+ if( SourceSection.start() >= (int)Size || SourceSection.width() == 0
+ || DestPos > (int)Size || SourceSection.start() == DestPos )
+ return SourceSection.start();
+
+ SourceSection.restrictEndTo( Size-1 );
+ bool ToRight = DestPos > SourceSection.start();
+ int MovedLength = SourceSection.width();
+ int DisplacedLength = ToRight ? DestPos - SourceSection.end()-1 : SourceSection.start() - DestPos;
+
+ // find out section that is smaller
+ int SmallPartLength, LargePartLength, SmallPartStart, LargePartStart, SmallPartDest, LargePartDest;
+ // moving part is smaller?
+ if( MovedLength < DisplacedLength )
+ {
+ SmallPartStart = SourceSection.start();
+ SmallPartLength = MovedLength;
+ LargePartLength = DisplacedLength;
+ // moving part moves right?
+ if( ToRight )
+ {
+ SmallPartDest = DestPos - MovedLength;
+ LargePartStart = SourceSection.end()+1;
+ LargePartDest = SourceSection.start();
+ }
+ else
+ {
+ SmallPartDest = DestPos;
+ LargePartStart = DestPos;
+ LargePartDest = DestPos + MovedLength;
+ }
+ }
+ else
+ {
+ LargePartStart = SourceSection.start();
+ LargePartLength = MovedLength;
+ SmallPartLength = DisplacedLength;
+ // moving part moves right?
+ if( ToRight )
+ {
+ LargePartDest = DestPos - MovedLength;
+ SmallPartStart = SourceSection.end()+1;
+ SmallPartDest = SourceSection.start();
+ }
+ else
+ {
+ LargePartDest = DestPos;
+ SmallPartStart = DestPos;
+ SmallPartDest = DestPos + MovedLength;
+ }
+ }
+
+ // copy smaller part to tempbuffer
+ char *Temp = new char[SmallPartLength];
+ memcpy( Temp, &Data[SmallPartStart], SmallPartLength );
+
+ // move the larger part
+ memmove( &Data[LargePartDest], &Data[LargePartStart], LargePartLength );
+
+ // copy smaller part to its new dest
+ memcpy( &Data[SmallPartDest], Temp, SmallPartLength );
+ delete [] Temp;
+
+ Modified = true;
+ return MovedLength < DisplacedLength ? SmallPartDest : LargePartDest;
+}
+
+
+int KFixedSizeBuffer::fill( const char FChar, int FillLength, unsigned int Pos )
+{
+ // nothing to fill
+ if( Pos >= Size )
+ return 0;
+
+ unsigned int LengthToEnd = Size - Pos;
+
+ if( FillLength < 0 || FillLength > (int)LengthToEnd )
+ FillLength = LengthToEnd;
+
+ memset( &Data[Pos], FChar, FillLength );
+ Modified = true;
+ return FillLength;
+}
+
+
+int KFixedSizeBuffer::compare( const KDataBuffer &Other, KSection OtherRange, unsigned int Pos )
+{
+ //kdDebug() << QString("Pos: %1, OtherRange: (%3/%4)" ).arg(Pos).arg(OtherRange.start()).arg(OtherRange.end())
+ // << endl;
+ // test other values
+ if( OtherRange.startsBehind(Other.size()-1) )
+ return 1;
+
+ // check own values
+ if( Pos >= Size )
+ return -1;
+
+ int ValueByLength = 0; // default: equal
+
+ KSection Range( Pos, OtherRange.width(), true );
+ int Last = Other.size()-1;
+ //
+ if( OtherRange.endsBehind(Last) )
+ {
+ // make shorter
+ OtherRange.setEnd( Last );
+ if( OtherRange.width() < Range.width() )
+ ValueByLength = 1;
+ }
+ Last = Size-1;
+ if( Range.endsBehind(Last) )
+ {
+ // make shorter
+ Range.setEnd( Last );
+ if( OtherRange.width() > Range.width() )
+ ValueByLength = -1;
+ }
+ //kdDebug()
+ // << QString( "Range: (%1/%2), OtherRange: (%3/%4)" ).arg(Range.start()).arg(Range.end()).arg(OtherRange.start()).arg(OtherRange.end())
+ // << endl;
+ int oi = OtherRange.start();
+ for( int i=Range.start(); i<=Range.end(); ++i,++oi )
+ {
+ char OD = Other.datum(oi);
+ char D = Data[i];
+ //kdDebug() << QString("%1==%2").arg((int)D).arg((int)OD) << endl;
+ if( OD == D )
+ continue;
+ return OD < D ? 1 : -1;
+ }
+
+ return ValueByLength;
+}
+
+
+int KFixedSizeBuffer::find( const char*/*KeyData*/, int /*Length*/, KSection /*Section*/ ) const { return 0; }
+int KFixedSizeBuffer::rfind( const char*, int /*Length*/, int /*Pos*/ ) const { return 0; }
+
+
+void KFixedSizeBuffer::reset( unsigned int Pos, unsigned int Length )
+{
+ memset( &Data[Pos], FillUpChar, Length );
+}
diff --git a/khexedit/lib/kfixedsizebuffer.h b/khexedit/lib/kfixedsizebuffer.h
new file mode 100644
index 0000000..15c17da
--- /dev/null
+++ b/khexedit/lib/kfixedsizebuffer.h
@@ -0,0 +1,116 @@
+/***************************************************************************
+ kfixedsizebuffer.h - description
+ -------------------
+ begin : Mit Jun 03 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_KFIXEDSIZEBUFFER_H
+#define KHE_KFIXEDSIZEBUFFER_H
+
+#include "kdatabuffer.h"
+
+namespace KHE
+{
+
+/** base class for all Data buffers that are used to display
+ * TODO: think about a way to inform KHexEdit that there has been
+ * a change in the buffer outside. what kind of changes are possible?
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KFixedSizeBuffer : public KDataBuffer
+{
+ public:
+ /** creates a readonly buffer around the given data */
+ KFixedSizeBuffer( char *D, unsigned int S, char FUC = '\0' );
+ /** creates a writeable buffer which is deleted at the end */
+ KFixedSizeBuffer( unsigned int S, char FUC = '\0' );
+ virtual ~KFixedSizeBuffer();
+
+ public: // KDataBuffer API
+ virtual bool prepareRange( KSection Range ) const;
+ virtual const char *dataSet( KSection S ) const;
+ virtual char datum( unsigned int Offset ) const;
+ virtual int size() const;
+ virtual bool isReadOnly() const;
+ virtual bool isModified() const;
+
+ virtual int insert( int Pos, const char*, int Length );
+ virtual int remove( KSection Remove );
+ virtual unsigned int replace( KSection Remove, const char*, unsigned int InputLength );
+ virtual int move( int DestPos, KSection SourceSection );
+ virtual int fill( const char FillChar, int Length = -1, unsigned int Pos = 0 );
+ virtual void setDatum( unsigned int Offset, const char Char );
+
+ virtual void setModified( bool M = true );
+
+ virtual int find( const char*KeyData, int Length, KSection Section ) const;
+ virtual int rfind( const char*, int Length, int Pos = -1 ) const;
+
+/* virtual int find( const QString &expr, bool cs, bool wo, bool forward = true, int *index = 0 ); */
+
+ public:
+ void setReadOnly( bool RO = true );
+ int compare( const KDataBuffer &Other, KSection Range, unsigned int Pos = 0 );
+ int compare( const KDataBuffer &Other, int OtherPos, int Length, unsigned int Pos = 0 );
+ int compare( const KDataBuffer &Other );
+
+ public:
+ char *rawData() const;
+
+ protected:
+ void reset( unsigned int Pos, unsigned int Length );
+
+ protected:
+ /** */
+ char *Data;
+ /***/
+ unsigned int Size;
+ /** */
+ char FillUpChar;
+ /** */
+ bool ReadOnly:1;
+ /** */
+ bool Modified:1;
+ /** */
+ bool AutoDelete:1;
+};
+
+
+inline bool KFixedSizeBuffer::prepareRange( KSection ) const { return true; }
+inline const char *KFixedSizeBuffer::dataSet( KSection S ) const { return &Data[S.start()]; }
+
+inline char KFixedSizeBuffer::datum( unsigned int Offset ) const { return Data[Offset]; }
+inline int KFixedSizeBuffer::size() const { return Size; }
+
+inline void KFixedSizeBuffer::setDatum( unsigned int Offset, const char Char )
+{ Data[Offset] = Char; Modified = true; }
+
+inline bool KFixedSizeBuffer::isReadOnly() const { return ReadOnly; }
+inline bool KFixedSizeBuffer::isModified() const { return Modified; }
+
+inline void KFixedSizeBuffer::setReadOnly( bool RO ) { ReadOnly = RO; }
+inline void KFixedSizeBuffer::setModified( bool M ) { Modified = M; }
+
+inline int KFixedSizeBuffer::compare( const KDataBuffer &Other )
+{ return compare( Other, KSection(0,Other.size()-1),0 ); }
+
+inline int KFixedSizeBuffer::compare( const KDataBuffer &Other, int OtherPos, int Length, unsigned int Pos )
+{ return compare( Other, KSection(OtherPos,Length,true),Pos ); }
+
+inline char *KFixedSizeBuffer::rawData() const { return Data; }
+
+}
+
+#endif
diff --git a/khexedit/lib/khe.h b/khexedit/lib/khe.h
new file mode 100644
index 0000000..af029ea
--- /dev/null
+++ b/khexedit/lib/khe.h
@@ -0,0 +1,95 @@
+/***************************************************************************
+ khe.h - description
+ -------------------
+ begin : Mon Jul 14 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_KHE_H
+#define KHE_KHE_H
+
+// here we collect all general data
+// let's see how much it gets ;)
+
+namespace KHE
+{
+ enum KCoding { HexadecimalCoding=0, DecimalCoding=1, OctalCoding=2, BinaryCoding=3, MaxCodingId=0xFFFF };
+ static const int NoOfCodings = 4;
+
+ /** */
+ enum KEncoding
+ {
+ /** the coding of your shell */
+ LocalEncoding=0,
+ /** ASCII encoding, also known as Latin1 */
+ ISO8859_1Encoding,
+ /** */
+ ISO8859_2Encoding,
+ /** */
+ ISO8859_3Encoding,
+ /** */
+ ISO8859_4Encoding,
+ /** */
+ ISO8859_5Encoding,
+ /** */
+ ISO8859_6Encoding,
+ /** */
+ ISO8859_7Encoding,
+ /** */
+ ISO8859_8Encoding,
+ /** */
+ ISO8859_8_IEncoding,
+ /** */
+ ISO8859_9Encoding,
+ /** */
+ ISO8859_11Encoding,
+ /** */
+ ISO8859_13Encoding,
+ /** */
+ ISO8859_15Encoding,
+ /** */
+ CP1250Encoding,
+ /** */
+ CP1251Encoding,
+ /** */
+ CP1252Encoding,
+ /** */
+ CP1253Encoding,
+ /** */
+ CP1254Encoding,
+ /** */
+ CP1255Encoding,
+ /** */
+ CP1256Encoding,
+ /** */
+ CP1257Encoding,
+ /** */
+ CP1258Encoding,
+ /** */
+ IBM850Encoding,
+ /** */
+ IBM866Encoding,
+ /** */
+ KOI8_REncoding,
+ /** */
+ KOI8_UEncoding,
+ /** the most common EBCDIC codepage */
+ EBCDIC1047Encoding,
+ /** Offset for own encodings which are bound in by plugins */
+ StartOfOwnEncoding=0x8000,
+ /** this should enable extension without breaking binary compatibility */
+ MaxEncodingId=0xFFFF
+ };
+}
+
+#endif
diff --git a/khexedit/lib/khechar.h b/khexedit/lib/khechar.h
new file mode 100644
index 0000000..4f51e9e
--- /dev/null
+++ b/khexedit/lib/khechar.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ helper.h - description
+ -------------------
+ begin : Do Nov 25 2004
+ copyright : (C) 2004 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_KHECHAR_H
+#define KHE_KHECHAR_H
+
+// qt specific
+#include <qstring.h>
+
+namespace KHE
+{
+
+class KHEChar : public QChar
+{
+ public:
+ KHEChar( QChar C );
+ KHEChar( QChar C, bool U );
+ public:
+ bool isUndefined() const;
+ protected:
+ // the byte is not defined
+ bool IsUndefined:1;
+};
+
+inline KHEChar::KHEChar( QChar C ) : QChar( C ), IsUndefined( false ) {}
+inline KHEChar::KHEChar( QChar C, bool U ) : QChar( C ), IsUndefined( U ) {}
+inline bool KHEChar::isUndefined() const { return IsUndefined; }
+
+}
+
+#endif
diff --git a/khexedit/lib/khexedit.cpp b/khexedit/lib/khexedit.cpp
new file mode 100644
index 0000000..85478e5
--- /dev/null
+++ b/khexedit/lib/khexedit.cpp
@@ -0,0 +1,2032 @@
+/***************************************************************************
+ khexedit.cpp - 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. *
+ * *
+ ***************************************************************************/
+
+
+//#include <kdebug.h>
+
+// c specific
+#include <stdlib.h>
+//#include <limits.h>
+// c++ specific
+//#include <limits>
+// qt specific
+#include <qstyle.h>
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qcursor.h>
+#include <qapplication.h>
+// kde specific
+#ifndef QT_ONLY
+#include <kglobalsettings.h>
+#endif
+// lib specific
+#include "kdatabuffer.h"
+#include "koffsetcolumn.h"
+#include "kvaluecolumn.h"
+#include "kcharcolumn.h"
+#include "kbordercolumn.h"
+#include "kbuffercursor.h"
+#include "kbufferlayout.h"
+#include "kbufferranges.h"
+#include "controller/ktabcontroller.h"
+#include "controller/knavigator.h"
+#include "controller/kvalueeditor.h"
+#include "controller/kchareditor.h"
+#include "kbufferdrag.h"
+#include "kcursor.h"
+#include "kbytecodec.h"
+#include "kcharcodec.h"
+#include "kwordbufferservice.h"
+#include "khexedit.h"
+
+using namespace KHE;
+
+// zooming is done in steps of font size points
+static const int DefaultZoomStep = 1;
+static const int DefaultStartOffset = 0;//5;
+static const int DefaultFirstLineOffset = 0;
+static const int DefaultNoOfBytesPerLine = 16;
+static const KHexEdit::KResizeStyle DefaultResizeStyle = KHexEdit::FullSizeUsage;
+static const KHexEdit::KEncoding DefaultEncoding = KHexEdit::LocalEncoding;
+static const int DefaultScrollTimerPeriod = 100;
+static const int InsertCursorWidth = 2;
+
+
+
+KHexEdit::KHexEdit( KDataBuffer *Buffer, QWidget *Parent, const char *Name, WFlags Flags )
+ : KColumnsView( Parent, Name, Flags ),
+ DataBuffer( Buffer ),
+ BufferLayout( new KBufferLayout(DefaultNoOfBytesPerLine,DefaultStartOffset,0) ),
+ BufferCursor( new KBufferCursor(BufferLayout) ),
+ BufferRanges( new KBufferRanges(BufferLayout) ),
+ CursorBlinkTimer( new QTimer(this) ),
+ ScrollTimer( new QTimer(this) ),
+ DragStartTimer( new QTimer(this) ),
+ TrippleClickTimer( new QTimer(this) ),
+ CursorPixmaps( new KCursor() ),
+ Codec( 0 ),
+ ClipboardMode( QClipboard::Clipboard ),
+ ResizeStyle( DefaultResizeStyle ),
+ Encoding( MaxEncodingId ), // forces update
+ ReadOnly( false ),
+// Modified( false ),
+ OverWriteOnly( false ),
+ OverWrite( true ),
+ MousePressed( false ),
+ InDoubleClick( false ),
+ InDnD( false ),
+ DragStartPossible( false ),
+ CursorPaused( false ),
+ BlinkCursorVisible( false ),
+ InZooming( false ),
+ d( 0 )
+{
+ // initalize layout
+ if( DataBuffer )
+ BufferLayout->setLength( DataBuffer->size() );
+ BufferLayout->setNoOfLinesPerPage( noOfLinesPerPage() );
+
+ // creating the columns in the needed order
+ OffsetColumn = new KOffsetColumn( this, DefaultFirstLineOffset, DefaultNoOfBytesPerLine, KOffsetFormat::Hexadecimal );
+ FirstBorderColumn = new KBorderColumn( this, false );
+ ValueColumn = new KValueColumn( this, DataBuffer, BufferLayout, BufferRanges );
+ SecondBorderColumn = new KBorderColumn( this, true );
+ CharColumn = new KCharColumn( this, DataBuffer, BufferLayout, BufferRanges );
+
+ // select the active column
+ ActiveColumn = &charColumn();
+ InactiveColumn = &valueColumn();
+
+ // set encoding
+ Codec = KCharCodec::createCodec( (KHE::KEncoding)DefaultEncoding );
+ valueColumn().setCodec( Codec );
+ charColumn().setCodec( Codec );
+ Encoding = DefaultEncoding;
+
+ TabController = new KTabController( this, 0 );
+ Navigator = new KNavigator( this, TabController );
+ ValueEditor = new KValueEditor( ValueColumn, BufferCursor, this, Navigator );
+ CharEditor = new KCharEditor( CharColumn, BufferCursor, this, Navigator );
+
+ Controller = Navigator;
+
+#ifdef QT_ONLY
+ QFont FixedFont( "fixed", 10 );
+ FixedFont.setFixedPitch( true );
+ setFont( FixedFont );
+#else
+ setFont( KGlobalSettings::fixedFont() );
+#endif
+
+ // get the full control
+ viewport()->setFocusProxy( this );
+ viewport()->setFocusPolicy( WheelFocus );
+
+ viewport()->installEventFilter( this );
+ installEventFilter( this );
+
+ connect( CursorBlinkTimer, SIGNAL(timeout()), this, SLOT(blinkCursor()) );
+ connect( ScrollTimer, SIGNAL(timeout()), this, SLOT(autoScrollTimerDone()) );
+ connect( DragStartTimer, SIGNAL(timeout()), this, SLOT(startDrag()) );
+
+ viewport()->setAcceptDrops( true );
+}
+
+
+KHexEdit::~KHexEdit()
+{
+ delete TabController;
+ delete Navigator;
+ delete ValueEditor;
+ delete CharEditor;
+}
+
+
+int KHexEdit::noOfBytesPerLine() const { return BufferLayout->noOfBytesPerLine(); }
+int KHexEdit::firstLineOffset() const { return OffsetColumn->firstLineOffset(); }
+int KHexEdit::startOffset() const { return BufferLayout->startOffset(); }
+KHexEdit::KResizeStyle KHexEdit::resizeStyle() const { return ResizeStyle; }
+KHexEdit::KCoding KHexEdit::coding() const { return (KHexEdit::KCoding)valueColumn().coding(); }
+KPixelX KHexEdit::byteSpacingWidth() const { return valueColumn().byteSpacingWidth(); }
+int KHexEdit::noOfGroupedBytes() const { return valueColumn().noOfGroupedBytes(); }
+KPixelX KHexEdit::groupSpacingWidth() const { return valueColumn().groupSpacingWidth(); }
+KPixelX KHexEdit::binaryGapWidth() const { return valueColumn().binaryGapWidth(); }
+bool KHexEdit::isOverwriteMode() const { return OverWrite; }
+bool KHexEdit::isOverwriteOnly() const { return OverWriteOnly; }
+bool KHexEdit::isReadOnly() const { return ReadOnly; }
+bool KHexEdit::isModified() const { return DataBuffer->isModified(); }
+bool KHexEdit::tabChangesFocus() const { return TabController->tabChangesFocus(); }
+bool KHexEdit::showUnprintable() const { return charColumn().showUnprintable(); }
+QChar KHexEdit::substituteChar() const { return charColumn().substituteChar(); }
+QChar KHexEdit::undefinedChar() const { return charColumn().undefinedChar(); }
+KHexEdit::KEncoding KHexEdit::encoding() const { return (KHexEdit::KEncoding)Encoding; }
+const QString &KHexEdit::encodingName() const { return Codec->name(); }
+
+KSection KHexEdit::selection() const { return BufferRanges->selection(); }
+int KHexEdit::cursorPosition() const { return BufferCursor->index(); }
+bool KHexEdit::isCursorBehind() const { return BufferCursor->isBehind(); }
+KHexEdit::KBufferColumnId KHexEdit::cursorColumn() const
+{ return static_cast<KHE::KValueColumn *>( ActiveColumn ) == &valueColumn()? ValueColumnId : CharColumnId; }
+
+void KHexEdit::setOverwriteOnly( bool OO ) { OverWriteOnly = OO; if( OverWriteOnly ) setOverwriteMode( true ); }
+void KHexEdit::setModified( bool M ) { DataBuffer->setModified(M); }
+void KHexEdit::setTabChangesFocus( bool TCF ) { TabController->setTabChangesFocus(TCF); }
+void KHexEdit::setFirstLineOffset( int FLO ) { OffsetColumn->setFirstLineOffset( FLO ); }
+
+bool KHexEdit::offsetColumnVisible() const { return OffsetColumn->isVisible(); }
+int KHexEdit::visibleBufferColumns() const
+{ return (valueColumn().isVisible() ? ValueColumnId : 0) | (charColumn().isVisible() ? CharColumnId : 0); }
+
+
+void KHexEdit::setOverwriteMode( bool OM )
+{
+ if( (OverWriteOnly && !OM) || (OverWrite == OM) )
+ return;
+
+ OverWrite = OM;
+
+ // affected:
+ // cursor shape
+ bool ChangeCursor = !( CursorPaused || ValueEditor->isInEditMode() );
+ if( ChangeCursor )
+ pauseCursor();
+
+ BufferCursor->setAppendPosEnabled( !OverWrite );
+
+ if( ChangeCursor )
+ unpauseCursor();
+
+ emit cutAvailable( !OverWrite && BufferRanges->hasSelection() );
+}
+
+
+void KHexEdit::setDataBuffer( KDataBuffer *B )
+{
+ //pauseCursor();
+ ValueEditor->reset();
+ CursorPaused = true;
+
+ DataBuffer = B;
+ valueColumn().set( DataBuffer );
+ charColumn().set( DataBuffer);
+
+ // affected:
+ // length -> no of lines -> width
+ BufferLayout->setLength( DataBuffer->size() );
+ adjustLayoutToSize();
+
+ // ensure that the widget is readonly if the buffer is
+ if( DataBuffer->isReadOnly() )
+ setReadOnly( true );
+
+ updateView();
+ BufferCursor->gotoStart();
+ ensureCursorVisible();
+ unpauseCursor();
+}
+
+
+void KHexEdit::setStartOffset( int SO )
+{
+ if( !BufferLayout->setStartOffset(SO) )
+ return;
+
+ pauseCursor();
+ // affects:
+ // the no of lines -> width
+ adjustLayoutToSize();
+
+ updateView();
+
+ BufferCursor->updateCoord();
+ ensureCursorVisible();
+ unpauseCursor();
+}
+
+
+void KHexEdit::setReadOnly( bool RO )
+{
+ // don't set editor readwrite if databuffer is readonly
+ ReadOnly = (DataBuffer && DataBuffer->isReadOnly()) ? true : RO;
+
+ Controller = ReadOnly ? (KController*)Navigator :
+ cursorColumn() == CharColumnId ? (KController*)CharEditor : (KController*)ValueEditor;
+}
+
+
+void KHexEdit::setBufferSpacing( KPixelX ByteSpacing, int NoOfGroupedBytes, KPixelX GroupSpacing )
+{
+ if( !valueColumn().setSpacing(ByteSpacing,NoOfGroupedBytes,GroupSpacing) )
+ return;
+
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setCoding( KCoding C )
+{
+ uint OldCodingWidth = valueColumn().byteCodec()->encodingWidth();
+
+ if( !valueColumn().setCoding((KHE::KCoding)C) )
+ return;
+
+ uint NewCodingWidth = valueColumn().byteCodec()->encodingWidth();
+ ValueEditor->ByteBuffer.setLength( NewCodingWidth ); //hack for now
+
+ // no change in the width?
+ if( NewCodingWidth == OldCodingWidth )
+ updateColumn( valueColumn() );
+ else
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setResizeStyle( KResizeStyle NewStyle )
+{
+ if( ResizeStyle == NewStyle )
+ return;
+
+ ResizeStyle = NewStyle;
+
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setNoOfBytesPerLine( int NoBpL )
+{
+ // if the number is explicitly set we expect a wish for no automatic resize
+ ResizeStyle = NoResize;
+
+ if( !BufferLayout->setNoOfBytesPerLine(NoBpL) )
+ return;
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setByteSpacingWidth( int/*KPixelX*/ BSW )
+{
+ if( !valueColumn().setByteSpacingWidth(BSW) )
+ return;
+ updateViewByWidth();
+}
+
+void KHexEdit::setNoOfGroupedBytes( int NoGB )
+{
+ if( !valueColumn().setNoOfGroupedBytes(NoGB) )
+ return;
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setGroupSpacingWidth( int/*KPixelX*/ GSW )
+{
+ if( !valueColumn().setGroupSpacingWidth(GSW) )
+ return;
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setBinaryGapWidth( int/*KPixelX*/ BGW )
+{
+ if( !valueColumn().setBinaryGapWidth(BGW) )
+ return;
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setSubstituteChar( QChar SC )
+{
+ if( !charColumn().setSubstituteChar(SC) )
+ return;
+ pauseCursor();
+ updateColumn( charColumn() );
+ unpauseCursor();
+}
+
+void KHexEdit::setUndefinedChar( QChar UC )
+{
+ if( !charColumn().setUndefinedChar(UC) )
+ return;
+ pauseCursor();
+ updateColumn( charColumn() );
+ unpauseCursor();
+}
+
+void KHexEdit::setShowUnprintable( bool SU )
+{
+ if( !charColumn().setShowUnprintable(SU) )
+ return;
+ pauseCursor();
+ updateColumn( charColumn() );
+ unpauseCursor();
+}
+
+
+void KHexEdit::setEncoding( KEncoding C )
+{
+ if( Encoding == C )
+ return;
+
+ KCharCodec *NC = KCharCodec::createCodec( (KHE::KEncoding)C );
+ if( NC == 0 )
+ return;
+
+ valueColumn().setCodec( NC );
+ charColumn().setCodec( NC );
+
+ delete Codec;
+ Codec = NC;
+ Encoding = C;
+
+ pauseCursor();
+ updateColumn( valueColumn() );
+ updateColumn( charColumn() );
+ unpauseCursor();
+}
+
+// TODO: join with function above!
+void KHexEdit::setEncoding( const QString& EncodingName )
+{
+ if( EncodingName == Codec->name() )
+ return;
+
+ KCharCodec *NC = KCharCodec::createCodec( EncodingName );
+ if( NC == 0 )
+ return;
+
+ valueColumn().setCodec( NC );
+ charColumn().setCodec( NC );
+
+ delete Codec;
+ Codec = NC;
+ Encoding = LocalEncoding; // TODO: add encoding no to every known codec
+
+ pauseCursor();
+ updateColumn( valueColumn() );
+ updateColumn( charColumn() );
+ unpauseCursor();
+}
+
+
+void KHexEdit::fontChange( const QFont &OldFont )
+{
+ QScrollView::fontChange( OldFont );
+
+ if( !InZooming )
+ DefaultFontSize = font().pointSize();
+
+ // get new values
+ QFontMetrics FM( fontMetrics() );
+ KPixelX DigitWidth = FM.maxWidth();
+ KPixelY DigitBaseLine = FM.ascent();
+
+ setLineHeight( FM.height() );
+
+ // update all dependant structures
+ BufferLayout->setNoOfLinesPerPage( noOfLinesPerPage() );
+
+ OffsetColumn->setMetrics( DigitWidth, DigitBaseLine );
+ valueColumn().setMetrics( DigitWidth, DigitBaseLine );
+ charColumn().setMetrics( DigitWidth, DigitBaseLine );
+
+ updateViewByWidth();
+}
+
+
+void KHexEdit::updateViewByWidth()
+{
+ pauseCursor();
+
+ adjustToLayoutNoOfBytesPerLine();
+ adjustLayoutToSize();
+
+ updateView();
+
+ BufferCursor->updateCoord();
+ ensureCursorVisible();
+
+ unpauseCursor();
+}
+
+
+void KHexEdit::zoomIn() { zoomIn( DefaultZoomStep ); }
+void KHexEdit::zoomOut() { zoomOut( DefaultZoomStep ); }
+
+void KHexEdit::zoomIn( int PointInc )
+{
+ InZooming = true;
+ QFont F( font() );
+ F.setPointSize( QFontInfo(F).pointSize() + PointInc );
+ setFont( F );
+ InZooming = false;
+}
+
+void KHexEdit::zoomOut( int PointDec )
+{
+ InZooming = true;
+ QFont F( font() );
+ F.setPointSize( QMAX( 1, QFontInfo(F).pointSize() - PointDec ) );
+ setFont( F );
+ InZooming = false;
+}
+
+
+void KHexEdit::zoomTo( int PointSize )
+{
+ InZooming = true;
+ QFont F( font() );
+ F.setPointSize( PointSize );
+ setFont( F );
+ InZooming = false;
+}
+
+
+void KHexEdit::unZoom()
+{
+ zoomTo( DefaultFontSize );
+}
+
+
+void KHexEdit::adjustLayoutToSize()
+{
+ // check whether there is a change with the numbers of fitting bytes per line
+ if( ResizeStyle != NoResize )
+ {
+ int FittingBytesPerLine = fittingBytesPerLine( size() );
+
+// std::cout<<"FitBpL"<<FittingBytesPerLine<<std::endl;
+
+ // changes?
+ if( BufferLayout->setNoOfBytesPerLine(FittingBytesPerLine) )
+ adjustToLayoutNoOfBytesPerLine();
+ }
+
+ setNoOfLines( BufferLayout->noOfLines() );
+}
+
+
+void KHexEdit::adjustToLayoutNoOfBytesPerLine()
+{
+ OffsetColumn->setDelta( BufferLayout->noOfBytesPerLine() );
+ valueColumn().resetXBuffer();
+ charColumn().resetXBuffer();
+
+ updateWidths();
+}
+
+
+void KHexEdit::setNoOfLines( int NewNoOfLines )
+{
+ KColumnsView::setNoOfLines( NewNoOfLines>1?NewNoOfLines:1 );
+}
+
+
+void KHexEdit::toggleOffsetColumn( bool Visible )
+{
+ bool OCVisible = OffsetColumn->isVisible();
+ // no change?
+ if( OCVisible == Visible )
+ return;
+
+ OffsetColumn->setVisible( Visible );
+ FirstBorderColumn->setVisible( Visible );
+
+ updateViewByWidth();
+}
+
+
+QSize KHexEdit::sizeHint() const
+{
+ return QSize( totalWidth(), totalHeight() );
+}
+
+
+QSize KHexEdit::minimumSizeHint() const
+{
+ // TODO: better minimal width (visibility!)
+ return QSize( OffsetColumn->visibleWidth()+FirstBorderColumn->visibleWidth()+SecondBorderColumn->visibleWidth()+valueColumn().byteWidth()+charColumn().byteWidth(),
+ lineHeight() + noOfLines()>1? style().pixelMetric(QStyle::PM_ScrollBarExtent):0 );
+}
+
+
+void KHexEdit::resizeEvent( QResizeEvent *ResizeEvent )
+{
+ if( ResizeStyle != NoResize )
+ {
+ int FittingBytesPerLine = fittingBytesPerLine( ResizeEvent->size() );
+
+ // changes?
+ if( BufferLayout->setNoOfBytesPerLine(FittingBytesPerLine) )
+ {
+ setNoOfLines( BufferLayout->noOfLines() );
+ updateViewByWidth();
+ }
+ }
+
+ QScrollView::resizeEvent( ResizeEvent );
+
+ BufferLayout->setNoOfLinesPerPage( noOfLinesPerPage() ); // TODO: doesn't work with the new size!!!
+}
+
+
+int KHexEdit::fittingBytesPerLine( const QSize &NewSize ) const
+{
+ KPixelX ReservedWidth = OffsetColumn->visibleWidth() + FirstBorderColumn->visibleWidth() + SecondBorderColumn->visibleWidth();
+
+ // abstract framewidth as well as offset and border columns width
+ int UsedbyFrameWidth = 2 * frameWidth();
+ KPixelX FullWidth = NewSize.width() - UsedbyFrameWidth - ReservedWidth;
+
+// // no width left for resizeable columns? TODO: put this in resizeEvent
+// if( FullWidth < 0 )
+// return;
+
+ KPixelY FullHeight = NewSize.height() - UsedbyFrameWidth;
+
+ // check influence of dis-/appearing of the vertical scrollbar
+ bool VerticalScrollbarIsVisible = verticalScrollBar()->isVisible();
+ KPixelX ScrollbarExtent = style().pixelMetric( QStyle::PM_ScrollBarExtent );//verticalScrollBar()->width();
+
+ KPixelX AvailableWidth = FullWidth;
+ if( VerticalScrollbarIsVisible )
+ AvailableWidth -= ScrollbarExtent;
+
+ enum KMatchTrial { FirstRun, RerunWithScrollbarOn, TestWithoutScrollbar };
+ KMatchTrial MatchRun = FirstRun;
+
+ // prepare needed values
+ KPixelX DigitWidth = valueColumn().digitWidth();
+ KPixelX TextByteWidth = charColumn().isVisible() ? DigitWidth : 0;
+ KPixelX HexByteWidth = valueColumn().isVisible() ? valueColumn().byteWidth() : 0;
+ KPixelX ByteSpacingWidth = valueColumn().isVisible() ? valueColumn().byteSpacingWidth() : 0;
+ KPixelX GroupSpacingWidth;
+ int NoOfGroupedBytes = valueColumn().noOfGroupedBytes();
+ // no grouping?
+ if( NoOfGroupedBytes == 0 )
+ {
+ // faking grouping by 1
+ NoOfGroupedBytes = 1;
+ GroupSpacingWidth = 0;
+ }
+ else
+ GroupSpacingWidth = valueColumn().isVisible() ? valueColumn().groupSpacingWidth() : 0;
+
+ KPixelX HexByteGroupWidth = NoOfGroupedBytes * HexByteWidth + (NoOfGroupedBytes-1)*ByteSpacingWidth;
+ KPixelX TextByteGroupWidth = NoOfGroupedBytes * TextByteWidth;
+ KPixelX TotalGroupWidth = HexByteGroupWidth + GroupSpacingWidth + TextByteGroupWidth;
+
+ int FittingBytesPerLine;
+ int WithScrollbarFittingBytesPerLine = 0;
+ for(;;)
+ {
+// std::cout << "matchWidth: " << FullWidth
+// << " (v:" << visibleWidth()
+// << ", f:" << frameWidth()
+// << ", A:" << AvailableWidth
+// << ", S:" << ScrollbarExtent
+// << ", R:" << ReservedWidth << ")" << std::endl;
+
+ // calculate fitting groups per line
+ int FittingGroupsPerLine = (AvailableWidth+GroupSpacingWidth) // fake spacing after last group
+ / TotalGroupWidth;
+
+ // calculate the fitting bytes per line by groups
+ FittingBytesPerLine = NoOfGroupedBytes * FittingGroupsPerLine;
+
+ // not only full groups?
+ if( ResizeStyle == FullSizeUsage && NoOfGroupedBytes > 1 )
+ {
+ if( FittingGroupsPerLine > 0 )
+ AvailableWidth -= FittingGroupsPerLine*TotalGroupWidth; // includes additional spacing after last group
+
+// std::cout << "Left: " << AvailableWidth << "("<<HexByteWidth<<", "<<TextByteWidth<<")" << std::endl;
+
+ if( AvailableWidth > 0 )
+ FittingBytesPerLine += (AvailableWidth+ByteSpacingWidth) / (HexByteWidth+ByteSpacingWidth+TextByteWidth);
+
+ // is there not even the space for a single byte?
+ if( FittingBytesPerLine == 0 )
+ {
+ // ensure at least one byte per line
+ FittingBytesPerLine = 1;
+ // and
+ break;
+ }
+ }
+ // is there not the space for a single group?
+ else if( FittingBytesPerLine == 0 )
+ {
+ // ensures at least one group
+ FittingBytesPerLine = NoOfGroupedBytes;
+ break;
+ }
+
+// std::cout << "meantime: " << FittingGroupsPerLine << " (T:" << TotalGroupWidth
+// << ", h:" << HexByteGroupWidth
+// << ", t:" << TextByteGroupWidth
+// << ", s:" << GroupSpacingWidth << ") " <<FittingBytesPerLine<< std::endl;
+
+ int NewNoOfLines = (BufferLayout->length()+BufferLayout->startOffset()+FittingBytesPerLine-1)
+ / FittingBytesPerLine;
+ KPixelY NewHeight = NewNoOfLines * LineHeight;
+
+ if( VerticalScrollbarIsVisible )
+ {
+ if( MatchRun == TestWithoutScrollbar )
+ {
+ // did the test without the scrollbar fail, don't the data fit into the view?
+ if( NewHeight>FullHeight )
+ // reset to old calculated value
+ FittingBytesPerLine = WithScrollbarFittingBytesPerLine;
+ break;
+ }
+
+ // a chance for to perhaps fit in height?
+ if( FittingBytesPerLine <= BufferLayout->noOfBytesPerLine() )
+ {
+ // remember this trial's result and calc number of bytes with vertical scrollbar on
+ WithScrollbarFittingBytesPerLine = FittingBytesPerLine;
+ AvailableWidth = FullWidth;
+ MatchRun = TestWithoutScrollbar;
+// std::cout << "tested without scrollbar..." << std::endl;
+ continue;
+ }
+ }
+ else
+ {
+ // doesn't it fit into the height anymore?
+ if( NewHeight>FullHeight && MatchRun==FirstRun )
+ {
+ // need for a scrollbar has risen... ->less width, new calculation
+ AvailableWidth = FullWidth - ScrollbarExtent;
+ MatchRun = RerunWithScrollbarOn;
+// std::cout << "rerun with scrollbar on..." << std::endl;
+ continue;
+ }
+ }
+
+ break;
+ }
+
+ return FittingBytesPerLine;
+}
+
+
+bool KHexEdit::selectWord( /*unsigned TODO:change all unneeded signed into unsigned!*/ int Index )
+{
+ if( Index >= 0 && Index < BufferLayout->length() )
+ {
+ KWordBufferService WBS( DataBuffer, Codec );
+ KSection WordSection = WBS.wordSection( Index );
+ if( WordSection.isValid() )
+ {
+ pauseCursor();
+
+ BufferRanges->setFirstWordSelection( WordSection );
+ BufferCursor->gotoIndex( WordSection.end()+1 );
+ repaintChanged();
+
+ unpauseCursor();
+ return true;
+ }
+ }
+ return false;
+}
+
+void KHexEdit::select( KSection Section )
+{
+ if( !Section.isValid() )
+ return;
+
+ Section.restrictTo( KSection(0,BufferLayout->length()-1) );
+
+ pauseCursor();
+
+ BufferRanges->setSelection( Section );
+ BufferCursor->gotoIndex( Section.end()+1 );
+ repaintChanged();
+
+ unpauseCursor();
+
+ if( !OverWrite ) emit cutAvailable( BufferRanges->hasSelection() );
+ emit copyAvailable( BufferRanges->hasSelection() );
+ emit selectionChanged( Section.start(), Section.end() );
+}
+
+void KHexEdit::selectAll( bool Select )
+{
+ KSection Selection;
+
+ pauseCursor( true );
+
+ if( !Select )
+ BufferRanges->removeSelection();
+ else
+ {
+ Selection.set( 0, BufferLayout->length()-1 );
+ BufferRanges->setSelection( Selection );
+ BufferCursor->gotoEnd();
+ }
+
+ repaintChanged();
+
+ unpauseCursor();
+
+ if( !OverWrite ) emit cutAvailable( BufferRanges->hasSelection() );
+ emit copyAvailable( BufferRanges->hasSelection() );
+ emit selectionChanged( Selection.start(), Selection.end() );
+ viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
+}
+
+
+bool KHexEdit::hasSelectedData() const
+{
+ return BufferRanges->hasSelection();
+}
+
+
+QByteArray KHexEdit::selectedData() const
+{
+ if( !BufferRanges->hasSelection() )
+ return QByteArray();
+
+ KSection Selection = BufferRanges->selection();
+ QByteArray SD( Selection.width() );
+ DataBuffer->copyTo( SD.data(), Selection.start(), Selection.width() );
+ return SD;
+}
+
+
+KBufferDrag *KHexEdit::dragObject( QWidget *Parent ) const
+{
+ if( !BufferRanges->hasSelection() )
+ return 0;
+
+ const KOffsetColumn *OC;
+ const KValueColumn *HC;
+ const KCharColumn *TC;
+ KCoordRange Range;
+
+ if( static_cast<KHE::KCharColumn *>( ActiveColumn ) == &charColumn() )
+ {
+ OC = 0;
+ HC = 0;
+ TC = 0;
+ }
+ else
+ {
+ OC = OffsetColumn->isVisible() ? OffsetColumn : 0;
+ HC = valueColumn().isVisible() ? &valueColumn() : 0;
+ TC = charColumn().isVisible() ? &charColumn() : 0;
+ KSection S = BufferRanges->selection();
+ Range.set( BufferLayout->coordOfIndex(S.start()),BufferLayout->coordOfIndex(S.end()) );
+ }
+
+ return new KBufferDrag( selectedData(), Range, OC, HC, TC,
+ charColumn().substituteChar(), charColumn().undefinedChar(),
+ Codec->name(), Parent );
+}
+
+
+void KHexEdit::cut()
+{
+ if( isReadOnly() || OverWrite )
+ return;
+
+ KBufferDrag *Drag = dragObject();
+ if( !Drag )
+ return;
+
+ QApplication::clipboard()->setData( Drag, ClipboardMode );
+
+ removeSelectedData();
+}
+
+
+void KHexEdit::copy()
+{
+ KBufferDrag *Drag = dragObject();
+ if( !Drag )
+ return;
+
+ QApplication::clipboard()->setData( Drag, ClipboardMode );
+}
+
+
+void KHexEdit::paste()
+{
+ if( isReadOnly() )
+ return;
+
+ QMimeSource *Source = QApplication::clipboard()->data( ClipboardMode );
+ pasteFromSource( Source );
+}
+
+
+void KHexEdit::pasteFromSource( QMimeSource *Source )
+{
+ if( !Source || !KBufferDrag::canDecode(Source) )
+ return;
+
+ QByteArray Data;
+ if( !KBufferDrag::decode(Source,Data) )
+ return;
+
+ if( !Data.isEmpty() )
+ insert( Data );
+}
+
+
+void KHexEdit::insert( const QByteArray &D )
+{
+ pauseCursor( true );
+
+ KSection ChangedRange;
+
+ if( OverWrite )
+ {
+ if( BufferRanges->hasSelection() )
+ {
+ // replacing the selection:
+ // we restrict the replacement to the minimum length of selection and input
+ ChangedRange = BufferRanges->selection();
+ ChangedRange.restrictEndTo( ChangedRange.start()+D.size()-1 );
+ int W = DataBuffer->replace( ChangedRange, D.data(), ChangedRange.width() );
+ BufferCursor->gotoCIndex( ChangedRange.start()+W );
+ BufferRanges->removeSelection();
+ }
+ else
+ {
+ if( !BufferCursor->isBehind() )
+ {
+ // replacing the normal data, at least until the end
+ ChangedRange.setByWidth( BufferCursor->realIndex(), D.size() );
+ ChangedRange.restrictEndTo( BufferLayout->length()-1 );
+ if( ChangedRange.isValid() )
+ {
+ int W = DataBuffer->replace( ChangedRange, D.data(), ChangedRange.width() );
+ BufferCursor->gotoNextByte( W );
+ }
+ }
+ }
+ }
+ else
+ {
+ if( BufferRanges->hasSelection() )
+ {
+ // replacing the selection
+ KSection Selection = BufferRanges->selection();
+ int OldLastIndex = BufferLayout->length() - 1;
+ int W = DataBuffer->replace( Selection, D.data(), D.size() );
+ updateLength();
+ BufferCursor->gotoIndex( Selection.start() + W );
+ if( W > 0 )
+ {
+ if( Selection.width() == (int)D.size() )
+ ChangedRange = Selection;
+ else
+ {
+ int NewLastIndex = DataBuffer->size() - 1;
+ ChangedRange.set( Selection.start(), NewLastIndex>OldLastIndex?NewLastIndex:OldLastIndex );
+ }
+ }
+ BufferRanges->removeSelection();
+ }
+ else
+ {
+ bool Appending = BufferCursor->atAppendPos();
+ int OldIndex = BufferCursor->realIndex();
+ int W = DataBuffer->insert( OldIndex, D.data(), D.size() );
+ updateLength();
+ // worked?
+ if( W > 0 )
+ {
+ if( Appending )
+ BufferCursor->gotoEnd();
+ else
+ BufferCursor->gotoNextByte( W );
+ ChangedRange.set( OldIndex, DataBuffer->size()-1 );
+ }
+ }
+ }
+
+ bool Changed = ChangedRange.isValid();
+ if( Changed )
+ {
+ BufferRanges->addChangedRange( ChangedRange );
+ repaintChanged();
+ }
+ ensureCursorVisible();
+
+ unpauseCursor();
+
+ if( Changed ) emit bufferChanged( ChangedRange.start(), ChangedRange.end() );
+ KSection Selection = BufferRanges->selection();
+ emit selectionChanged( Selection.start(), Selection.end() );
+}
+
+
+void KHexEdit::removeSelectedData()
+{
+ // Can't we do this?
+ if( isReadOnly() || OverWrite || ValueEditor->isInEditMode() )
+ return;
+
+ pauseCursor();
+
+ KSection Selection = BufferRanges->selection();
+
+ BufferRanges->removeFurtherSelections();
+
+ KSection ChangedRange = removeData( Selection );
+ BufferRanges->removeSelection();
+
+ repaintChanged();
+
+ BufferCursor->gotoCIndex( Selection.start() );
+
+ ensureCursorVisible();
+// clearUndoRedo();
+ viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
+
+ unpauseCursor();
+
+ if( ChangedRange.isValid() ) emit bufferChanged( ChangedRange.start(), ChangedRange.end() );
+ emit selectionChanged( -1, -1 );
+}
+
+
+KSection KHexEdit::removeData( KSection Indizes )
+{
+// if( undoEnabled )
+// {
+// checkUndoRedoInfo( UndoRedoInfo::RemoveSelected );
+// if( !undoRedoInfo.valid() )
+// {
+// doc->selectionStart( selNum, undoRedoInfo.id, undoRedoInfo.index );
+// undoRedoInfo.d->text = QString::null;
+// }
+// readFormats( c1, c2, undoRedoInfo.d->text, TRUE );
+// }
+
+ KSection ChangedRange( Indizes.start(), BufferLayout->length()-1 );
+ // do it!
+ DataBuffer->remove( Indizes );
+ updateLength();
+ BufferRanges->addChangedRange( ChangedRange );
+
+ return ChangedRange;
+}
+
+
+void KHexEdit::updateLength()
+{
+ BufferLayout->setLength( DataBuffer->size() );
+ setNoOfLines( BufferLayout->noOfLines() );
+}
+
+
+void KHexEdit::clipboardChanged()
+{
+ // don't listen to selection changes
+ disconnect( QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0 );
+ selectAll( false );
+}
+
+
+void KHexEdit::setCursorPosition( int Index, bool Behind )
+{
+ pauseCursor( true );
+
+ BufferCursor->gotoCIndex( Index );
+ if( Behind )
+ BufferCursor->stepBehind();
+
+ BufferRanges->removeSelection();
+ bool RangesModifed = BufferRanges->isModified();
+ if( RangesModifed )
+ {
+ repaintChanged();
+
+ viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
+
+ }
+ ensureCursorVisible();
+ unpauseCursor();
+
+ if( RangesModifed )
+ {
+ if( !OverWrite ) emit cutAvailable( BufferRanges->hasSelection() );
+ emit copyAvailable( BufferRanges->hasSelection() );
+ emit selectionChanged( -1, -1 );
+ }
+}
+
+
+void KHexEdit::showBufferColumns( int CCs )
+{
+ int Columns = visibleBufferColumns();
+
+ // no changes or no column selected?
+ if( CCs == Columns || !(CCs&( ValueColumnId | CharColumnId )) )
+ return;
+
+ valueColumn().setVisible( ValueColumnId & CCs );
+ charColumn().setVisible( CharColumnId & CCs );
+ SecondBorderColumn->setVisible( CCs == (ValueColumnId|CharColumnId) );
+
+ // active column not visible anymore?
+ if( !activeColumn().isVisible() )
+ {
+ KBufferColumn *H = ActiveColumn;
+ ActiveColumn = InactiveColumn;
+ InactiveColumn = H;
+ Controller = ReadOnly ? (KController*)Navigator :
+ cursorColumn() == CharColumnId ? (KController*)CharEditor : (KController*)ValueEditor;
+ }
+
+ updateViewByWidth();
+}
+
+
+void KHexEdit::setCursorColumn( KBufferColumnId CC )
+{
+ // no changes or not visible?
+ if( CC == cursorColumn()
+ || (CC == ValueColumnId && !valueColumn().isVisible())
+ || (CC == CharColumnId && !charColumn().isVisible()) )
+ return;
+
+ pauseCursor( true );
+
+ if( CC == ValueColumnId )
+ {
+ ActiveColumn = &valueColumn();
+ InactiveColumn = &charColumn();
+ }
+ else
+ {
+ ActiveColumn = &charColumn();
+ InactiveColumn = &valueColumn();
+ }
+ Controller = ReadOnly ? (KController*)Navigator :
+ cursorColumn() == CharColumnId ? (KController*)CharEditor : (KController*)ValueEditor;
+
+ ensureCursorVisible();
+ unpauseCursor();
+}
+
+
+void KHexEdit::placeCursor( const QPoint &Point )
+{
+ resetInputContext();
+
+ // switch active column if needed
+ if( charColumn().isVisible() && Point.x() >= charColumn().x() )
+ {
+ ActiveColumn = &charColumn();
+ InactiveColumn = &valueColumn();
+ }
+ else
+ {
+ ActiveColumn = &valueColumn();
+ InactiveColumn = &charColumn();
+ }
+ Controller = ReadOnly ? (KController*)Navigator :
+ cursorColumn() == CharColumnId ? (KController*)CharEditor : (KController*)ValueEditor;
+
+ // get coord of click and whether this click was closer to the end of the pos
+ KBufferCoord C( activeColumn().magPosOfX(Point.x()), lineAt(Point.y()) );
+
+ BufferCursor->gotoCCoord( C );
+}
+
+
+int KHexEdit::indexByPoint( const QPoint &Point ) const
+{
+ const KBufferColumn *C;
+ if( charColumn().isVisible() && Point.x() >= charColumn().x() )
+ C = &charColumn();
+ else
+ C = &valueColumn();
+
+ KBufferCoord Coord( C->posOfX(Point.x()), lineAt(Point.y()) );
+
+ return BufferLayout->indexAtCCoord( Coord );
+}
+
+
+void KHexEdit::showEvent( QShowEvent *e )
+{
+ KColumnsView::showEvent( e );
+ BufferLayout->setNoOfLinesPerPage( noOfLinesPerPage() );
+}
+
+
+bool KHexEdit::eventFilter( QObject *O, QEvent *E )
+{
+ if( O == this || O == viewport() )
+ {
+ if( E->type() == QEvent::FocusIn )
+ {
+ startCursor();
+ }
+ else if( E->type() == QEvent::FocusOut )
+ {
+ stopCursor();
+ }
+ }
+
+// if( O == this && E->type() == QEvent::PaletteChange )
+// {
+// QColor old( viewport()->colorGroup().color(QColorGroup::Text) );
+//
+// if( old != colorGroup().color(QColorGroup::Text) )
+// {
+// QColor c( colorGroup().color(QColorGroup::Text) );
+// doc->setMinimumWidth( -1 );
+// doc->setDefaultFormat( doc->formatCollection()->defaultFormat()->font(), c );
+// lastFormatted = doc->firstParagraph();
+// formatMore();
+// repaintChanged();
+// }
+// }
+
+ return QScrollView::eventFilter( O, E );
+}
+
+
+void KHexEdit::blinkCursor()
+{
+ // skip the cursor drawing?
+ if( CursorPaused || ValueEditor->isInEditMode() )
+ return;
+
+ // switch the cursor state
+ paintActiveCursor( !BlinkCursorVisible );
+}
+
+
+void KHexEdit::startCursor()
+{
+ CursorPaused = false;
+
+ updateCursor();
+
+ CursorBlinkTimer->start( QApplication::cursorFlashTime()/2 );
+}
+
+
+void KHexEdit::unpauseCursor()
+{
+ CursorPaused = false;
+
+ if( CursorBlinkTimer->isActive() )
+ updateCursor();
+}
+
+
+void KHexEdit::updateCursor()
+{
+ createCursorPixmaps();
+
+ paintActiveCursor( true );
+ paintInactiveCursor( true );
+}
+
+
+void KHexEdit::stopCursor()
+{
+ CursorBlinkTimer->stop();
+
+ pauseCursor();
+}
+
+
+void KHexEdit::pauseCursor( bool LeaveEdit )
+{
+ paintActiveCursor( false );
+ paintInactiveCursor( false );
+
+ if( LeaveEdit )
+ ValueEditor->InEditMode = false;
+ CursorPaused = true;
+}
+
+
+void KHexEdit::createCursorPixmaps()
+{
+ // create CursorPixmaps
+ CursorPixmaps->setSize( activeColumn().byteWidth(), LineHeight );
+
+ int Index = BufferCursor->validIndex();
+
+ QPainter Paint;
+ Paint.begin( &CursorPixmaps->offPixmap(), this );
+ activeColumn().paintByte( &Paint, Index );
+ Paint.end();
+
+ Paint.begin( &CursorPixmaps->onPixmap(), this );
+ activeColumn().paintCursor( &Paint, Index );
+ Paint.end();
+
+ // calculat the shape
+ KPixelX CursorX;
+ KPixelX CursorW;
+ if( BufferCursor->isBehind() )
+ {
+ CursorX = QMAX( 0, CursorPixmaps->onPixmap().width()-InsertCursorWidth );
+ CursorW = InsertCursorWidth;
+ }
+ else
+ {
+ CursorX = 0;
+ CursorW = OverWrite ? -1 : InsertCursorWidth;
+ }
+ CursorPixmaps->setShape( CursorX, CursorW );
+}
+
+
+void KHexEdit::pointPainterToCursor( QPainter &Painter, const KBufferColumn &Column ) const
+{
+ int x = Column.xOfPos( BufferCursor->pos() ) - contentsX();
+ int y = LineHeight * BufferCursor->line() - contentsY();
+
+ Painter.begin( viewport() );
+ Painter.translate( x, y );
+}
+
+
+void KHexEdit::paintActiveCursor( bool CursorOn )
+{
+ // any reason to skip the cursor drawing?
+ if( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled()
+ || (CursorOn && !hasFocus() && !viewport()->hasFocus() && !InDnD ) )
+ return;
+
+ QPainter Painter;
+ pointPainterToCursor( Painter, activeColumn() );
+
+ // paint edited byte?
+ if( ValueEditor->isInEditMode() )
+ {
+ int Index = BufferCursor->index();
+
+ if( CursorOn )
+ valueColumn().paintEditedByte( &Painter, ValueEditor->EditValue, ValueEditor->ByteBuffer );
+ else
+ valueColumn().paintByte( &Painter, Index );
+ }
+ else
+ {
+
+ Painter.drawPixmap( CursorPixmaps->cursorX(), 0,
+ CursorOn?CursorPixmaps->onPixmap():CursorPixmaps->offPixmap(),
+ CursorPixmaps->cursorX(),0,CursorPixmaps->cursorW(),-1 );
+ // store state
+ BlinkCursorVisible = CursorOn;
+ }
+}
+
+
+void KHexEdit::paintInactiveCursor( bool CursorOn )
+{
+ // any reason to skip the cursor drawing?
+ if( !isUpdatesEnabled()
+ || !viewport()->isUpdatesEnabled()
+ || !inactiveColumn().isVisible()
+ || (CursorOn && !hasFocus() && !viewport()->hasFocus() && !InDnD) )
+ return;
+
+ int Index = BufferCursor->validIndex();
+
+ QPainter Painter;
+ pointPainterToCursor( Painter, inactiveColumn() );
+ if( CursorOn )
+ {
+ KBufferColumn::KFrameStyle Style =
+ BufferCursor->isBehind() ? KBufferColumn::Right :
+ (OverWrite||ValueEditor->isInEditMode()) ? KBufferColumn::Frame :
+ KBufferColumn::Left;
+ inactiveColumn().paintFramedByte( &Painter, Index, Style );
+ }
+ else
+ inactiveColumn().paintByte( &Painter, Index );
+}
+
+
+void KHexEdit::drawContents( QPainter *P, int cx, int cy, int cw, int ch )
+{
+ KColumnsView::drawContents( P, cx, cy, cw, ch );
+ // TODO: update non blinking cursors. Should this perhaps be done in the buffercolumn?
+ // Then it needs to know about inactive, insideByte and the like... well...
+ // perhaps subclassing the buffer columns even more, to KCharColumn and KValueColumn?
+
+ if( !CursorPaused && visibleLines(KPixelYs(cy,ch,false)).includes(BufferCursor->line()) )
+ {
+ paintActiveCursor( true );
+ paintInactiveCursor( true );
+ }
+}
+
+void KHexEdit::updateColumn( KColumn &Column )
+{
+ //kdDebug(1501) << "updateColumn\n";
+ if( Column.isVisible() )
+ updateContents( Column.x(), 0, Column.width(), totalHeight() );
+}
+
+
+void KHexEdit::keyPressEvent( QKeyEvent *KeyEvent )
+{
+ if( !Controller->handleKeyPress( KeyEvent ) )
+ KeyEvent->ignore();
+}
+
+
+void KHexEdit::repaintChanged()
+{
+ if( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() || !BufferRanges->isModified() )
+ return;
+
+ // TODO: we do this only to let the scrollview handle new or removed lines. overlaps with repaintRange
+ resizeContents( totalWidth(), totalHeight() );
+
+ KPixelXs Xs( contentsX(), visibleWidth(), true );
+
+ // collect affected buffer columns
+ QPtrList<KBufferColumn> RepaintColumns;
+
+ KBufferColumn *C = ValueColumn;
+ while( true )
+ {
+ if( C->isVisible() && C->overlaps(Xs) )
+ {
+ RepaintColumns.append( C );
+ C->preparePainting( Xs );
+ }
+
+ if( C == CharColumn )
+ break;
+ C = CharColumn;
+ }
+
+ // any colums to paint?
+ if( RepaintColumns.count() > 0 )
+ {
+ KPixelYs Ys( contentsY(), visibleHeight(), true );
+
+ // calculate affected lines/indizes
+ KSection FullPositions( 0, BufferLayout->noOfBytesPerLine()-1 );
+ KCoordRange VisibleRange( FullPositions, visibleLines(Ys) );
+
+ KCoordRange ChangedRange;
+ // as there might be multiple selections on this line redo until no more is changed
+ while( hasChanged(VisibleRange,&ChangedRange) )
+ {
+// std::cout << " changed->"<<FirstChangedIndex<<","<<LastChangedIndex<<std::endl;
+
+ // only one line?
+ if( ChangedRange.start().line() == ChangedRange.end().line() )
+ for( KBufferColumn *C=RepaintColumns.first(); C; C=RepaintColumns.next() )
+ paintLine( C, ChangedRange.start().line(),
+ KSection(ChangedRange.start().pos(),ChangedRange.end().pos()) );
+ //
+ else
+ {
+ // first line
+ for( KBufferColumn *C=RepaintColumns.first(); C; C=RepaintColumns.next() )
+ paintLine( C, ChangedRange.start().line(),
+ KSection(ChangedRange.start().pos(),FullPositions.end()) );
+
+ // at least one full line?
+ for( int l = ChangedRange.start().line()+1; l < ChangedRange.end().line(); ++l )
+ for( KBufferColumn *C=RepaintColumns.first(); C; C=RepaintColumns.next() )
+ paintLine( C, l, FullPositions );
+
+ // last line
+ for( KBufferColumn *C=RepaintColumns.first(); C; C=RepaintColumns.next() )
+ paintLine( C, ChangedRange.end().line(),
+ KSection(FullPositions.start(),ChangedRange.end().pos()) );
+ }
+
+ // continue the search at the overnext index
+ VisibleRange.setStart( ChangedRange.end()+2 );
+ if( !VisibleRange.isValid() )
+ break;
+ }
+ }
+
+
+ // Paint possible removed bytes at the end of the last line
+ // Paint new/removed trailing lines
+// drawContents( P, cx, cy, cw, ch );
+ // Paint empty rects
+// paintEmptyArea( P, cx, cy, cw, ch );
+// BufferLayout->noOfLines()
+
+ BufferRanges->resetChangedRanges();
+}
+
+
+void KHexEdit::paintLine( KBufferColumn *C, int Line, KSection Positions )
+{
+ Positions.restrictTo( C->visiblePositions() );
+
+ // nothing to paint?
+ if( !Positions.isValid() )
+ return;
+// std::cout << " paintLine->"<<Line<< ":"<<FirstPos<<","<<LastPos<<std::endl;
+
+ // calculating pixel values
+ KPixelXs XPixels = C->wideXPixelsOfPos( Positions );
+
+ KPixelY cy = Line * LineHeight;
+
+ // to avoid flickers we first paint to the linebuffer
+ QPainter Paint;
+ Paint.begin( &LineBuffer, this );
+
+ Paint.translate( C->x(), 0 );
+ C->paintPositions( &Paint, Line, Positions );
+ Paint.translate( -C->x(), 0 );
+
+ if( HorizontalGrid && XPixels.start() < TotalWidth )
+ Paint.drawLine( XPixels.start(), LineHeight-1, XPixels.width(), LineHeight-1 ); // TODO: use a additional TotalHeight?
+
+ Paint.end();
+ // copy to screen
+ bitBlt( viewport(), XPixels.start() - contentsX(), cy - contentsY(),
+ &LineBuffer, XPixels.start(), 0, XPixels.width(), LineHeight );
+}
+
+
+bool KHexEdit::hasChanged( const KCoordRange &VisibleRange, KCoordRange *ChangedRange ) const
+{
+ if( !BufferRanges->overlapsChanges(VisibleRange,ChangedRange) )
+ return false;
+
+ ChangedRange->restrictTo( VisibleRange );
+ return true;
+}
+
+
+void KHexEdit::ensureCursorVisible()
+{
+// // Not visible or the user is draging the window, so don't position to caret yet
+// if ( !isVisible() || isHorizontalSliderPressed() || isVerticalSliderPressed() )
+// {
+// d->ensureCursorVisibleInShowEvent = true;
+// return;
+// }
+
+ KPixelX x = activeColumn().xOfPos( BufferCursor->pos() )+ activeColumn().byteWidth()/2;
+ KPixelY y = LineHeight * BufferCursor->line() + LineHeight/2;
+ int xMargin = activeColumn().byteWidth()/2 + 1;
+ int yMargin = LineHeight/2 + 1;
+ ensureVisible( x, y, xMargin, yMargin );
+}
+
+
+
+void KHexEdit::contentsMousePressEvent( QMouseEvent *e )
+{
+// clearUndoRedo();
+ pauseCursor( true );
+
+ // care about a left button press?
+ if( e->button() == LeftButton )
+ {
+ MousePressed = true;
+
+ // select whole line?
+ if( TrippleClickTimer->isActive()
+ && (e->globalPos()-DoubleClickPoint).manhattanLength() < QApplication::startDragDistance() )
+ {
+ BufferRanges->setSelectionStart( BufferLayout->indexAtLineStart(DoubleClickLine) );
+ BufferCursor->gotoLineEnd();
+ BufferRanges->setSelectionEnd( BufferCursor->realIndex() );
+ repaintChanged();
+
+ unpauseCursor();
+ return;
+ }
+
+ QPoint MousePoint = e->pos();
+ placeCursor( MousePoint );
+ ensureCursorVisible();
+
+ // start of a drag perhaps?
+ if( BufferRanges->selectionIncludes(BufferCursor->index()) )
+ {
+ DragStartPossible = true;
+ DragStartTimer->start( QApplication::startDragTime(), true );
+ DragStartPoint = MousePoint;
+
+ unpauseCursor();
+ return;
+ }
+
+ int RealIndex = BufferCursor->realIndex();
+ if( BufferRanges->selectionStarted() )
+ {
+ if( e->state() & ShiftButton )
+ BufferRanges->setSelectionEnd( RealIndex );
+ else
+ {
+ BufferRanges->removeSelection();
+ BufferRanges->setSelectionStart( RealIndex );
+ }
+ }
+ else // start of a new selection possible
+ {
+ BufferRanges->setSelectionStart( RealIndex );
+
+ if( !isReadOnly() && (e->state()&ShiftButton) ) // TODO: why only for readwrite?
+ BufferRanges->setSelectionEnd( RealIndex );
+ }
+
+ BufferRanges->removeFurtherSelections();
+ }
+ else if( e->button() == MidButton )
+ BufferRanges->removeSelection();
+
+ if( BufferRanges->isModified() )
+ {
+ repaintChanged();
+ viewport()->setCursor( isReadOnly() ? arrowCursor : ibeamCursor );
+ }
+
+ unpauseCursor();
+}
+
+
+void KHexEdit::contentsMouseMoveEvent( QMouseEvent *e )
+{
+ if( MousePressed )
+ {
+ if( DragStartPossible )
+ {
+ DragStartTimer->stop();
+ // moved enough for a drag?
+ if( (e->pos()-DragStartPoint).manhattanLength() > QApplication::startDragDistance() )
+ startDrag();
+ if( !isReadOnly() )
+ viewport()->setCursor( ibeamCursor );
+ return;
+ }
+ // selecting
+ QPoint MousePoint = e->pos();
+ handleMouseMove( MousePoint );
+ }
+ else if( !isReadOnly() )
+ {
+ // visual feedback for possible dragging
+ bool InSelection = BufferRanges->hasSelection() && BufferRanges->selectionIncludes( indexByPoint(e->pos()) );
+ viewport()->setCursor( InSelection?arrowCursor:ibeamCursor );
+ }
+}
+
+
+void KHexEdit::contentsMouseReleaseEvent( QMouseEvent *e )
+{
+ // this is not the release of a doubleclick so we need to process it?
+ if( !InDoubleClick )
+ {
+ int Line = lineAt( e->pos().y() );
+ int Pos = activeColumn().posOfX( e->pos().x() ); // TODO: can we be sure here about the active column?
+ int Index = BufferLayout->indexAtCCoord( KBufferCoord(Pos,Line) ); // TODO: can this be another index than the one of the cursor???
+ emit clicked( Index );
+ }
+
+ if( MousePressed )
+ {
+ MousePressed = false;
+
+ if( ScrollTimer->isActive() )
+ ScrollTimer->stop();
+
+ // was only click inside selection, nothing dragged?
+ if( DragStartPossible )
+ {
+ selectAll( false );
+ DragStartTimer->stop();
+ DragStartPossible = false;
+
+ unpauseCursor();
+ }
+ // was end of selection operation?
+ else if( BufferRanges->hasSelection() )
+ {
+ if( QApplication::clipboard()->supportsSelection() )
+ {
+ ClipboardMode = QClipboard::Selection;
+ disconnect( QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
+
+ copy();
+
+ connect( QApplication::clipboard(), SIGNAL(selectionChanged()), this, SLOT(clipboardChanged()) );
+ ClipboardMode = QClipboard::Clipboard;
+ }
+ }
+ }
+ // middle mouse button paste?
+ else if( e->button() == MidButton && !isReadOnly() )
+ {
+ pauseCursor();
+
+ placeCursor( e->pos() );
+
+ // replace no selection?
+ if( BufferRanges->hasSelection() && !BufferRanges->selectionIncludes(BufferCursor->index()) )
+ BufferRanges->removeSelection();
+
+ ClipboardMode = QClipboard::Selection;
+ paste();
+ ClipboardMode = QClipboard::Clipboard;
+
+ // ensure selection changes to be drawn TODO: create a insert/pasteAtCursor that leaves out drawing
+ repaintChanged();
+
+ ensureCursorVisible();
+ unpauseCursor();
+ }
+
+ InDoubleClick = false;
+
+ if( BufferRanges->selectionJustStarted() )
+ BufferRanges->removeSelection();
+
+ emit cursorPositionChanged( BufferCursor->index() );
+
+ if( !OverWrite ) emit cutAvailable( BufferRanges->hasSelection() );
+ emit copyAvailable( BufferRanges->hasSelection() );
+ KSection Selection = BufferRanges->selection();
+ emit selectionChanged( Selection.start(), Selection.end() );
+}
+
+
+// gets called after press and release instead of a plain press event (?)
+void KHexEdit::contentsMouseDoubleClickEvent( QMouseEvent *e )
+{
+ // we are only interested in LMB doubleclicks
+ if( e->button() != Qt::LeftButton )
+ {
+ e->ignore();
+ return;
+ }
+
+ DoubleClickLine = BufferCursor->line();
+
+ int Index = BufferCursor->validIndex();
+
+ if( ActiveColumn == &charColumn() )
+ {
+ selectWord( Index );
+
+ // as we already have a doubleclick maybe it is a tripple click
+ TrippleClickTimer->start( qApp->doubleClickInterval(), true );
+ DoubleClickPoint = e->globalPos();
+ }
+// else
+// ValueEditor->goInsideByte(); TODO: make this possible again
+
+ InDoubleClick = true; //
+ MousePressed = true;
+
+ emit doubleClicked( Index );
+}
+
+
+void KHexEdit::autoScrollTimerDone()
+{
+ if( MousePressed )
+ handleMouseMove( viewportToContents(viewport()->mapFromGlobal( QCursor::pos() )) );
+}
+
+
+void KHexEdit::handleMouseMove( const QPoint& Point ) // handles the move of the mouse with pressed buttons
+{
+ // no scrolltimer and outside of viewport?
+ if( !ScrollTimer->isActive() && Point.y() < contentsY() || Point.y() > contentsY() + visibleHeight() )
+ ScrollTimer->start( DefaultScrollTimerPeriod, false );
+ // scrolltimer but inside of viewport?
+ else if( ScrollTimer->isActive() && Point.y() >= contentsY() && Point.y() <= contentsY() + visibleHeight() )
+ ScrollTimer->stop();
+
+ pauseCursor();
+
+ placeCursor( Point );
+ ensureCursorVisible();
+
+ // do wordwise selection?
+ if( InDoubleClick && BufferRanges->hasFirstWordSelection() )
+ {
+ int NewIndex = BufferCursor->realIndex();
+ KSection FirstWordSelection = BufferRanges->firstWordSelection();
+ KWordBufferService WBS( DataBuffer, Codec );
+ // are we before the selection?
+ if( NewIndex < FirstWordSelection.start() )
+ {
+ BufferRanges->ensureWordSelectionForward( false );
+ NewIndex = WBS.indexOfLeftWordSelect( NewIndex );
+ }
+ // or behind?
+ else if( NewIndex > FirstWordSelection.end() )
+ {
+ BufferRanges->ensureWordSelectionForward( true );
+ NewIndex = WBS.indexOfRightWordSelect( NewIndex );
+ }
+ // or inside?
+ else
+ {
+ BufferRanges->ensureWordSelectionForward( true );
+ NewIndex = FirstWordSelection.end()+1;
+ }
+
+ BufferCursor->gotoIndex( NewIndex );
+ }
+
+ if( BufferRanges->selectionStarted() )
+ BufferRanges->setSelectionEnd( BufferCursor->realIndex() );
+
+ repaintChanged();
+
+ unpauseCursor();
+}
+
+
+void KHexEdit::startDrag()
+{
+ // reset states
+ MousePressed = false;
+ InDoubleClick = false;
+ DragStartPossible = false;
+
+ // create data
+ QDragObject *Drag = dragObject( viewport() );
+ if( !Drag )
+ return;
+
+ // will we only copy the data?
+ if( isReadOnly() || OverWrite )
+ Drag->dragCopy();
+ // or is this left to the user and he choose to move?
+ else if( Drag->drag() )
+ // Not inside this widget itself?
+ if( QDragObject::target() != this && QDragObject::target() != viewport() )
+ removeSelectedData();
+}
+
+
+void KHexEdit::contentsDragEnterEvent( QDragEnterEvent *e )
+{
+ // interesting for this widget?
+ if( isReadOnly() || !KBufferDrag::canDecode(e) )
+ {
+ e->ignore();
+ return;
+ }
+
+ e->acceptAction();
+ InDnD = true;
+}
+
+
+void KHexEdit::contentsDragMoveEvent( QDragMoveEvent *e )
+{
+ // is this content still interesting for us?
+ if( isReadOnly() || !KBufferDrag::canDecode(e) )
+ {
+ e->ignore();
+ return;
+ }
+
+ // let text cursor follow mouse
+ pauseCursor( true );
+ placeCursor( e->pos() );
+ unpauseCursor();
+
+ e->acceptAction();
+}
+
+
+void KHexEdit::contentsDragLeaveEvent( QDragLeaveEvent * )
+{
+ // bye... and thanks for all the cursor movement...
+ InDnD = false;
+}
+
+
+
+void KHexEdit::contentsDropEvent( QDropEvent *e )
+{
+ // after drag enter and move check one more time
+ if( isReadOnly() )
+ return;
+
+ // leave state
+ InDnD = false;
+ e->acceptAction();
+
+ if( !KBufferDrag::canDecode(e) ) //TODO: why do we acept the action still?
+ return;
+
+ // is this an internal dnd?
+ if( e->source() == this || e->source() == viewport() )
+ handleInternalDrag( e );
+ else
+ {
+ //BufferRanges->removeSelection();
+ pasteFromSource( e );
+ }
+}
+
+
+void KHexEdit::handleInternalDrag( QDropEvent *e )
+{
+ KSection ChangedRange;
+
+ // stop ui
+ pauseCursor();
+
+ // get drag origin
+ KSection Selection = BufferRanges->selection();
+ int InsertIndex = BufferCursor->realIndex();
+
+ // is this a move?
+ if( e->action() == QDropEvent::Move )
+ {
+ // ignore the copy hold in the event but only move
+ int NewIndex = DataBuffer->move( InsertIndex, Selection );
+ if( NewIndex != Selection.start() )
+ {
+ BufferCursor->gotoCIndex( NewIndex+Selection.width() );
+ ChangedRange.set( QMIN(InsertIndex,Selection.start()), QMAX(InsertIndex,Selection.end()) );
+ }
+ }
+ // is a copy
+ else
+ {
+ // get data
+ QByteArray Data;
+ if( KBufferDrag::decode(e,Data) && !Data.isEmpty() )
+ {
+ if( OverWrite )
+ {
+ if( !BufferCursor->isBehind() )
+ {
+ ChangedRange.setByWidth( InsertIndex, Data.size() );
+ ChangedRange.restrictEndTo( BufferLayout->length()-1 );
+ if( ChangedRange.isValid() )
+ {
+ int NoOfReplaced = DataBuffer->replace( ChangedRange, Data.data(), ChangedRange.width() );
+ BufferCursor->gotoNextByte( NoOfReplaced );
+ }
+ }
+ }
+ else
+ {
+ int NoOfInserted = DataBuffer->insert( InsertIndex, Data.data(), Data.size() );
+ updateLength();
+ if( NoOfInserted > 0 )
+ {
+ BufferCursor->gotoCIndex( InsertIndex + NoOfInserted );
+ ChangedRange.set( InsertIndex, DataBuffer->size()-1 );
+ }
+ }
+ }
+ }
+ BufferRanges->addChangedRange( ChangedRange );
+ BufferRanges->removeSelection();
+
+ repaintChanged();
+ ensureCursorVisible();
+
+ // open ui
+ unpauseCursor();
+
+ // emit appropriate signals.
+ emit selectionChanged( -1, -1 );
+ if( ChangedRange.isValid() ) emit bufferChanged( ChangedRange.start(), ChangedRange.end() );
+ emit cursorPositionChanged( BufferCursor->index() );
+}
+
+
+void KHexEdit::contentsWheelEvent( QWheelEvent *e )
+{
+ if( isReadOnly() )
+ {
+ if( e->state() & ControlButton )
+ {
+ if( e->delta() > 0 )
+ zoomOut();
+ else if( e->delta() < 0 )
+ zoomIn();
+ return;
+ }
+ }
+ QScrollView::contentsWheelEvent( e );
+}
+
+
+#if 0
+void KHexEdit::contentsContextMenuEvent( QContextMenuEvent *e )
+{
+// clearUndoRedo();
+ MousePressed = false;
+
+ e->accept();
+
+ QPopupMenu *PopupMenu = createPopupMenu( e->pos() );
+ if( !PopupMenu )
+ PopupMenu = createPopupMenu();
+ if( !PopupMenu )
+ return;
+ int r = PopupMenu->exec( e->globalPos() );
+ delete PopupMenu;
+
+ if ( r == d->id[ IdClear ] )
+ clear();
+ else if ( r == d->id[ IdSelectAll ] )
+ {
+ selectAll();
+ // if the clipboard support selections, put the newly selected text into the clipboard
+ if( QApplication::clipboard()->supportsSelection() )
+ {
+ ClipboardMode = QClipboard::Selection;
+ disconnect( QApplication::clipboard(), SIGNAL(selectionChanged()), this, 0);
+
+ copy();
+
+ connect( QApplication::clipboard(), SIGNAL(selectionChanged()), this, SLOT(clipboardChanged()) );
+ ClipboardMode = QClipboard::Clipboard;
+ }
+ }
+ else if( r == d->id[IdUndo] )
+ undo();
+ else if( r == d->id[IdRedo] )
+ redo();
+ else if( r == d->id[IdCut] )
+ cut();
+ else if( r == d->id[IdCopy] )
+ copy();
+ else if( r == d->id[IdPaste] )
+ paste();
+}
+#endif
+
+#include "khexedit.moc"
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
diff --git a/khexedit/lib/khexedit_export.h b/khexedit/lib/khexedit_export.h
new file mode 100644
index 0000000..f922516
--- /dev/null
+++ b/khexedit/lib/khexedit_export.h
@@ -0,0 +1,25 @@
+/***************************************************************************
+ khexedit_export.h - description
+ -------------------
+ begin : 22 Nov 2004
+ copyright : (C) 2004 Dirk Mueller
+ email : mueller@kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 KHEXEDIT_EXPORT_H
+#define KHEXEDIT_EXPORT_H
+
+#include <kdemacros.h>
+
+#define KHEXEDIT_EXPORT KDE_EXPORT
+
+#endif
diff --git a/khexedit/lib/koffsetcoltextexport.cpp b/khexedit/lib/koffsetcoltextexport.cpp
new file mode 100644
index 0000000..c5644df
--- /dev/null
+++ b/khexedit/lib/koffsetcoltextexport.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ koffsetcoltextexport.cpp - description
+ -------------------
+ begin : Sam Aug 30 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qstring.h>
+// lib specific
+#include "koffsetcolumn.h"
+#include "koffsetcoltextexport.h"
+
+using namespace KHE;
+
+
+KOffsetColTextExport::KOffsetColTextExport( const KOffsetColumn *OffsetColumn )
+ : CodingWidth( OffsetColumn->codingWidth() ),
+ FirstLineOffset( OffsetColumn->firstLineOffset() ),
+ Delta( OffsetColumn->delta() ),
+ printFunction( OffsetColumn->printFunction() )
+{
+}
+
+int KOffsetColTextExport::charsPerLine() const
+{
+ return CodingWidth;
+}
+
+
+void KOffsetColTextExport::printFirstLine( QString &T, int Line ) const
+{
+ PrintLine = Line;
+ print( T );
+}
+
+void KOffsetColTextExport::printNextLine( QString &T ) const
+{
+ print( T );
+}
+
+void KOffsetColTextExport::print( QString &T ) const
+{
+ // TODO: fix me (no more printFunction)
+ char *B = new char[CodingWidth+1];
+ printFunction( B, FirstLineOffset + Delta*PrintLine );
+ T.append( B );
+ delete [] B;
+
+ ++PrintLine;
+}
diff --git a/khexedit/lib/koffsetcoltextexport.h b/khexedit/lib/koffsetcoltextexport.h
new file mode 100644
index 0000000..e07e659
--- /dev/null
+++ b/khexedit/lib/koffsetcoltextexport.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ koffsetcoltextexport.h - description
+ -------------------
+ begin : Sam Aug 30 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_KOFFSETCOLTEXTEXPORT_H
+#define KHE_KOFFSETCOLTEXTEXPORT_H
+
+// lib specific
+#include "kcoltextexport.h"
+#include "koffsetformat.h"
+
+
+namespace KHE
+{
+
+class KOffsetColumn;
+
+class KOffsetColTextExport : public KColTextExport
+{
+ public:
+ KOffsetColTextExport( const KOffsetColumn *OC );
+
+ public: // KColTextExport API
+ void printFirstLine( QString &T, int Line ) const;
+ void printNextLine( QString &T ) const;
+ /** tells how much chars per line are needed */
+ int charsPerLine() const;
+
+ protected:
+ void print( QString &T ) const;
+
+ protected:
+ const int CodingWidth;
+ const int FirstLineOffset;
+ const int Delta;
+ const KOffsetFormat::print printFunction;
+
+ /** the line we are in */
+ mutable int PrintLine;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/koffsetcolumn.cpp b/khexedit/lib/koffsetcolumn.cpp
new file mode 100644
index 0000000..6bd6d09
--- /dev/null
+++ b/khexedit/lib/koffsetcolumn.cpp
@@ -0,0 +1,110 @@
+/***************************************************************************
+ koffsetcolumn.cpp - description
+ -------------------
+ begin : Mit Mai 14 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. *
+ * *
+ ***************************************************************************/
+
+// qt specific
+#include "qpainter.h"
+// lib specific
+#include "kcolumnsview.h"
+#include "koffsetcolumn.h"
+
+using namespace KHE;
+
+KOffsetColumn::KOffsetColumn( KColumnsView *V, int FLO, int D, KOffsetFormat::KFormat F )
+ : KColumn( V ),
+ FirstLineOffset( FLO ),
+ Delta( D ),
+ Margin( 0 ),
+ DigitWidth( 0 ),
+ DigitBaseLine( 0 ),
+ Format( KOffsetFormat::None )
+{
+ setFormat( F );
+}
+
+
+KOffsetColumn::~KOffsetColumn()
+{
+}
+
+
+void KOffsetColumn::paintLine( QPainter *P, int Line )
+{
+ const QColor &ButtonColor = View->colorGroup().button();
+ P->fillRect( 0,0,width(),LineHeight, QBrush(ButtonColor,Qt::SolidPattern) );
+
+ printFunction()( CodedOffset,FirstLineOffset+Delta*Line );
+ P->drawText( 0, DigitBaseLine, QString().append(CodedOffset) );
+}
+
+
+void KOffsetColumn::paintFirstLine( QPainter *P, KPixelXs, int FirstLine )
+{
+ PaintLine = FirstLine;
+ paintLine( P, PaintLine++ );
+}
+
+
+void KOffsetColumn::paintNextLine( QPainter *P )
+{
+ paintLine( P, PaintLine++ );
+}
+
+
+
+void KOffsetColumn::paintEmptyColumn( QPainter *P, KPixelXs Xs, KPixelYs Ys )
+{
+ Xs.restrictTo( XSpan );
+
+ const QColor &ButtonColor = View->colorGroup().button();
+ P->fillRect( Xs.start(), Ys.start(), Xs.width(), Ys.width(), QBrush(ButtonColor,Qt::SolidPattern) );
+}
+
+void KOffsetColumn::setFormat( KOffsetFormat::KFormat F )
+{
+ // no changes?
+ if( Format == F )
+ return;
+
+ Format = F;
+
+ CodingWidth = KOffsetFormat::codingWidth( Format );
+ PrintFunction = KOffsetFormat::printFunction( Format );
+
+ recalcX();
+}
+
+void KOffsetColumn::setMetrics( KPixelX DW, KPixelY DBL )
+{
+ DigitBaseLine = DBL;
+ setDigitWidth( DW );
+}
+
+void KOffsetColumn::setDigitWidth( KPixelX DW )
+{
+ // no changes?
+ if( DigitWidth == DW )
+ return;
+
+ DigitWidth = DW;
+
+ recalcX();
+}
+
+void KOffsetColumn::recalcX()
+{
+ // recalculate depend sizes
+ setWidth( CodingWidth * DigitWidth );
+}
diff --git a/khexedit/lib/koffsetcolumn.h b/khexedit/lib/koffsetcolumn.h
new file mode 100644
index 0000000..ae182f9
--- /dev/null
+++ b/khexedit/lib/koffsetcolumn.h
@@ -0,0 +1,109 @@
+/***************************************************************************
+ koffsetcolumn.h - description
+ -------------------
+ begin : Mit Mai 14 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_KOFFSETCOLUMN_H
+#define KHE_KOFFSETCOLUMN_H
+
+// lib specific
+#include "koffsetformat.h"
+#include "kcolumn.h"
+
+namespace KHE
+{
+
+/**
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KOffsetColumn : public KColumn
+{
+ public:
+ KOffsetColumn( KColumnsView *V, int FLO, int D, KOffsetFormat::KFormat F );
+ virtual ~KOffsetColumn();
+
+ public: // KColumn API
+ virtual void paintFirstLine( QPainter *P, KPixelXs Xs, int FirstLine );
+ virtual void paintNextLine( QPainter *P );
+ virtual void paintEmptyColumn( QPainter *P, KPixelXs Xs, KPixelYs Ys );
+
+
+ public:
+ void setFirstLineOffset( int FLO );
+ void setDelta( int D );
+
+ void setFormat( KOffsetFormat::KFormat F );
+ /** sets width of digits and recalculates depend sizes */
+ void setDigitWidth( KPixelX DW );
+ /** */
+ void setMetrics( KPixelX DW, KPixelY DBL );
+
+ public: // read access
+ int delta() const;
+ int firstLineOffset() const;
+ int codingWidth() const;
+ KOffsetFormat::print printFunction() const;
+
+
+ protected:
+ /** recalculates all x values */
+ void recalcX();
+ /** paints full line */
+ void paintLine( QPainter *P, int Line );
+
+
+ protected: // user settings
+ /** starting offset of the first line
+ * if different from StartOffset results in leading space
+ */
+ int FirstLineOffset;
+ /** offset delta per line */
+ int Delta;
+
+ protected: // pixel related
+ /** size of the line margin */
+ int Margin;
+ /** */
+ KPixelX DigitWidth;
+ /** */
+ KPixelY DigitBaseLine;
+
+ protected: // general layout
+ KOffsetFormat::KFormat Format;
+
+ int CodingWidth;
+ KOffsetFormat::print PrintFunction;
+
+ /** buffer to hold the formatted coding */
+ mutable char CodedOffset[KOffsetFormat::MaxFormatWidth+1];
+
+ protected: // firstnext trips related
+ /** */
+ int PaintLine;
+};
+
+
+inline int KOffsetColumn::firstLineOffset() const { return FirstLineOffset; }
+inline void KOffsetColumn::setFirstLineOffset( int FLO ) { FirstLineOffset = FLO; }
+inline int KOffsetColumn::delta() const { return Delta; }
+inline void KOffsetColumn::setDelta( int D ) { Delta = D; }
+
+inline int KOffsetColumn::codingWidth() const { return CodingWidth; }
+inline KOffsetFormat::print KOffsetColumn::printFunction() const { return PrintFunction; }
+
+}
+
+#endif
diff --git a/khexedit/lib/koffsetformat.cpp b/khexedit/lib/koffsetformat.cpp
new file mode 100644
index 0000000..e82fa9d
--- /dev/null
+++ b/khexedit/lib/koffsetformat.cpp
@@ -0,0 +1,48 @@
+/***************************************************************************
+ koffsetformat.cpp - description
+ -------------------
+ begin : Mit Mai 21 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. *
+ * *
+ ***************************************************************************/
+
+
+// c specific
+#include <stdio.h>
+// lib specific
+#include "koffsetformat.h"
+
+using namespace KHE;
+
+
+const unsigned int KOffsetFormat::CodingWidth[2] = { 9, 10 };
+
+const KOffsetFormat::print KOffsetFormat::PrintFunction[2] =
+{ KOffsetFormat::printHexadecimalOffset, KOffsetFormat::printDecimalOffset };
+
+
+
+void KOffsetFormat::printHexadecimalOffset( char *Buffer, unsigned int Offset )
+{
+ sprintf( Buffer, "%04X:%04X", Offset>>16, Offset&0x0000FFFF );
+}
+
+
+void KOffsetFormat::printHexadecimalSmallOffset( char *Buffer, unsigned int Offset )
+{
+ sprintf( Buffer, "%04x:%04x", Offset>>16, Offset&0x0000FFFF );
+}
+
+
+void KOffsetFormat::printDecimalOffset( char *Buffer, unsigned int Offset )
+{
+ sprintf( Buffer, "%010u", Offset );
+}
diff --git a/khexedit/lib/koffsetformat.h b/khexedit/lib/koffsetformat.h
new file mode 100644
index 0000000..8bd90e2
--- /dev/null
+++ b/khexedit/lib/koffsetformat.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ koffsetformat.h - description
+ -------------------
+ begin : Mit Mai 21 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_KOFFSETFORMAT_H
+#define KHE_KOFFSETFORMAT_H
+
+namespace KHE
+{
+
+/**
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KOffsetFormat
+{
+ public:
+ /** */
+ typedef void (*print)( char *Buffer, unsigned int Offset );
+ /** */
+ enum KFormat { Hexadecimal=0, Decimal, None };
+ /** */
+ static const int MaxFormatWidth = 9;
+
+ private:
+ KOffsetFormat();
+ ~KOffsetFormat();
+
+ public:
+ /** */
+ static unsigned int codingWidth( int i );
+ /** */
+ static print printFunction( int i );
+
+ public:
+ static void printHexadecimalOffset( char *Buffer, unsigned int Offset );
+ static void printHexadecimalSmallOffset( char *Buffer, unsigned int Offset );
+ static void printDecimalOffset( char *Buffer, unsigned int Offset );
+
+ protected:
+ /** */
+ static const unsigned int CodingWidth[2]; //TODO: would sizeof(Coding} work?
+ /** */
+ static const print PrintFunction[2];
+};
+
+
+inline unsigned int KOffsetFormat::codingWidth( int i )
+{ return CodingWidth[i]; }
+
+inline KOffsetFormat::print KOffsetFormat::printFunction( int i )
+{ return PrintFunction[i]; }
+
+
+}
+
+#endif
diff --git a/khexedit/lib/kplainbuffer.cpp b/khexedit/lib/kplainbuffer.cpp
new file mode 100644
index 0000000..63c1db7
--- /dev/null
+++ b/khexedit/lib/kplainbuffer.cpp
@@ -0,0 +1,344 @@
+/***************************************************************************
+ kplainbuffer.cpp - description
+ -------------------
+ begin : Mit Jun 03 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. *
+ * *
+ ***************************************************************************/
+
+//#include <kdebug.h>
+// c specific
+#include <string.h>
+#include <stdlib.h>
+// lib specific
+#include "kplainbuffer.h"
+
+
+static const unsigned int MinChunkSize = 512;
+static const unsigned int MaxChunkSize = 1024*10; // TODO: get max. memory page size
+
+// TODO: think about realloc & Co.
+using namespace KHE;
+
+KPlainBuffer::KPlainBuffer( char *D, unsigned int S, int RS, bool KM )
+ : Data( D ),
+ Size( S ),
+ RawSize( RS<(int)S?S:RS ),
+ MaxSize( -1 ),
+ KeepsMemory( KM ),
+ ReadOnly( true ),
+ Modified( false )
+{
+}
+
+KPlainBuffer::KPlainBuffer( const char *D, unsigned int S )
+ : Data( (char *)D ),
+ Size( S ),
+ RawSize( S ),
+ MaxSize( -1 ),
+ KeepsMemory( true ),
+ ReadOnly( true ),
+ Modified( false )
+{
+}
+
+KPlainBuffer::KPlainBuffer( int S, int MS )
+ : Data( S?new char[S]:0 ),
+ Size( S ),
+ RawSize( S ),
+ MaxSize( MS ),
+ KeepsMemory( false ),
+ ReadOnly( true ),
+ Modified( false )
+{
+}
+
+KPlainBuffer::~KPlainBuffer()
+{
+}
+
+
+
+int KPlainBuffer::insert( int Pos, const char* D, int Length )
+{
+ // check all parameters
+ if( Length == 0 )
+ return 0;
+ //kdDebug() << QString("before: Size: %1, RawSize: %2").arg(Size).arg(RawSize) << endl;
+ // correct for appending
+ if( Pos > (int)Size )
+ Pos = Size;
+
+ Length = addSize( Length, Pos, true );
+
+ // copy new data to its place
+ memcpy( &Data[Pos], D, Length );
+
+ //kdDebug() << QString("after: Size: %1, RawSize: %2").arg(Size).arg(RawSize) << endl;
+
+ Modified = true;
+ return Length;
+}
+
+
+int KPlainBuffer::remove( KSection Remove )
+{
+ if( Remove.startsBehind(Size-1) || Remove.width() == 0 )
+ return 0;
+
+ Remove.restrictEndTo( Size-1 );
+
+ unsigned int BehindRemovePos = Remove.end()+1;
+ // move right data behind the input range
+ memmove( &Data[Remove.start()], &Data[BehindRemovePos], Size-BehindRemovePos );
+
+ // set new values
+ Size -= Remove.width();
+
+ Modified = true;
+ return Remove.width();
+}
+
+
+unsigned int KPlainBuffer::replace( KSection Remove, const char* D, unsigned int InputLength )
+{
+ // check all parameters
+ if( Remove.start() >= (int)Size || (Remove.width()==0 && InputLength==0) )
+ return 0;
+
+ Remove.restrictEndTo( Size-1 );
+
+ int SizeDiff = InputLength - Remove.width();
+ unsigned int NewSize = Size + SizeDiff;
+ // check if buffer does not get to big TODO: make algo simplier and less if else
+ if( MaxSize != -1 && (int)NewSize > MaxSize)
+ {
+ if( (int)Size == MaxSize )
+ return 0;
+ InputLength -= NewSize - MaxSize;
+ NewSize = MaxSize;
+ }
+ else if( KeepsMemory && NewSize > RawSize )
+ {
+ if( Size == RawSize )
+ return 0;
+ InputLength -= NewSize - RawSize;
+ NewSize = RawSize;
+ }
+
+ int BehindInsertPos = Remove.start() + InputLength;
+ int BehindRemovePos = Remove.end()+1;
+
+ // raw array not big enough?
+ if( RawSize < NewSize )
+ {
+ // create new buffer
+ char *NewData = new char[NewSize];
+ if( NewData == 0 )
+ return 0;
+
+ // move old data to its (new) places
+ memcpy( NewData, Data, Remove.start() );
+ memcpy( &NewData[BehindInsertPos], &Data[BehindRemovePos], Size-BehindRemovePos );
+
+ // remove old
+ delete [] Data;
+ // set new values
+ Data = NewData;
+ RawSize = NewSize;
+ }
+ else
+ // move old data to its (new) places
+ memmove( &Data[BehindInsertPos], &Data[BehindRemovePos], Size-BehindRemovePos );
+
+ // copy new data to its place
+ memcpy( &Data[Remove.start()], D, InputLength );
+
+ // set new values
+ Size = NewSize;
+
+ Modified = true;
+ return InputLength;
+}
+
+
+int KPlainBuffer::move( int DestPos, KSection SourceSection )
+{
+ // check all parameters
+ if( SourceSection.start() >= (int)Size || SourceSection.width() == 0
+ || DestPos > (int)Size || SourceSection.start() == DestPos )
+ return SourceSection.start();
+
+ SourceSection.restrictEndTo( Size-1 );
+ bool ToRight = DestPos > SourceSection.start();
+ int MovedLength = SourceSection.width();
+ int DisplacedLength = ToRight ? DestPos - SourceSection.end()-1 : SourceSection.start() - DestPos;
+
+ // find out section that is smaller
+ int SmallPartLength, LargePartLength, SmallPartStart, LargePartStart, SmallPartDest, LargePartDest;
+ // moving part is smaller?
+ if( MovedLength < DisplacedLength )
+ {
+ SmallPartStart = SourceSection.start();
+ SmallPartLength = MovedLength;
+ LargePartLength = DisplacedLength;
+ // moving part moves right?
+ if( ToRight )
+ {
+ SmallPartDest = DestPos - MovedLength;
+ LargePartStart = SourceSection.end()+1;
+ LargePartDest = SourceSection.start();
+ }
+ else
+ {
+ SmallPartDest = DestPos;
+ LargePartStart = DestPos;
+ LargePartDest = DestPos + MovedLength;
+ }
+ }
+ else
+ {
+ LargePartStart = SourceSection.start();
+ LargePartLength = MovedLength;
+ SmallPartLength = DisplacedLength;
+ // moving part moves right?
+ if( ToRight )
+ {
+ LargePartDest = DestPos - MovedLength;
+ SmallPartStart = SourceSection.end()+1;
+ SmallPartDest = SourceSection.start();
+ }
+ else
+ {
+ LargePartDest = DestPos;
+ SmallPartStart = DestPos;
+ SmallPartDest = DestPos + MovedLength;
+ }
+ }
+
+ // copy smaller part to tempbuffer
+ char *Temp = new char[SmallPartLength];
+ memcpy( Temp, &Data[SmallPartStart], SmallPartLength );
+
+ // move the larger part
+ memmove( &Data[LargePartDest], &Data[LargePartStart], LargePartLength );
+
+ // copy smaller part to its new dest
+ memcpy( &Data[SmallPartDest], Temp, SmallPartLength );
+ delete [] Temp;
+
+ Modified = true;
+ return MovedLength < DisplacedLength ? SmallPartDest : LargePartDest;
+}
+
+
+int KPlainBuffer::fill( const char FChar, int FillLength, unsigned int Pos )
+{
+ // nothing to fill
+ if( Pos >= Size )
+ return 0;
+
+ int LengthToEnd = Size - Pos;
+
+ if( FillLength < 0 )
+ FillLength = LengthToEnd;
+ else if( FillLength > LengthToEnd )
+ FillLength = addSize( FillLength, Pos, false );
+
+ memset( &Data[Pos], FChar, FillLength );
+ Modified = true;
+ return FillLength;
+}
+
+
+int KPlainBuffer::find( const char* SearchString, int Length, KSection Section ) const
+{
+ Section.restrictEndTo( Size-1 );
+
+ for( int i = Section.start(); i <= Section.end(); ++i )
+ {
+ int Result;
+// if( IgnoreCase )
+// result = strncasecmp( &data()[i], sc.key.data(), sc.key.size() );
+// else
+ Result = memcmp( &Data[i], SearchString, Length );
+ // found?
+ if( Result == 0 )
+ return i;
+ }
+ return -1;
+}
+
+int KPlainBuffer::rfind( const char*, int /*Length*/, int /*Pos*/ ) const { return 0; }
+
+
+int KPlainBuffer::addSize( int AddSize, int SplitPos, bool SaveUpperPart )
+{
+ unsigned int NewSize = Size + AddSize;
+ // check if buffer does not get too big
+ if( MaxSize != -1 && (int)NewSize > MaxSize )
+ {
+ if( (int)Size == MaxSize )
+ return 0;
+ NewSize = MaxSize;
+ AddSize = NewSize - Size;
+ }
+ else if( KeepsMemory && NewSize > RawSize )
+ {
+ if( Size == RawSize )
+ return 0;
+ NewSize = RawSize;
+ AddSize = NewSize - Size;
+ }
+
+ int BehindSplitPos = SplitPos + AddSize;
+ // raw array not big enough?
+ if( RawSize < NewSize )
+ {
+ // get new raw size
+ unsigned int ChunkSize = MinChunkSize;
+ // find chunk size where newsize fits into
+ while( ChunkSize < NewSize )
+ ChunkSize <<= 1;
+ // limit to max size
+ if( ChunkSize > MaxChunkSize )
+ ChunkSize = MaxChunkSize;
+ // find add size
+ unsigned int NewRawSize = ChunkSize;
+ while( NewRawSize<NewSize )
+ NewRawSize += ChunkSize;
+ // create new buffer
+ char *NewData = new char[NewRawSize];
+
+ // move old data to its (new) places
+ memcpy( NewData, Data, SplitPos );
+ if( SaveUpperPart )
+ memcpy( &NewData[BehindSplitPos], &Data[SplitPos], Size-SplitPos );
+
+ // remove old
+ delete [] Data;
+ // set new values
+ Data = NewData;
+ RawSize = NewRawSize;
+ }
+ // old buffer kept
+ else
+ {
+ if( SaveUpperPart )
+ // move old data to its (new) places
+ memmove( &Data[BehindSplitPos], &Data[SplitPos], Size-SplitPos );
+ }
+
+ // set new values
+ Size = NewSize;
+
+ return AddSize;
+}
diff --git a/khexedit/lib/kplainbuffer.h b/khexedit/lib/kplainbuffer.h
new file mode 100644
index 0000000..27bbbad
--- /dev/null
+++ b/khexedit/lib/kplainbuffer.h
@@ -0,0 +1,131 @@
+/***************************************************************************
+ kplainbuffer.h - description
+ -------------------
+ begin : Mit Jun 03 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_KPLAINBUFFER_H
+#define KHE_KPLAINBUFFER_H
+
+#include "kdatabuffer.h"
+
+namespace KHE
+{
+/*
+class KPlainBufferIterator : public KDataBufferIterator
+{
+}
+*/
+/** base class for all Data buffers that are used to display
+ * TODO: think about a way to inform KHexEdit that there has been
+ * a change in the buffer outside. what kind of changes are possible?
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KPlainBuffer : public KDataBuffer
+{
+ friend class KPlainBufferIterator;
+
+ public:
+ KPlainBuffer( char *D, unsigned int S, int RS = -1, bool KM = true );
+ KPlainBuffer( const char *D, unsigned int S );
+ KPlainBuffer( int S=0, int MS = -1 );
+ virtual ~KPlainBuffer();
+
+ public: // KDataBuffer API
+ virtual bool prepareRange( KSection Range ) const;
+ //virtual KDataBufferIterator *iterator() const;
+ virtual const char *dataSet( KSection S ) const;
+ virtual char datum( unsigned int Offset ) const;
+ virtual int size() const;
+ virtual bool isReadOnly() const;
+ virtual bool isModified() const;
+
+ virtual int insert( int Pos, const char*, int Length );
+ virtual int remove( KSection Remove );
+ virtual unsigned int replace( KSection Remove, const char*, unsigned int InputLength );
+ virtual int move( int DestPos, KSection SourceSection );
+ virtual int fill( const char FillChar, int Length = -1, unsigned int Pos = 0 );
+ virtual void setDatum( unsigned int Offset, const char Char );
+
+ virtual void setModified( bool M = true );
+
+ //virtual int find( const char*, int Length, int Pos = 0 ) const;
+ virtual int find( const char*KeyData, int Length, KSection Section ) const;
+ virtual int rfind( const char*, int Length, int Pos = -1 ) const;
+
+/* virtual int find( const QString &expr, bool cs, bool wo, bool forward = true, int *index = 0 ); */
+
+ public:
+ void setReadOnly( bool RO = true );
+ void setMaxSize( int MS );
+ /** sets whether the memory given by setData or in the constructor should be kept on resize
+ */
+ void setKeepsMemory( bool KM = true );
+
+ public:
+ char *data() const;
+ int maxSize() const;
+ /** returns whether the memory of the byte array is kept */
+ bool keepsMemory() const;
+
+ protected:
+ /** resizes the buffer, if possible, saving the data and splitting the data, if demanded
+ * @param AddSize additional size the buffer should grow
+ * @param SplitPos if -1 does not split
+ * @param SaveUpperPart true if upper part should be copied into new buffer
+ * @return additional size the buffer has grown
+ */
+ int addSize( int AddSize, int SplitPos = -1, bool SaveUpperPart = true );
+
+ protected:
+ /** */
+ char *Data;
+ /** size of the data */
+ unsigned int Size;
+ /** Size of data array */
+ unsigned int RawSize;
+ /** maximal size of array, unlimited if -1 */
+ int MaxSize;
+ /** flag whether the initially given memory should be kept */
+ bool KeepsMemory:1;
+ /** */
+ bool ReadOnly:1;
+ /** */
+ bool Modified:1;
+};
+
+
+inline bool KPlainBuffer::prepareRange( KSection ) const { return true; }
+inline const char *KPlainBuffer::dataSet( KSection S ) const { return &Data[S.start()]; }
+inline char KPlainBuffer::datum( unsigned int Offset ) const { return Data[Offset]; }
+inline int KPlainBuffer::size() const { return Size; }
+
+inline bool KPlainBuffer::isReadOnly() const { return ReadOnly; }
+inline bool KPlainBuffer::isModified() const { return Modified; }
+
+inline void KPlainBuffer::setDatum( unsigned int Offset, const char Char )
+{ Data[Offset] = Char; Modified = true; }
+
+inline void KPlainBuffer::setReadOnly( bool RO ) { ReadOnly = RO; }
+inline void KPlainBuffer::setModified( bool M ) { Modified = M; }
+inline void KPlainBuffer::setMaxSize( int MS ) { MaxSize = MS; }
+inline void KPlainBuffer::setKeepsMemory( bool KM ) { KeepsMemory = KM; }
+
+inline char *KPlainBuffer::data() const { return Data; }
+inline int KPlainBuffer::maxSize() const { return MaxSize; }
+inline bool KPlainBuffer::keepsMemory() const { return KeepsMemory; }
+}
+
+#endif
diff --git a/khexedit/lib/krange.h b/khexedit/lib/krange.h
new file mode 100644
index 0000000..a0df3f1
--- /dev/null
+++ b/khexedit/lib/krange.h
@@ -0,0 +1,123 @@
+/***************************************************************************
+ krange.h - description
+ -------------------
+ begin : Sun 03.08.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_KRANGE_H
+#define KHE_KRANGE_H
+
+
+namespace KHE
+{
+
+/** This template describes a range.
+ * A range is something with a start and an end.
+ * The start is a value relative before the end.
+ * The distance cannot be estimated.
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+template<class T>
+class KRange
+{
+ public:
+ KRange( T S, T E ) : Start( S ), End( E ) {}
+ KRange() : Start( null() ), End( null() ) {}
+ ~KRange() {}
+
+ public:
+ KRange &operator=( const KRange &R ) { Start = R.Start; End = R.End; return *this; }
+
+ public:
+ bool operator==( const KRange &R ) const { return Start == R.Start && End == R.End; }
+
+ public: // modification access
+ /** sets the first and the last index of the range */
+ void set( T S, T E ) { Start = S; End = E; }
+ /** sets the first index of the range */
+ void setStart( T S ) { Start = S; }
+ /** sets the last index of the range */
+ void setEnd( T E ) { End = E; }
+ /** sets the range to null */
+ void unset() { Start = End = null(); }
+ /** restricts the range to Limit. If one of both ranges is invalid the behaviour is undefined */
+ void restrictTo( const KRange &Limit )
+ { if( Start < Limit.start() ) Start = Limit.start(); if( End > Limit.end() ) End = Limit.end(); }
+ /** restricts the start to Limit. If the range is invalid the behaviour is undefined */
+ void restrictStartTo( T Limit ) { if( Start < Limit ) Start = Limit; }
+ /** restricts the end to Limit. If the range is invalid the behaviour is undefined */
+ void restrictEndTo( T Limit ) { if( End > Limit ) End = Limit; }
+ /** extends the range to Limit. If one of both is invalid the behaviour is undefined */
+ void extendTo( const KRange &Limit )
+ { if( Start > Limit.start() ) Start = Limit.start(); if( End < Limit.end() ) End = Limit.end(); }
+ /** extends the start to Limit. If the range is invalid the behaviour is undefined */
+ void extendStartTo( T Limit ) { if( Start > Limit ) Start = Limit; }
+ /** extends the end to Limit. If the range is invalid the behaviour is undefined */
+ void extendEndTo( T Limit ) { if( End < Limit ) End = Limit; }
+ /** moves the range by D. If the range is invalid the behaviour is undefined */
+ void moveBy( T D ) { Start += D; End += D; }
+
+ public: // value access
+ /** @return start */
+ T start() const { return Start; }
+ /** @return end */
+ T end() const { return End; }
+
+
+ public: // logic access
+ /** returns true if Value is covered */
+ bool includes( T Value ) const { return Value <= End && Value >= Start; }
+ /** returns true if range is before index. if range is invalid the behaviour is undefined */
+ bool endsBefore( T Value ) const { return End < Value; }
+ /** returns true if range is behind index. if range is invalid the behaviour is undefined */
+ bool startsBehind( T Value ) const { return Start > Value; }
+ /** returns true is the range starts before index. If the range is invalid the behaviour is undefined */
+ bool startsBefore( T Value ) const { return Start < Value; }
+ /** returns true is the range end later then index. If the range is invalid the behaviour is undefined */
+ bool endsBehind( T Value ) const { return End > Value; }
+
+ /** returns true is the range covers R. If one of both is invalid the behaviour is undefined */
+ bool includes( const KRange &R ) const { return End >= R.End && Start <= R.Start; }
+ /** returns true is the range ends before R starts. If one of both is invalid the behaviour is undefined */
+ bool endsBefore( const KRange &R ) const { return End < R.Start; }
+ /** returns true is the range starts later than R ends. If one of both is invalid the behaviour is undefined */
+ bool startsBehind( const KRange &R ) const { return Start > R.End; }
+ /** returns true is the range starts prior than R. If one of both is invalid the behaviour is undefined */
+ bool startsBefore( const KRange &R ) const { return Start < R.Start; }
+ /** returns true is the range ends later than R. If one of both is invalid the behaviour is undefined */
+ bool endsBehind( const KRange &R ) const { return End > R.End; }
+ /** returns true is the range shares at least one index with R. If one of both is invalid the behaviour is undefined */
+ bool overlaps( const KRange &R ) const { return Start <= R.End && End >= R.Start; }
+
+ /** returns true if the range covers at least one index */
+ bool isValid() const { return Start != null() && Start <= End; }
+ /** returns true if the range has not been set */
+ bool isEmpty() const { return Start == null() && End == null(); }
+
+
+ protected:
+ /** delivers a null element. Should be specialiced for complexer types. */
+ const T null () const { return T(-1);}
+
+ protected:
+ /** first value of the range */
+ T Start;
+ /** last value of the range */
+ T End;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kreadonlybuffer.h b/khexedit/lib/kreadonlybuffer.h
new file mode 100644
index 0000000..63264b2
--- /dev/null
+++ b/khexedit/lib/kreadonlybuffer.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ kreadonlybuffer.h - description
+ -------------------
+ begin : Mit Mai 14 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_KREADONLYBUFFER_H
+#define KHE_KREADONLYBUFFER_H
+
+#include "kdatabuffer.h"
+
+namespace KHE
+{
+
+/**
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KReadOnlyBuffer : public KDataBuffer
+{
+ public:
+ KReadOnlyBuffer() {}
+ ~KReadOnlyBuffer() {}
+
+ public: // KDataBuffer API
+ /** is the buffer changeable ?*/
+ virtual bool isReadOnly() const { return true; }
+ /** has the buffer been modified? */
+ virtual bool isModified() const { return false; }
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/ksection.h b/khexedit/lib/ksection.h
new file mode 100644
index 0000000..7693219
--- /dev/null
+++ b/khexedit/lib/ksection.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ ksection.h - description
+ -------------------
+ begin : Sun 22.06.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_KSECTION_H
+#define KHE_KSECTION_H
+
+
+#include "krange.h"
+
+namespace KHE
+{
+
+/** describes a section of indizes
+ *@author Friedrich W. H. Kossebau
+ */
+class KSection : public KRange<int>
+{
+ public:
+ /** constructs a section
+ * @param SI starting index
+ * @param EI end index
+ */
+ KSection( int SI, int EI );
+ /** constructs a section
+ * @param SI starting index
+ * @param W width of the section
+ */
+ KSection( int SI, int W, bool );
+ KSection();
+ ~KSection();
+
+ public:
+ KSection &operator=( const KSection &S );
+
+ public:
+ bool operator==( const KSection &S ) const;
+
+ public:
+ void setByWidth( int S, int Width );
+ /** sets the first index of the section's range one behind the other's end
+ * If one of both is invalid the behaviour is undefined
+ */
+ void setStartBehind( KSection S );
+ /** sets the first index of the section's range one behind the other's end
+ * If one of both is invalid or the other' start is 0 the behaviour is undefined
+ */
+ void setEndBefore( KSection S );
+ /** sets the first index of the section's range to be width-1 before the end
+ * If the section is invalid the behaviour is undefined
+ */
+ void setStartByWidth( int Width );
+ /** sets the last index of the section's range to be width-1 behind the start
+ * If the section is invalid the behaviour is undefined
+ */
+ void setEndByWidth( int Width );
+ /** moves the range defined by a new start.
+ * If the range is invalid the behaviour is undefined
+ */
+ void moveToStart( int S );
+ /** moves the range defined by a new start.
+ * If the range is invalid the behaviour is undefined
+ */
+ void moveToEnd( int E );
+
+ public:
+ /**
+ * @return the numbered of included indizes or 0, if the section is invalid
+ */
+ int width() const;
+};
+
+
+inline KSection::KSection( int SI, int EI ) : KRange<int>(SI,EI) {}
+inline KSection::KSection( int SI, int W, bool ) : KRange<int>(SI,SI+W-1) {}
+inline KSection::KSection() {}
+inline KSection::~KSection() {}
+
+inline bool KSection::operator==( const KSection &S ) const { return KRange<int>::operator==(S); }
+
+inline KSection &KSection::operator=( const KSection &S ) { KRange<int>::operator=(S); return *this; }
+
+inline int KSection::width() const { return isValid() ? end()-start()+1 : 0; }
+
+inline void KSection::setByWidth( int S, int Width ) { setStart( S ); setEnd( S+Width-1 ); }
+inline void KSection::setStartByWidth( int Width ) { setStart( end()-Width+1 ); }
+inline void KSection::setEndByWidth( int Width ) { setEnd( start()+Width-1 ); }
+inline void KSection::setStartBehind( KSection S ) { setStart( S.end()+1 ); }
+inline void KSection::setEndBefore( KSection S ) { setEnd( S.start()-1 ); }
+
+inline void KSection::moveToStart( int S ) { setEnd( S+width()-1 ); setStart( S ); }
+inline void KSection::moveToEnd( int E ) { setStart( E-width()+1 ); setEnd( E ); }
+}
+
+#endif
diff --git a/khexedit/lib/ksectionlist.cpp b/khexedit/lib/ksectionlist.cpp
new file mode 100644
index 0000000..eec54e4
--- /dev/null
+++ b/khexedit/lib/ksectionlist.cpp
@@ -0,0 +1,79 @@
+/***************************************************************************
+ ksectionlist.cpp - description
+ -------------------
+ begin : Mon Jun 30 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "ksectionlist.h"
+
+using namespace KHE;
+
+KSectionList::KSectionList()
+{
+}
+
+
+KSectionList::~KSectionList()
+{
+}
+
+
+void KSectionList::addSection( KSection NewSection )
+{
+ if( !NewSection.isValid() )
+ return;
+
+ // we try to insert it by ascending indizes
+ // if sections are overlapping we combine them
+ iterator S = begin();
+ for( ; S!=end(); ++S )
+ {
+ // is new section before the next section?
+ if( NewSection.endsBefore(*S) )
+ {
+ // put the new before it
+ insert( S, NewSection );
+ return;
+ }
+
+ // does the next section overlap?
+ if( (*S).overlaps(NewSection) )
+ {
+ // Start of the combined sections is the smaller one
+ NewSection.extendStartTo( (*S).start() );
+ // next we search all the overlapping sections and keep the highest end index
+ int End = (*S).end();
+ iterator LS = S;
+ for( ++LS; LS!=end(); ++LS )
+ {
+ if( !(*LS).overlaps(NewSection) )
+ break;
+ End = (*LS).end();
+ }
+ // the higher end is the end of the combined section
+ NewSection.extendEndTo( End );
+ // remove all overlapping sections
+ S = erase( S, LS );
+ // and instead insert the combined one
+ insert( S, NewSection );
+ return;
+ }
+ }
+
+ // all others are before the new?
+ if( S == end() )
+ // add it at the end
+ append( NewSection );
+}
diff --git a/khexedit/lib/ksectionlist.h b/khexedit/lib/ksectionlist.h
new file mode 100644
index 0000000..7328e42
--- /dev/null
+++ b/khexedit/lib/ksectionlist.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ ksectionlist.h - description
+ -------------------
+ begin : Mon Jun 30 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_KSECTIONLIST_H
+#define KHE_KSECTIONLIST_H
+
+// qt specific
+#include <qvaluelist.h>
+// lib specific
+#include "ksection.h"
+
+namespace KHE {
+
+typedef QValueList<KSection> KSectionBasicList;
+/**
+@author Friedrich W. H. Kossebau
+*/
+class KSectionList : public KSectionBasicList
+{
+ public:
+ KSectionList();
+ ~KSectionList();
+
+ public:
+ void addSection( KSection S );
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kselection.h b/khexedit/lib/kselection.h
new file mode 100644
index 0000000..19b8a99
--- /dev/null
+++ b/khexedit/lib/kselection.h
@@ -0,0 +1,178 @@
+/***************************************************************************
+ kbuffersection.h - description
+ -------------------
+ begin : 22.06.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_KSELECTION_H
+#define KHE_KSELECTION_H
+
+#include "ksection.h"
+
+namespace KHE
+{
+
+/** This class describes a selected section of the buffer.
+ * As it is used as selection controlled by
+ * mouse and keyboard commands it offers two ways to set its range:
+ * - by giving the startposition (of the cursor) of an interactive selection
+ * and the subsequent end positions (until selection is finished)
+ * - direct setting (as provided by KSection)
+ *
+ * the interactive selection takes care that
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+class KSelection : public KSection
+{
+ public:
+ /** creates a selection with a given start.
+ * @param Index index in front of which the selection begins
+ */
+ KSelection( int Index );
+ /** creates an invalid selection */
+ KSelection();
+ ~KSelection();
+
+ public:
+ KSelection &operator=( const KSelection &S );
+ KSelection &operator=( const KSection &S );
+
+ public: // modification access
+ /** starts the selection.
+ * For this the anchor, start and end are set to the given index,
+ * so the initial selection is empty.
+ * @param Index index in front of which the selection begins
+ */
+ void setStart( int Index );
+ /** sets the end of the current selection
+ * If the end is before the start the selection will reach from the given index
+ * @param Index index in front of which the selection ends
+ */
+ void setEnd( int Index );
+ /** sets the selection to be invalid
+ */
+ void cancel();
+ /** sets the anchor to the start
+ * If the selection has not started the behaviour is undefined.
+ */
+ void setForward();
+ /** sets the anchor to the end
+ * If the selection has not started the behaviour is undefined.
+ */
+ void setBackward();
+ /** swaps anchor from start to end or vice versa
+ * If the selection has not started the behaviour is undefined.
+ */
+ void reverse();
+
+ public: // value access
+ /**
+ * @return anchor value
+ */
+ int anchor() const;
+
+ public: // logic access
+ /**
+ * @return @c true if the anchor has been set, otherwise @c false.
+ */
+ bool started() const;
+ /**
+ * @return @c true if the anchor has been set and the selection is empty, otherwise @c false.
+ */
+ bool justStarted() const;
+ /**
+ * @return @c true if the anchor is at the begin of the selection
+ */
+ bool isForward() const;
+
+ protected:
+ /** cursor index where the selection starts */
+ int Anchor;
+};
+
+
+inline KSelection::KSelection() : Anchor( -1 ) {}
+inline KSelection::KSelection( int Index ) : Anchor( Index ) {}
+inline KSelection::~KSelection() {}
+
+inline KSelection &KSelection::operator=( const KSelection &S )
+{
+ KSection::operator=(S);
+ Anchor = S.Anchor;
+ return *this;
+}
+
+inline KSelection &KSelection::operator=( const KSection &S )
+{
+ KSection::operator=(S);
+ Anchor = start();
+ return *this;
+}
+
+
+inline void KSelection::setStart( int Index )
+{
+ Anchor = Index;
+ unset();
+}
+
+
+inline void KSelection::setEnd( int Index )
+{
+ // nothing selected?
+ if( Index == Anchor )
+ unset();
+ // selecting forwards?
+ else if( Index > Anchor )
+ {
+ KSection::setStart( Anchor );
+ KSection::setEnd( Index-1 );
+ }
+ // selecting backwards
+ else
+ {
+ KSection::setStart( Index );
+ KSection::setEnd( Anchor-1 );
+ }
+}
+
+inline void KSelection::reverse()
+{
+ Anchor = isForward() ? end()+1 : start();
+}
+
+inline void KSelection::setForward()
+{
+ Anchor = start();
+}
+
+inline void KSelection::setBackward()
+{
+ Anchor = end()+1;
+}
+
+inline int KSelection::anchor() const { return Anchor; }
+
+inline void KSelection::cancel() { Anchor = -1; unset(); }
+
+inline bool KSelection::started() const { return Anchor != -1; }
+
+inline bool KSelection::justStarted() const { return Anchor != -1 && start() == -1; }
+
+inline bool KSelection::isForward() const { return Anchor == start(); }
+
+}
+
+#endif
diff --git a/khexedit/lib/kvaluecoltextexport.cpp b/khexedit/lib/kvaluecoltextexport.cpp
new file mode 100644
index 0000000..009ad54
--- /dev/null
+++ b/khexedit/lib/kvaluecoltextexport.cpp
@@ -0,0 +1,69 @@
+/***************************************************************************
+ kvaluecoltextexport.cpp - description
+ -------------------
+ begin : Wed Sep 3 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kbufferlayout.h"
+#include "kvaluecolumn.h"
+#include "kvaluecoltextexport.h"
+#include "helper.h"
+
+
+using namespace KHE;
+
+KValueColTextExport::KValueColTextExport( const KValueColumn* HC, const char *D, KCoordRange CR )
+ : KBufferColTextExport( HC, D, CR, HC->byteCodec()->encodingWidth() ),
+ ByteCodec( KByteCodec::createCodec(HC->coding()) )
+{
+}
+
+
+KValueColTextExport::~KValueColTextExport()
+{
+ delete ByteCodec;
+}
+
+
+
+void KValueColTextExport::print( QString &T ) const
+{
+ int p = 0;
+ int pEnd = NoOfBytesPerLine;
+ // correct boundaries
+ if( PrintLine == CoordRange.start().line() )
+ p = CoordRange.start().pos();
+ if( PrintLine == CoordRange.end().line() )
+ pEnd = CoordRange.end().pos()+1;
+
+ QString E;
+ E.setLength( ByteCodec->encodingWidth() );
+ // draw individual chars
+ uint e = 0;
+ for( ; p<pEnd; ++p, ++PrintData )
+ {
+ // get next position
+ uint t = Pos[p];
+ // clear spacing
+ T.append( whiteSpace(t-e) );
+ ByteCodec->encode( E, 0, *PrintData );
+ T.append( E );
+ e = t + ByteCodec->encodingWidth();
+ }
+
+ T.append( whiteSpace(NoOfCharsPerLine-e) );
+ ++PrintLine;
+}
+
diff --git a/khexedit/lib/kvaluecoltextexport.h b/khexedit/lib/kvaluecoltextexport.h
new file mode 100644
index 0000000..be6bab4
--- /dev/null
+++ b/khexedit/lib/kvaluecoltextexport.h
@@ -0,0 +1,47 @@
+/***************************************************************************
+ kvaluecoltextexport.h - description
+ -------------------
+ begin : Sam Aug 30 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_KVALUECOLTEXTEXPORT_H
+#define KHE_KVALUECOLTEXTEXPORT_H
+
+#include "kbytecodec.h"
+#include "kbuffercoltextexport.h"
+
+
+namespace KHE
+{
+
+class KValueColumn;
+
+
+class KValueColTextExport : public KBufferColTextExport
+{
+ public:
+ KValueColTextExport( const KValueColumn* BF, const char *D, KCoordRange CR );
+ virtual ~KValueColTextExport();
+
+ protected:
+ virtual void print( QString &T ) const;
+
+
+ protected:
+ KByteCodec *ByteCodec;
+};
+
+}
+
+#endif
diff --git a/khexedit/lib/kvaluecolumn.cpp b/khexedit/lib/kvaluecolumn.cpp
new file mode 100644
index 0000000..82da795
--- /dev/null
+++ b/khexedit/lib/kvaluecolumn.cpp
@@ -0,0 +1,134 @@
+/***************************************************************************
+ kvaluecolumn.cpp - description
+ -------------------
+ begin : Mit Sep 3 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. *
+ * *
+ ***************************************************************************/
+
+
+// qt specific
+#include <qpainter.h>
+// lib specific
+#include "kcolumnsview.h"
+#include "kbuffercursor.h"
+#include "kbufferlayout.h"
+#include "kbufferranges.h"
+#include "kvaluecolumn.h"
+#include "helper.h"
+#include "kcharcodec.h"
+
+using namespace KHE;
+
+static const KCoding DefaultCoding = HexadecimalCoding;
+static const KCoding NotDefaultCoding = DecimalCoding;
+static const int DefaultBinaryGapWidth = 1;
+
+
+KValueColumn::KValueColumn( KColumnsView *CV, KDataBuffer *B, KBufferLayout *L, KBufferRanges *R )
+ : KBufferColumn( CV, B, L, R ),
+ Coding( NotDefaultCoding ),
+ ByteCodec( 0 ),
+ BinaryGapWidth( DefaultBinaryGapWidth )
+{
+ setCoding( DefaultCoding );
+}
+
+
+KValueColumn::~KValueColumn()
+{
+}
+
+
+
+bool KValueColumn::setCoding( KCoding C )
+{
+ // no changes?
+ if( Coding == C )
+ return false;
+
+ delete ByteCodec;
+
+ Coding = C;
+ ByteCodec = KByteCodec::createCodec( Coding );
+ CodedByte.setLength( ByteCodec->encodingWidth() );
+
+ // recalculate depend sizes
+ recalcByteWidth();
+
+ if( PosX )
+ recalcX();
+ return true;
+}
+
+
+bool KValueColumn::setBinaryGapWidth( KPixelX BGW )
+{
+ // no changes?
+ if( BinaryGapWidth == BGW )
+ return false;
+
+ BinaryGapWidth = BGW;
+
+ // recalculate depend sizes
+ recalcByteWidth();
+
+ if( PosX )
+ recalcX();
+ return true;
+}
+
+
+void KValueColumn::recalcByteWidth()
+{
+ ByteWidth = ByteCodec->encodingWidth() * DigitWidth;
+
+ if( Coding == BinaryCoding )
+ {
+ BinaryHalfOffset = 4 * DigitWidth + BinaryGapWidth;
+ ByteWidth += BinaryGapWidth;
+ }
+ recalcVerticalGridX();
+}
+
+
+// perhaps sometimes there will be a grammar
+void KValueColumn::paintEditedByte( QPainter *P, char Byte, const QString &EditBuffer )
+{
+ KHEChar B = Codec->decode( Byte );
+
+ const QColorGroup &CG = View->colorGroup();
+
+ P->fillRect( 0,0,ByteWidth,LineHeight, QBrush(colorForChar(B),Qt::SolidPattern) );
+
+ drawCode( P, EditBuffer, CG.base() );
+}
+
+
+void KValueColumn::drawByte( QPainter *P, char Byte, KHEChar /*B*/, const QColor &Color ) const
+{
+ ByteCodec->encode( CodedByte, 0, Byte );
+ drawCode( P, CodedByte, Color );
+}
+
+
+void KValueColumn::drawCode( QPainter *P, const QString &Code, const QColor &Color ) const
+{
+ P->setPen( Color );
+ if( Coding == BinaryCoding )
+ {
+ // leave a gap in the middle
+ P->drawText( 0, DigitBaseLine, Code.left(4) );
+ P->drawText( BinaryHalfOffset, DigitBaseLine, Code.right(4) );
+ }
+ else
+ P->drawText( 0, DigitBaseLine, Code );
+}
diff --git a/khexedit/lib/kvaluecolumn.h b/khexedit/lib/kvaluecolumn.h
new file mode 100644
index 0000000..cc25929
--- /dev/null
+++ b/khexedit/lib/kvaluecolumn.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ kvaluecolumn.h - description
+ -------------------
+ begin : Mit Sep 3 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_KVALUECOLUMN_H
+#define KHE_KVALUECOLUMN_H
+
+// lib specific
+#include "kbytecodec.h"
+#include "kbuffercolumn.h"
+
+
+namespace KHE
+{
+
+class KBufferRanges;
+
+
+/** buffer column which displays the numerical values of the bytes
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+class KValueColumn : public KBufferColumn
+{
+ public:
+ KValueColumn( KColumnsView *CV, KDataBuffer *B, KBufferLayout *L, KBufferRanges *R );
+ virtual ~KValueColumn();
+
+ public:
+ void paintEditedByte( QPainter *P, char Byte, const QString &EditBuffer );
+
+ public: // modification access
+ /**
+ * returns true if there was a change
+ */
+ bool setCoding( KCoding C );
+ /** 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
+ */
+ bool setBinaryGapWidth( KPixelX BGW );
+
+
+ public: // value access
+ KPixelX binaryGapWidth() const;
+ KCoding coding() const;
+ const KByteCodec *byteCodec() const;
+
+
+ protected: // KBufferColumn API
+ virtual void drawByte( QPainter *P, char Byte, KHEChar B, const QColor &Color ) const;
+ virtual void recalcByteWidth();
+
+ protected:
+ void drawCode( QPainter *P, const QString &Code, const QColor &Color ) const;
+
+ protected: // set data
+ /** */
+ KCoding Coding;
+ /** */
+ KByteCodec *ByteCodec;
+ /** */
+ KPixelX BinaryGapWidth;
+
+ protected: // buffered data
+ /** buffer to hold the formatted coding */
+ mutable QString CodedByte;
+ /** calculated: Offset in pixels of the second half of the binary */
+ KPixelX BinaryHalfOffset;
+};
+
+
+inline KPixelX KValueColumn::binaryGapWidth() const { return BinaryGapWidth; }
+inline KCoding KValueColumn::coding() const { return Coding; }
+inline const KByteCodec *KValueColumn::byteCodec() const { return ByteCodec; }
+
+}
+
+#endif
diff --git a/khexedit/lib/kwordbufferservice.cpp b/khexedit/lib/kwordbufferservice.cpp
new file mode 100644
index 0000000..0489139
--- /dev/null
+++ b/khexedit/lib/kwordbufferservice.cpp
@@ -0,0 +1,209 @@
+/***************************************************************************
+ kwordbufferservice.cpp - description
+ -------------------
+ begin : Di Jan 18 2005
+ copyright : (C) 2005 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. *
+ * *
+ ***************************************************************************/
+
+
+// lib specific
+#include "kdatabuffer.h"
+#include "kcharcodec.h"
+#include "kwordbufferservice.h"
+
+using namespace KHE;
+
+
+bool KWordBufferService::isWordChar( unsigned int Index ) const
+{
+ KHEChar C = CharCodec->decode( Buffer->datum(Index) );
+ return !C.isUndefined() && C.isLetterOrNumber();
+}
+
+
+int KWordBufferService::indexOfPreviousWordStart( unsigned int Index ) const
+{
+ unsigned int Size = Buffer->size();
+ // already at the start or can the result only be 0?
+ if( Index == 0 || Size < 3 )
+ return 0;
+
+ // search in two rounds: first for the next char, than for the next nonchar
+ // after that return the index of the one before
+ bool LookingForFirstWordChar = false;
+ for( ; Index>0; --Index )
+ {
+ if( !isWordChar(Index-1) )
+ {
+ if( !LookingForFirstWordChar )
+ continue;
+ return( Index );
+ }
+ else if( !LookingForFirstWordChar )
+ LookingForFirstWordChar = true;
+ }
+ return 0;
+}
+
+
+int KWordBufferService::indexOfNextWordStart( unsigned int Index ) const
+{
+ unsigned int Size = Buffer->size();
+ bool LookingForFirstWordChar = false;
+ for( ; Index<Size; ++Index )
+ {
+ if( isWordChar(Index) )
+ {
+ if( !LookingForFirstWordChar )
+ continue;
+ return Index;
+ }
+ else if( !LookingForFirstWordChar )
+ LookingForFirstWordChar = true;
+ }
+ // if no more word found, go to the end
+ return Size;
+}
+
+
+int KWordBufferService::indexOfBeforeNextWordStart( unsigned int Index ) const
+{
+ unsigned int Size = Buffer->size();
+ bool LookingForFirstWordChar = false;
+ for( ; Index<Size; ++Index )
+ {
+ if( isWordChar(Index) )
+ {
+ if( !LookingForFirstWordChar )
+ continue;
+ return Index-1;
+ }
+ else if( !LookingForFirstWordChar )
+ LookingForFirstWordChar = true;
+ }
+ // if no more word found, go to the end
+ return Size-1;
+}
+
+
+int KWordBufferService::indexOfWordStart( unsigned int Index ) const
+{
+ for( ; Index > 0; --Index )
+ {
+ if( !isWordChar(Index-1) )
+ return( Index );
+ }
+ return 0;
+}
+
+
+int KWordBufferService::indexOfWordEnd( unsigned int Index ) const
+{
+ unsigned int Size = Buffer->size();
+ for( ++Index; Index<Size; ++Index )
+ {
+ if( !isWordChar(Index) )
+ return Index-1;
+ }
+ // word reaches the end
+ return Size-1;
+}
+
+
+int KWordBufferService::indexOfLeftWordSelect( unsigned int Index ) const
+{
+ // word at Index?
+ if( isWordChar(Index) )
+ {
+ // search for word start to the left
+ for( ; Index>0; --Index )
+ {
+ if( !isWordChar(Index-1) )
+ return Index;
+ }
+ // reached start, so return it
+ return 0;
+ }
+ else
+ {
+ unsigned int Size = Buffer->size();
+ // search for word start to the right
+ for( ++Index; Index<Size; ++Index )
+ {
+ if( isWordChar(Index) )
+ return Index;
+ }
+ // word reaches the end, so step behind
+ return Size;
+ }
+}
+
+
+int KWordBufferService::indexOfRightWordSelect( unsigned int Index ) const
+{
+ // no word at Index?
+ if( !isWordChar(Index) )
+ {
+ // search for word end to the left
+ for( ; Index>0; --Index )
+ {
+ if( isWordChar(Index-1) )
+ return Index;
+ }
+ // reached start, so return it
+ return 0;
+ }
+ else
+ {
+ unsigned int Size = Buffer->size();
+ for( ++Index; Index<Size; ++Index )
+ {
+ // search for word end to the right
+ if( !isWordChar(Index) )
+ return Index;
+ }
+ // word reaches the end, so step behind
+ return Size;
+ }
+}
+
+/*
+int KWordBufferService::indexOfBehindWordEnd( unsigned int Index ) const
+{
+ // no word at Index?
+ return !::isWordChar(datum(Index)) ? indexOfBehindLeftWordEnd(Index) : indexOfBehindRightWordEnd(Index+1)
+}
+
+
+int KWordBufferService::indexOfBehindRightWordEnd( unsigned int Index ) const
+{
+ for( ; Index<size(); ++Index )
+{
+ if( !::isWordChar(datum(Index)) )
+ return Index;
+}
+ // word reaches the end, so step behind
+ return size();
+}
+
+
+int KWordBufferService::indexOfBehindLeftWordEnd( unsigned int Index ) const
+{
+ for( --Index; Index>=0; --Index )
+{
+ if( ::isWordChar(datum(Index)) )
+ return Index+1;
+}
+ // word reaches the end, so step behind
+ return 0;
+}
+*/
diff --git a/khexedit/lib/kwordbufferservice.h b/khexedit/lib/kwordbufferservice.h
new file mode 100644
index 0000000..805f064
--- /dev/null
+++ b/khexedit/lib/kwordbufferservice.h
@@ -0,0 +1,137 @@
+/***************************************************************************
+ kwordbufferservice.h - description
+ -------------------
+ begin : Di Jan 18 2005
+ copyright : (C) 2005 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_KWORDBUFFERSERVICE_H
+#define KHE_KWORDBUFFERSERVICE_H
+
+// lib specific
+#include "ksection.h"
+
+namespace KHE
+{
+
+class KDataBuffer;
+class KCharCodec;
+
+/**
+ *
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KWordBufferService
+{
+ public:
+ KWordBufferService( KDataBuffer *B, KCharCodec *C );
+ ~KWordBufferService();
+
+
+ public:
+ /** searches for the start of the word including the given index.
+ * if no other nonwordchar preceds this is 0;
+ * If the byte at the given Index is already a nonword char the given index is returned.
+ * @param Index index to start with
+ * @param CharType
+ * @return index of the first char of the current word or the given index if there is none
+ */
+ int indexOfWordStart( unsigned int Index ) const;
+ int indexOfLeftWordSelect( unsigned int Index ) const;
+ /** searches for the end of the word including the given index.
+ * If the byte at the given Index is already a nonword char the given index is returned.
+ * if no other nonwordchar follows, that of the last byte;
+ * @param Index index to start with
+ * @param CharType
+ * @return index of the last char of the current word or the given index if there is none
+ */
+ int indexOfWordEnd( unsigned int Index ) const;
+ /** searches for the first char after the end of the word including the given index.
+ * If the byte at the given Index is already a nonword char the given index is returned.
+ * if no other nonwordchar follows that of behind the last byte;
+ * @param Index index to start with
+ * @param CharType
+ * @return index of the first char after the current word or the given index if there is none
+ */
+ int indexOfRightWordSelect( unsigned int Index ) const;
+ /** searches for the first char after the end of the word including the given index.
+ * If the byte at the given Index is already a nonword char the given index is returned.
+ * if no other nonwordchar follows that of behind the last byte;
+ * @param Index index to start with
+ * @param CharType
+ * @return index of the first char after the current word or the given index if there is none
+ */
+// int indexOfBehindLeftWordEnd( unsigned int Index ) const;
+ /** searches for the first char after the end of the word including the given index.
+ * If the byte at the given Index is already a nonword char the given index is returned.
+ * if no other nonwordchar follows that of behind the last byte;
+ * @param Index index to start with
+ * @param CharType
+ * @return index of the first char after the current word or the given index if there is none
+ */
+// int indexOfBehindRightWordEnd( unsigned int Index ) const;
+ /** searches the start of the next previous word that does not include the given index,
+ * if no further word is found 0 is returned.
+ * if the index is out of range the behaviour is undefined.
+ * @param Index
+ * @param CharType
+ * @return index of the next previous word start or 0
+ */
+ int indexOfPreviousWordStart( unsigned int Index ) const;
+ /** searches for the start of the next word not including the given index.
+ * if there isn't a next word the index behind end is returned
+ * @param Index
+ * @param CharType
+ * @return index of the start of the next word or behind end
+ */
+ int indexOfNextWordStart( unsigned int Index ) const;
+ /** searches for the start of the next word not including the given index.
+ * if there isn't a next word the index of the end is returned
+ * @param Index index to start with
+ * @param CharType
+ * @return index of the last nonword char before the next word or the last index
+ */
+ int indexOfBeforeNextWordStart( unsigned int Index ) const;
+
+ /** if Index is out of range the behaviour is undefined
+ * @param Index
+ * @param CharType
+ * @return @c true if the byte at position i is a char of type CharType
+ */
+ bool isWordChar( unsigned int Index ) const;
+
+ /** returns the section with a word around index.
+ * if there is no word the section is empty
+ * @param Index
+ * @param CharType
+ * @return the section with a word around index.
+ */
+ KSection wordSection( unsigned int Index ) const;
+
+ protected:
+ KDataBuffer *Buffer;
+ KCharCodec *CharCodec;
+};
+
+
+inline KWordBufferService::KWordBufferService( KDataBuffer *B, KCharCodec *C )
+ : Buffer( B ), CharCodec( C ) {}
+inline KWordBufferService::~KWordBufferService() {}
+
+inline KSection KWordBufferService::wordSection( unsigned int Index ) const
+{ return isWordChar(Index) ? KSection( indexOfWordStart(Index), indexOfWordEnd(Index) ) : KSection(); }
+
+}
+
+#endif
diff --git a/khexedit/lib/kwrappingrobuffer.cpp b/khexedit/lib/kwrappingrobuffer.cpp
new file mode 100644
index 0000000..b913c1a
--- /dev/null
+++ b/khexedit/lib/kwrappingrobuffer.cpp
@@ -0,0 +1,61 @@
+/***************************************************************************
+ kwrappingrobuffer.cpp - description
+ -------------------
+ begin : Mit Mai 14 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. *
+ * *
+ ***************************************************************************/
+
+
+#include "kwrappingrobuffer.h"
+
+using namespace KHE;
+
+KWrappingROBuffer::KWrappingROBuffer( const char* D, int L )
+{
+ Data = D;
+ Size = L;
+}
+
+KWrappingROBuffer::KWrappingROBuffer()
+{
+ Data = 0L;
+ Size = 0;
+}
+
+
+KWrappingROBuffer::~KWrappingROBuffer()
+{
+}
+
+
+const char *KWrappingROBuffer::dataSet( KSection S ) const
+{
+ return &Data[S.start()];
+}
+
+
+void KWrappingROBuffer::set( const char* D, int L )
+{
+ Data = D;
+ Size = L;
+}
+
+
+int KWrappingROBuffer::find( const char*/*KeyData*/, int /*Length*/, KSection /*Section*/ ) const
+{
+ return 0;
+}
+
+int KWrappingROBuffer::rfind( const char*, int /*Length*/, int /*Pos*/ ) const
+{
+ return 0;
+}
diff --git a/khexedit/lib/kwrappingrobuffer.h b/khexedit/lib/kwrappingrobuffer.h
new file mode 100644
index 0000000..51ee7b8
--- /dev/null
+++ b/khexedit/lib/kwrappingrobuffer.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ kwrappingrobuffer.h - description
+ -------------------
+ begin : Mit Mai 14 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_KWRAPPINGROBUFFER_H
+#define KHE_KWRAPPINGROBUFFER_H
+
+#include "kreadonlybuffer.h"
+
+namespace KHE
+{
+
+/**
+ *@author Friedrich W. H. Kossebau
+ */
+
+class KWrappingROBuffer : public KReadOnlyBuffer
+{
+ public:
+ static const int NothingFound = -1;
+
+ public:
+ KWrappingROBuffer();
+ KWrappingROBuffer( const char* D, int L );
+ virtual ~KWrappingROBuffer();
+
+
+ public: // KDataBuffer API
+ virtual bool prepareRange( KSection Range ) const;
+ virtual const char *dataSet( KSection S ) const;
+ virtual char datum( unsigned int Offset ) const;
+ virtual int size() const;
+ virtual bool isModified() const;
+
+ virtual int insert( int Pos, const char*, int Length );
+ virtual int remove( KSection S );
+ virtual unsigned int replace( KSection S, const char*, unsigned int Length );
+ virtual int fill( const char FillChar, int, int );
+ virtual void setDatum( unsigned int Offset, const char Char );
+
+ virtual void setModified( bool M );
+
+ virtual int find( const char*KeyData, int Length, KSection Section ) const;
+ virtual int rfind( const char*, int Length, int Pos = -1 ) const;
+
+
+ public: //
+ void set( const char* D, int L );
+
+ protected:
+ const char* Data;
+ int Size;
+ bool Modified;
+};
+
+inline int KWrappingROBuffer::size() const { return Size; }
+
+inline bool KWrappingROBuffer::isModified() const { return Modified; }
+
+inline bool KWrappingROBuffer::prepareRange( KSection ) const { return true; }
+inline char KWrappingROBuffer::datum( unsigned int Offset ) const { return Data[Offset]; }
+
+inline int KWrappingROBuffer::insert( int, const char*, int ) { return 0; }
+inline int KWrappingROBuffer::remove( KSection ) { return 0; }
+inline unsigned int KWrappingROBuffer::replace( KSection, const char*, unsigned int ) { return 0; }
+inline int KWrappingROBuffer::fill( const char , int, int ) { return 0; }
+inline void KWrappingROBuffer::setDatum( unsigned int, const char ) {}
+
+inline void KWrappingROBuffer::setModified( bool M ) { Modified = M; }
+}
+
+#endif