00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <qheaderview.h>
00029 #include <qtextcursor.h>
00030 #include "FEUISimpleHexTable.h"
00031 #include <QMessageBox>
00032
00033
00034
00035
00036
00037 FEHexItemEditor::FEHexItemEditor(QWidget *parent)
00038 : QTextEdit(parent), m_bOnlyHex(false), rowIndex(0) {}
00039
00040
00041
00042
00043
00044 void FEHexItemEditor::keyPressEvent(QKeyEvent *event)
00045 {
00046 QString s = toPlainText();
00047 QTextCursor cursor = textCursor();
00048
00049 event->accept();
00050
00051
00052 if (m_bOnlyHex && isHex(event->key()) && cursor.position() < s.length())
00053 {
00054 if (s[cursor.position()] == ' ')
00055 cursor.movePosition(QTextCursor::Right);
00056 setTextCursor(cursor);
00057 QTextEdit::keyPressEvent(event);
00058 }
00059
00060 else if (!m_bOnlyHex && cursor.position() < s.length() && !event->modifiers()
00061 && event->key() < 256 && isprint(event->key()))
00062 {
00063 QTextEdit::keyPressEvent(event);
00064 }
00065 else
00066 {
00067 if (!event->modifiers())
00068 {
00069 switch(event->key())
00070 {
00071 case Qt::Key_Home:
00072 QTextEdit::keyPressEvent(event);
00073 break;
00074 case Qt::Key_End:
00075 QTextEdit::keyPressEvent(event);
00076 break;
00077 case Qt::Key_Right:
00078 if (!m_bOnlyHex && s[cursor.position()+1] == ' ')
00079 cursor.movePosition(QTextCursor::Right);
00080 setTextCursor(cursor);
00081 QTextEdit::keyPressEvent(event);
00082 break;
00083 case Qt::Key_Left:
00084 if (!m_bOnlyHex && s[cursor.position()-1] == ' ')
00085 cursor.movePosition(QTextCursor::Left);
00086 setTextCursor(cursor);
00087 QTextEdit::keyPressEvent(event);
00088 break;
00089 }
00090 }
00091 }
00092 }
00093
00094
00095
00096
00097
00098 void FEHexItemEditor::setAllowOnlyHexKeys(bool onlyHex)
00099 {
00100 m_bOnlyHex = onlyHex;
00101 }
00102
00103
00104
00105
00106
00107 bool FEHexItemEditor::isHex(int cSign)
00108 {
00109 if ((cSign > 47) && (cSign < 58))
00110 return true;
00111 if ((cSign > 64) && (cSign < 71))
00112 return true;
00113 if ((cSign > 96) && (cSign < 104))
00114 return true;
00115
00116 return false;
00117 }
00118
00119
00120 void FEHexItemEditor::dropEvent(QDropEvent *e)
00121 {
00122 e->accept();
00123 }
00124
00125 void FEHexItemEditor::mousePressEvent(QMouseEvent *e)
00126 {
00127 e->accept();
00128 }
00129
00130
00131
00132
00133
00134
00135 FEUISimpleHexTableDelegate::FEUISimpleHexTableDelegate(QObject *parent)
00136 : QItemDelegate(parent), isResolving(false) {}
00137
00138 QWidget *FEUISimpleHexTableDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem&,
00139 const QModelIndex &index) const
00140 {
00141 FEHexItemEditor *editor = new FEHexItemEditor(parent);
00142
00143 editor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00144 editor->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00145 if(index.column() == 1)
00146 {
00147 editor->setReadOnly(false);
00148 editor->setOverwriteMode(true);
00149 editor->setAllowOnlyHexKeys(true);
00150 }
00151 else if (index.column() == 2)
00152 {
00153 editor->setReadOnly(false);
00154 editor->setOverwriteMode(true);
00155 editor->setAllowOnlyHexKeys(false);
00156 }
00157 else
00158 {
00159 editor->setReadOnly(true);
00160 }
00161
00162 return editor;
00163 }
00164
00165
00166
00167
00168
00169 void FEUISimpleHexTableDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
00170 {
00171 FEHexItemEditor *edit = qobject_cast<FEHexItemEditor *>(editor);
00172 if (edit)
00173 {
00174 edit->setHtml(index.model()->data(index, Qt::EditRole).toString());
00175 }
00176 }
00177
00178
00179
00180
00181
00182 void FEUISimpleHexTableDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
00183 const QModelIndex &index) const
00184 {
00185 FEHexItemEditor *edit = qobject_cast<FEHexItemEditor *>(editor);
00186 if (edit)
00187 {
00188
00189 model->setData(index, edit->toHtml());
00190 }
00191 }
00192
00193
00194
00195
00196
00197 FEUISimpleHexTableItem::FEUISimpleHexTableItem()
00198 : QTableWidgetItem(), m_bSecurityArea(false), isResolving(false) {}
00199
00200
00201
00202
00203
00204 FEUISimpleHexTableItem::FEUISimpleHexTableItem(const QString &text)
00205 : QTableWidgetItem(text), m_bSecurityArea(false), isResolving(false) {}
00206
00207
00208
00209
00210
00211 QTableWidgetItem *FEUISimpleHexTableItem::clone() const
00212 {
00213 FEUISimpleHexTableItem *item = new FEUISimpleHexTableItem();
00214 *item = *this;
00215 return item;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 QVariant FEUISimpleHexTableItem::display() const
00230 {
00231 QTextDocument textDoc;
00232 QString modelText;
00233
00234 modelText = hexString();
00235 textDoc.setHtml(modelText);
00236 return textDoc.toPlainText();
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246 QVariant FEUISimpleHexTableItem::data(int role) const
00247 {
00248
00249 if (role == Qt::DisplayRole)
00250 return display();
00251
00252
00253
00254 if (role == Qt::TextColorRole)
00255 {
00256 if (m_bSecurityArea)
00257 return qVariantFromValue(QColor(Qt::red));
00258 }
00259
00260 if (role == Qt::EditRole)
00261 {
00262 return hexString();
00263 }
00264
00265 return QTableWidgetItem::data(role);
00266 }
00267
00268
00269
00270
00271
00272 void FEUISimpleHexTableItem::setData(int role, const QVariant &value)
00273 {
00274 QTableWidgetItem::setData(role, value);
00275 if (tableWidget())
00276 tableWidget()->viewport()->update();
00277 }
00278
00279
00280
00281
00282
00283 void FEUISimpleHexTableItem::setSecurityArea(bool isSecure)
00284 {
00285 m_bSecurityArea = isSecure;
00286 }
00287
00288
00289
00290
00291
00292 char FEUISimpleHexTable::hexToChar(char *str)
00293 {
00294 int iValue = 0;
00295
00296 str[0] = (unsigned char) toupper((int) str[0]);
00297 str[1] = (unsigned char) toupper((int) str[1]);
00298
00299 if ((str[0] >= '0') && (str[0] <= '9')) { iValue = (str[0] - 48) << 4; }
00300 if ((str[0] >= 'A') && (str[0] <= 'F')) { iValue = (str[0] - 55) << 4; }
00301 if ((str[1] >= '0') && (str[1] <= '9')) { iValue += (str[1] - 48); }
00302 if ((str[1] >= 'A') && (str[1] <= 'F')) { iValue += (str[1] - 55); }
00303
00304 if (isprint(char(iValue)))
00305 return char(iValue);
00306 else
00307 return '.';
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 void FEUISimpleHexTable::updateAscii(QTableWidgetItem* item)
00317 {
00318 QTableWidgetItem *editor = NULL;
00319 if (item && item == currentItem())
00320 {
00321 if (column(item) == 1)
00322 {
00323 editor = (QTableWidgetItem*)this->item(row(item),2);
00324 if (editor != NULL)
00325 {
00326 QString str = "";
00327 char* s = qstrdup(item->text().toLatin1());
00328 char outStr[64] = {0};
00329 removeBlanks(outStr, s, strlen(s));
00330 for (int i=0; i<strlen(outStr); i+=2)
00331 {
00332 str += hexToChar((char*)outStr+i);
00333 }
00334 editor->setText(str);
00335 delete s;
00336 }
00337 }
00338 if (column(item) == 2)
00339 {
00340 editor = (QTableWidgetItem*)this->item(row(item),1);
00341 if (editor != NULL)
00342 {
00343 char* s = qstrdup(item->text().toLatin1());
00344 char str[64] = {0};
00345 char* outIter = str;
00346 for (int i=0; i<strlen(s); i++)
00347 {
00348 char sHex[3] = {0};
00349 charToHex(s[i], sHex);
00350 *(outIter++) = sHex[0];
00351 *(outIter++) = sHex[1];
00352 }
00353 char outStr[128] = {0};
00354 addSpaces(outStr, str, strlen(str));
00355 editor->setText(outStr);
00356 delete s;
00357 }
00358 }
00359 }
00360 }
00361
00362
00363
00364
00365
00366 void FEUISimpleHexTable::charToHex(char a, char *str)
00367 {
00368 const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
00369 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
00370
00371 sprintf(str, "%c%c",hex[((unsigned) a/16) & 0x0F], hex[(unsigned) a & 0x0F]);
00372
00373 str[2] = 0;
00374 }
00375
00376
00377
00378
00379
00380 void FEUISimpleHexTable::addSpaces(char* dest, char* src, int srcLen)
00381 {
00382
00383 char* destIter;
00384
00385 destIter = dest;
00386 for (int iCnt=0; iCnt < srcLen; iCnt++)
00387 {
00388 *(destIter++) = src[iCnt];
00389 if ((iCnt+1) % 2 == 0 && iCnt < srcLen -2)
00390 *(destIter++) = ' ';
00391 }
00392 }
00393
00394
00395
00396
00397
00398 void FEUISimpleHexTable::removeBlanks(char* dest, char* src, int srcLen)
00399 {
00400
00401 char* destIter;
00402 destIter = dest;
00403 for (int iCnt=0; iCnt < srcLen; iCnt++)
00404 {
00405 if (src[iCnt] != ' ')
00406 *(destIter++) = src[iCnt];
00407 }
00408 }
00409
00410
00411
00412
00413
00414 void FEUISimpleHexTable::initTable(int size, int blockSize)
00415 {
00416 clearContents();
00417 m_iBlockSize = blockSize;
00418 setRowCount(size);
00419 unsigned char ucHex[blockSize];
00420 memset(ucHex, 0, blockSize);
00421 for (int i=0; i<size; i++)
00422 edit(i, ucHex, false);
00423
00424 }
00425
00426
00427
00428
00429
00430 void FEUISimpleHexTable::convUcharToAscii(char* dest, unsigned char* src, int srcLen)
00431 {
00432 for (int i=0; i<srcLen; i++)
00433 {
00434 if (isprint(src[i]))
00435 dest[i] = src[i];
00436 else
00437 dest[i] = '.';
00438 }
00439 }
00440
00441
00442
00443
00444
00445 int FEUISimpleHexTable::edit(int record, unsigned char* data, bool securityArea)
00446 {
00447 FEUISimpleHexTableItem* hexItem ;
00448 FEUISimpleHexTableItem* dbItem;
00449 FEUISimpleHexTableItem* asciiItem;
00450
00451 if (record >= rowCount())
00452 return -1;
00453
00454
00455 char sDbn[8] = {0};
00456 sprintf(sDbn, "%d", record);
00457 dbItem = (FEUISimpleHexTableItem*)item(record, 0);
00458 if (!dbItem)
00459 dbItem = new FEUISimpleHexTableItem(sDbn);
00460 else
00461 {
00462 dbItem->setText(sDbn);
00463 }
00464 dbItem->setFont(font());
00465 setItem(record, 0, dbItem);
00466
00467
00468
00469 int iHexLen = 2 * m_iBlockSize + 2;
00470 char sHexData[iHexLen];
00471 memset(sHexData, 0, iHexLen);
00472 FEDM_ConvHexUCharToHexChar(data, m_iBlockSize, sHexData, iHexLen);
00473
00474 int iDataLen = 2 * m_iBlockSize + m_iBlockSize / 2 + 2;
00475 char sData[iDataLen];
00476 memset(sData, 0, iDataLen);
00477
00478 addSpaces(sData, sHexData, iDataLen);
00479
00480 hexItem = (FEUISimpleHexTableItem*)item(record, 1);
00481 if (!hexItem)
00482 {
00483 hexItem = new FEUISimpleHexTableItem();
00484 setItem(record, 1, hexItem);
00485 }
00486 hexItem->setSecurityArea(securityArea);
00487 hexItem->setFont(font());
00488
00489 QString text;
00490 if (securityArea)
00491 {
00492 text = "<font color=\"red\">";
00493 text += sData;
00494 text += "</font>";
00495 }
00496 else
00497 text = sData;
00498 hexItem->setText(text);
00499
00500
00501 int iAsciiLen = m_iBlockSize + 1;
00502 char sAscii[iAsciiLen];
00503 memset(sAscii, 0, iAsciiLen);
00504 convUcharToAscii(sAscii, data, m_iBlockSize);
00505 asciiItem = (FEUISimpleHexTableItem*)item(record, 2);
00506 if (!asciiItem)
00507 asciiItem = new FEUISimpleHexTableItem(sAscii);
00508 else
00509 asciiItem->setText(sAscii);
00510 asciiItem->setFont(font());
00511 setItem(record, 2, asciiItem);
00512
00513 return 0;
00514 }
00515
00516
00517
00518
00519
00520 FEUISimpleHexTable::FEUISimpleHexTable(QWidget *parent)
00521 : QTableWidget(parent)
00522 {
00523 m_iBlockSize = 0;
00524
00525
00526 QFont fnt;
00527 fnt.setFixedPitch(true);
00528 fnt.setStyleHint(QFont::System);
00529
00530 fnt.setFamily("Misc Fixed");
00531 setFont(fnt);
00532
00533 this->insertColumn(0);
00534 this->insertColumn(1);
00535 this->insertColumn(2);
00536
00537 QTableWidgetItem* dbItem = new QTableWidgetItem("DB");
00538 setHorizontalHeaderItem(0, dbItem);
00539 QTableWidgetItem* hexItem = new QTableWidgetItem("HEX DATA");
00540 setHorizontalHeaderItem(1, hexItem);
00541 QTableWidgetItem* asciiItem = new QTableWidgetItem("ASCII");
00542 setHorizontalHeaderItem(2, asciiItem);
00543 setItemPrototype(item(0, 1));
00544 setItemDelegate(new FEUISimpleHexTableDelegate());
00545 #if !defined(QT_NO_DBUS) && defined(Q_OS_UNIX)
00546 new FEUISimpleHexTableAdaptor(this);
00547 #endif
00548
00549 QHeaderView *h = verticalHeader();
00550 h->hide();
00551
00552 h = horizontalHeader();
00553 h->stretchLastSection();
00554 createActions();
00555 setupContextMenu();
00556
00557 connect(this, SIGNAL(itemChanged(QTableWidgetItem*)),
00558 this, SLOT(updateAscii(QTableWidgetItem*)));
00559
00560 }
00561
00562
00563
00564
00565
00566 FEUISimpleHexTable::~FEUISimpleHexTable()
00567 {
00568
00569 }
00570
00571
00572
00573
00574
00575 void FEUISimpleHexTable::getHexString(char* str, int row)
00576 {
00577 QTableWidgetItem *editor;
00578 QString hexStr = "";
00579
00580 editor = item(row, 1);
00581 if (editor != NULL)
00582 {
00583 hexStr += editor->text();
00584 }
00585 char* s = qstrdup(hexStr.toLatin1());
00586 removeBlanks(str, s, strlen(s));
00587 delete s;
00588 }
00589
00590
00591
00592
00593
00594 void FEUISimpleHexTable::createActions()
00595 {
00596 clearAction = new QAction(tr("Clear"), this);
00597 clearAction->setShortcut(Qt::Key_Delete);
00598 connect(clearAction, SIGNAL(triggered()), this, SLOT(clear()));
00599 }
00600
00601
00602
00603
00604
00605 void FEUISimpleHexTable::clear()
00606 {
00607 clearContents();
00608 setRowCount(0);
00609 }
00610
00611
00612
00613
00614
00615 void FEUISimpleHexTable::setupContextMenu()
00616 {
00617 addAction(clearAction);
00618 setContextMenuPolicy(Qt::ActionsContextMenu);
00619 }
00620
00621
00622
00623
00624
00625 void FEUISimpleHexTable::resizeEvent(QResizeEvent *event)
00626 {
00627
00628
00629
00630 int blockSize;
00631 blockSize = m_iBlockSize > 0 ? m_iBlockSize : 12;
00632 QHeaderView *h = horizontalHeader();
00633 h->stretchLastSection();
00634 h->resizeSection(0, 40);
00635
00636 h->resizeSection(1, 188);
00637
00638 h->resizeSection(2, 110);
00639 }