diff options
Diffstat (limited to 'src/hexGui.cpp')
-rw-r--r-- | src/hexGui.cpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/src/hexGui.cpp b/src/hexGui.cpp new file mode 100644 index 0000000..a2cb65e --- /dev/null +++ b/src/hexGui.cpp @@ -0,0 +1,326 @@ +/* $Id: hexGui.cpp,v 1.13 2006-11-05 04:42:43 ganzhorn Exp $ + * This file is part of lfhex. + * Copyright (C) 2006 Salem Ganzhorn <eyekode@yahoo.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <QFileDialog> +#include <qsizepolicy.h> +#include <qstatusbar.h> +#include <qmenubar.h> +#include <qapplication.h> +#include <qscrollbar.h> +#include <qstring.h> +#include <qmessagebox.h> +#include <qlineedit.h> +#include <QDockWidget> +#include <QLabel> +#include <QCloseEvent> +#include <QPushButton> + +#include "hexGui.hpp" +#include "box.hpp" +#include "expr.h" + +HexGui::HexGui (QWidget * p) + : QMainWindow(p) +{ + QWidget* h = new QWidget(this); + QHBoxLayout* l = new QHBoxLayout(h); + + hexEditor = new HexEditor(h); + hexEditor->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, + QSizePolicy::Expanding ) ); + l->addWidget(hexEditor); + vsb = new QScrollBar(h); + l->addWidget(vsb); + vsb->setRange(0,0); + + setCentralWidget(h); + + connect( hexEditor,SIGNAL(rangeChanged(off_t,off_t)), + this,SLOT(setScrollBarRange(off_t,off_t)) ); + connect( vsb, SIGNAL(valueChanged(int)), + hexEditor,SLOT(setTopLeftToPercent(int)) ); + connect( hexEditor, SIGNAL(topLeftChanged(off_t)), + this, SLOT(setScrollBarValue(off_t)) ); + connect( hexEditor, SIGNAL(offsetChanged(off_t)), + this, SLOT(setOffsetLabel(off_t)) ); + + // setup dock + QDockWidget* dock = new QDockWidget("Conversions Assistant",this); + vbox* vb = new vbox(dock); + conversionDlg = new ConversionDlg(vb); + connect(conversionDlg,SIGNAL(nextPressed()),this,SLOT(searchForwards())); + connect(conversionDlg,SIGNAL(prevPressed()),this,SLOT(searchBackwards())); + + dock->setWidget(vb); + dock->hide(); + connect(hexEditor,SIGNAL(selectionChanged(const QString &)), + conversionDlg, SLOT(valueChanged(const QString&)) ); + addDockWidget( Qt::RightDockWidgetArea, dock ); + dock->setFloating(true); + + // setup menu: + fileMenu = new QMenu("&File",this); + fileMenu->addAction("&Open...",this,SLOT(browseLoadFile())); + fileMenu->addAction("&Open in new editor...",this, + SLOT(browseLoadFileNew())); + fileMenu->addSeparator(); + actions[SaveAction] = fileMenu->addAction("&Save",this,SLOT(save())); + actions[SaveAsAction] = fileMenu->addAction("Save &As...",this, + SLOT(saveAs())); + // only include close functions in menu if this is a toplevel window + if( isTopLevel() ) { + fileMenu->addSeparator(); + if( isTopLevel() ) + fileMenu->addAction("Close Editor",this,SLOT(close())); + else + fileMenu->addAction("Close File",this,SLOT(closeFile())); + fileMenu->addAction("&Exit Application",qApp, SLOT(quit())); + } + menuBar()->addMenu( fileMenu ); + + // edit pulldown + editMenu = new QMenu( "&Edit", this ); + actions[UndoAction] = editMenu->addAction("&Undo",hexEditor,SLOT(undo())); + actions[RedoAction] = editMenu->addAction("&Redo",hexEditor,SLOT(redo())); + menuBar()->addMenu( editMenu ); + + // view menu + viewMenu = new QMenu("&View",this); + QAction* dockAction = dock->toggleViewAction(); + viewMenu->addAction( dockAction ); + + // menu for selecting editing base (octal/binary/hex) + QMenu * baseMenu = new QMenu("&Editing base", this); + baseMenu->addAction("&Hex",hexEditor,SLOT(setBaseHex())); + baseMenu->addAction("&ASCII",hexEditor,SLOT(setBaseASCII())); + baseMenu->addAction("&Binary",hexEditor,SLOT(setBaseBinary())); + baseMenu->addAction("&Octal",hexEditor,SLOT(setBaseOctal())); + viewMenu->addMenu(baseMenu); + // menu for selecting bytes per column + QMenu * nbytesMenu = new QMenu("&Bytes per column",this); + nbytesMenu->addAction("&1",hexEditor,SLOT(set1BPC())); + nbytesMenu->addAction("&2",hexEditor,SLOT(set2BPC())); + nbytesMenu->addAction("&4",hexEditor,SLOT(set4BPC())); + nbytesMenu->addAction("&8",hexEditor,SLOT(set8BPC())); + viewMenu->addMenu(nbytesMenu); + menuBar()->addMenu(viewMenu); + + resize(400,196); + statusBar()->showMessage("Ready",2000); + statusBar()->addWidget(new QLabel("Cursor Offset:",statusBar())); + offsetLineEdit = new QLineEdit(statusBar()); +// offsetLineEdit->setValidator( new HexValidator(offsetLineEdit) ); + connect(offsetLineEdit,SIGNAL(returnPressed()), + SLOT(setOffsetFromStatusBar())); + statusBar()->addWidget(offsetLineEdit); + // progressBar = new QProgressBar(statusBar()); + // statusBar()->addWidget(progressBar,1,FALSE); + statusLabel = new QLabel("",statusBar()); + statusBar()->addWidget(statusLabel,1); + statusBar()->setSizeGripEnabled( !parent() ); + setWindowTitle(PROGRAM_STRING); + + // deactivate save,saveas undo and redo + actions[SaveAction]->setEnabled(false); + actions[SaveAsAction]->setEnabled(false); + actions[UndoAction]->setEnabled(false); + actions[RedoAction]->setEnabled(false); +} + +HexGui::~HexGui() +{ +} + +bool HexGui::open(const char * filename) +{ + if (hexEditor->open(filename)) { + if( isTopLevel() ) + setWindowTitle(filename); + else + statusLabel->setText(filename); + actions[SaveAction]->setEnabled(true); + actions[SaveAsAction]->setEnabled(true); + actions[UndoAction]->setEnabled(true); + actions[RedoAction]->setEnabled(true); + return true; + } else { + return false; + } +} + +void HexGui::gotoOffset(off_t offset) +{ + hexEditor->setOffset(offset); + hexEditor->seeCursor(); + emit offsetChanged(offset); +} + +bool HexGui::browseLoadFile() +{ + QString filename = QFileDialog::getOpenFileName(); + if( filename.isNull() ) + return false; + return open( C_STR(filename) ); +} +bool HexGui::browseLoadFileNew() +{ + QString filename = QFileDialog::getOpenFileName(); + if( filename.isNull() ) + return false; + HexGui * hg = new HexGui(); + bool retval = hg->open( C_STR(filename) ); + hg->show(); + return retval; +} + +bool HexGui::save() +{ + statusBar()->showMessage("saveing " + hexEditor->filename()) ; + bool retval = hexEditor->save(); + statusBar()->showMessage("done.",2000); + return retval; +} + +bool HexGui::saveAs() +{ + QString filename = QFileDialog::getSaveFileName(); + if( filename.isNull() ) + return false; + statusBar()->showMessage("saveing to \"" + filename + "\"..."); + bool retval = hexEditor->save(filename); + statusBar()->showMessage("done.",2000); + setWindowTitle(filename); + return retval; +} + +int HexGui::closeFile() +{ + return closeFile( false ); +} +int HexGui::closeFile( bool force ) +{ + return hexEditor->closeFile(force); +} + +void HexGui::closeEvent( QCloseEvent * ce ) +{ + if( hexEditor->closeFile() == QMessageBox::Cancel ) + ce->ignore(); + else + ce->accept(); +} + +void HexGui::setScrollBarRange(off_t low, off_t high) +{ + (void)low;(void)high; + // range must be contained in the space of an integer, just do 100 + // increments + vsb->setRange(0,100); +} +void HexGui::setScrollBarValue(off_t pos) +{ + // pos is the topLeft pos, set the scrollbar to the + // location of the last byte on the page + // Note: offsetToPercent now rounds up, so we don't + // have to worry about if this is the topLeft or bottom right + vsb->setValue(hexEditor->offsetToPercent(pos)); +} +void HexGui::setOffsetLabel(off_t pos) +{ + QString label; + char buffer[64]; +#if _LARGEFILE_SOURCE + sprintf(buffer,"0x%lx",pos); +#else + sprintf(buffer,"0x%x",pos); +#endif + label = buffer; + offsetLineEdit->setText(label); +} + +const QString& HexGui::filename(void) const +{ + static QString value = ""; + if(!hexEditor) + return (value=""); + return (value=hexEditor->filename()); +} + +void HexGui::setOffsetFromStatusBar() +{ + // remove leading "0x" if necessary + off_t o; + if( !expr_eval( C_STR(offsetLineEdit->text()),o ) || o < 0 ) { + QApplication::beep(); + } else { + gotoOffset(o); + } + return; + bool ok; + off_t offset; + QString value = offsetLineEdit->text(); + if( value.length() > 2 && value[1] == 'x' ) { + value = value.mid(2); + offset = value.toInt(&ok,16); + } else { + offset = value.toInt(&ok,10); + if( !ok ) { + offset = value.toInt(&ok,16); + } + } + if( !ok ) { + cerr << "Error converting offset: " << C_STR(offsetLineEdit->text()) + << endl; + } else { + gotoOffset(offset); + } +} + +off_t HexGui::offset() const +{ + return hexEditor->offset(); +} + +Reader * HexGui::reader() +{ + return hexEditor->reader(); +} + +void HexGui::setSelection(off_t start,off_t stop) +{ + hexEditor->setSelection(HexEditor::SelectionStart,start); + hexEditor->setSelection(HexEditor::SelectionEnd,stop); +} + +void HexGui::search( bool forward ) +{ + QString hex = conversionDlg->hexValue(); + if( !hex.isEmpty() ) { + hexEditor->search( hex, forward ); + } +} + +void HexGui::searchForwards() +{ + search(true); +} + +void HexGui::searchBackwards() +{ + search(false); +} |