Skip to content

Commit

Permalink
Implement hex editor/viewer via Dax89/QHexView.
Browse files Browse the repository at this point in the history
  • Loading branch information
vaibhavpandeyvpz committed May 9, 2019
1 parent 004720b commit d94b7d8
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
@@ -1,3 +1,6 @@
[submodule "Qt-Frameless-Window-DarkStyle"]
path = Qt-Frameless-Window-DarkStyle
url = https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle
[submodule "QHexView"]
path = QHexView
url = https://github.com/Dax89/QHexView.git
1 change: 1 addition & 0 deletions QHexView
Submodule QHexView added at 4524ca
3 changes: 3 additions & 0 deletions README.md
Expand Up @@ -32,6 +32,7 @@ If you are just willing to quickly decompile an [Android](https://android.com/)
- Decompile/recompile/sign & install APKs
- Built-in code editor (\*.java; \*.smali; \*.xml; \*.yml) w/ syntax highlighting
- Built-in viewer for image (\*.gif; \*.jpg; \*.jpeg; \*.png) files
- Built-in hex viewer for binary files

### Downloads
Please head over to [Releases](https://github.com/vaibhavpandeyvpz/apkstudio/releases) page for downloading.
Expand All @@ -44,6 +45,8 @@ Information on building from source is provided in the [Wiki](https://github.com
- [patrickfav](https://github.com/patrickfav) for [uber-apk-signer](https://github.com/patrickfav/uber-apk-signer)
- [skylot](https://github.com/skylot) for [jadx](https://github.com/skylot/jadx)
- [probonopd](https://github.com/probonopd) for [linuxdeployqt](https://github.com/probonopd/linuxdeployqt)
- [Jürgen Skrotzky](https://github.com/Jorgen-VikingGod) for [Qt-Frameless-Window-DarkStyle](https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle)
- [Antonio Davide](https://github.com/Dax89) for [QHexView](https://github.com/Dax89/QHexView)
- [p.yusukekamiyamane](https://p.yusukekamiyamane.com/) for [Fugue](https://p.yusukekamiyamane.com/) icons
- [Icons8](https://icons8.com/) for various icons
- [Surendrajat](https://github.com/Surendrajat) for maintaining project while I couldn't
Expand Down
4 changes: 4 additions & 0 deletions apkstudio.pro
@@ -1,3 +1,5 @@
include(QHexView/QHexView.pri)

QT += core gui widgets

TARGET = ApkStudio
Expand All @@ -16,6 +18,7 @@ HEADERS += \
sources/binarysettingswidget.h \
sources/findreplacedialog.h \
sources/flickcharm.h \
sources/hexedit.h \
sources/imageviewerwidget.h \
sources/mainwindow.h \
sources/processutils.h \
Expand All @@ -30,6 +33,7 @@ HEADERS += \
SOURCES += \
Qt-Frameless-Window-DarkStyle/DarkStyle.cpp \
sources/flickcharm.cpp \
sources/hexedit.cpp \
sources/imageviewerwidget.cpp \
sources/main.cpp \
sources/adbinstallworker.cpp \
Expand Down
3 changes: 3 additions & 0 deletions resources/all.qrc
@@ -1,10 +1,13 @@
<RCC>
<qresource prefix="/highlights">
<file>html.def</file>
<file>java.def</file>
<file>numbers.def</file>
<file>properties.def</file>
<file>smali.def</file>
<file>strings.def</file>
<file>xml.def</file>
<file>yaml.def</file>
<file>yml.def</file>
</qresource>
<qresource prefix="/icons">
Expand Down
1 change: 1 addition & 0 deletions resources/html.def
@@ -0,0 +1 @@
@include html
1 change: 1 addition & 0 deletions resources/properties.def
@@ -0,0 +1 @@
keywords \b[a-zA-Z0-9.]+=
1 change: 1 addition & 0 deletions resources/yaml.def
@@ -0,0 +1 @@
@include yml
36 changes: 36 additions & 0 deletions sources/hexedit.cpp
@@ -0,0 +1,36 @@
#include <QFile>
#include <QVBoxLayout>
#include "document/buffer/qmemorybuffer.h"
#include "hexedit.h"

HexEdit::HexEdit(QWidget *parent)
: QWidget(parent)
{
auto layout = new QVBoxLayout();
layout->addWidget(m_HexView = new QHexView(this));
layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
}

QString HexEdit::filePath()
{
return m_FilePath;
}

void HexEdit::open(const QString &path)
{
auto document = QHexDocument::fromFile<QMemoryBuffer>(path);
m_HexView->setDocument(document);
m_FilePath = path;
}

bool HexEdit::save()
{
QFile file(m_FilePath);
if (file.open(QFile::WriteOnly)) {
m_HexView->document()->saveTo(&file);
file.close();
return true;
}
return false;
}
20 changes: 20 additions & 0 deletions sources/hexedit.h
@@ -0,0 +1,20 @@
#ifndef HEXEDIT_H
#define HEXEDIT_H

#include <QWidget>
#include "qhexview.h"

class HexEdit : public QWidget
{
Q_OBJECT
private:
QString m_FilePath;
QHexView *m_HexView;
public:
explicit HexEdit(QWidget *parent = nullptr);
QString filePath();
void open(const QString &path);
bool save();
};

#endif // HEXEDIT_H
66 changes: 42 additions & 24 deletions sources/mainwindow.cpp
Expand Up @@ -26,18 +26,20 @@
#include "apkrecompileworker.h"
#include "apksignworker.h"
#include "findreplacedialog.h"
#include "hexedit.h"
#include "imageviewerwidget.h"
#include "mainwindow.h"
#include "settingsdialog.h"
#include "signingconfigdialog.h"
#include "sourcecodeedit.h"
#include "mainwindow.h"

#define COLOR_CODE 0x2ad2c9
#define COLOR_COMMAND 0xd0d2d3
#define COLOR_OUTPUT 0xffffff
#define COLOR_ERROR 0xfb0a2a

#define IMAGE_EXTENSIONS "gif|jpg|jpeg|png"
#define IMAGE_EXTENSIONS "gif|jpeg|jpg|png"
#define TEXT_EXTENSIONS "java|html|properties|smali|txt|xml|yaml|yml"

#define URL_CONTRIBUTE "https://github.com/vaibhavpandeyvpz/apkstudio"
#define URL_DOCUMENTATION "https://vaibhavpandey.com/apkstudio/"
Expand Down Expand Up @@ -328,14 +330,16 @@ int MainWindow::findTabIndex(const QString &path)
int total = m_TabEditors->count();
for (int i = 0; i < total; i++) {
QString path2;
auto edit = dynamic_cast<SourceCodeEdit *>(m_TabEditors->widget(i));
auto widget = m_TabEditors->widget(i);
auto edit = dynamic_cast<SourceCodeEdit *>(widget);
auto hex = dynamic_cast<HexEdit *>(widget);
auto viewer = dynamic_cast<ImageViewerWidget *>(widget);
if (edit) {
path2 = edit->filePath();
} else {
auto viewer = dynamic_cast<ImageViewerWidget *>(m_TabEditors->widget(i));
if (viewer) {
path2 = viewer->filePath();
}
} else if (hex) {
path2 = hex->filePath();
} else if (viewer) {
path2 = viewer->filePath();
}
if (QString::compare(path, path2) == 0) {
return i;
Expand Down Expand Up @@ -817,14 +821,16 @@ void MainWindow::handleTabChanged(const int index)
qDebug() << "User changed current tab" << index;
#endif
QString path;
auto edit = dynamic_cast<SourceCodeEdit *>(m_TabEditors->currentWidget());
auto widget = m_TabEditors->currentWidget();
auto edit = dynamic_cast<SourceCodeEdit *>(widget);
auto hex = dynamic_cast<HexEdit *>(widget);
auto viewer = dynamic_cast<ImageViewerWidget *>(widget);
if (edit) {
path = edit->filePath();
} else {
auto viewer = dynamic_cast<ImageViewerWidget *>(m_TabEditors->currentWidget());
if (viewer) {
path = viewer->filePath();
}
} else if (hex) {
path = hex->filePath();
} else if (viewer) {
path = viewer->filePath();
}
const int total = m_ModelOpenFiles->rowCount();
for (int i = 0; i < total; ++i) {
Expand All @@ -843,8 +849,8 @@ void MainWindow::handleTabChanged(const int index)
m_ActionUndo->setEnabled(false);
m_ActionFind->setEnabled(edit);
m_ActionReplace->setEnabled(edit);
m_ActionSave->setEnabled(edit);
m_ActionSaveAll->setEnabled(edit);
m_ActionSave->setEnabled(edit || hex);
m_ActionSaveAll->setEnabled(edit || hex);
m_ActionGoto->setEnabled(edit);
for (auto conn: m_EditorConnections) {
disconnect(conn);
Expand Down Expand Up @@ -875,14 +881,16 @@ void MainWindow::handleTabCloseRequested(const int index)
qDebug() << "User requested to close tab" << index;
#endif
QString path;
auto edit = dynamic_cast<SourceCodeEdit *>(m_TabEditors->widget(index));
auto widget = m_TabEditors->widget(index);
auto edit = dynamic_cast<SourceCodeEdit *>(widget);
auto hex = dynamic_cast<HexEdit *>(widget);
auto viewer = dynamic_cast<ImageViewerWidget *>(widget);
if (edit) {
path = edit->filePath();
} else {
auto viewer = dynamic_cast<ImageViewerWidget *>(m_TabEditors->widget(index));
if (viewer) {
path = viewer->filePath();
}
} else if (hex) {
path = hex->filePath();
} else if (viewer) {
path = viewer->filePath();
}
const int total = m_ModelOpenFiles->rowCount();
for (int i = 0; i < total; ++i) {
Expand Down Expand Up @@ -1031,10 +1039,14 @@ void MainWindow::openFile(const QString &path)
viewer->open(path);
viewer->zoomReset();
widget = viewer;
} else {
} else if (!extension.isEmpty() && QString(TEXT_EXTENSIONS).contains(extension, Qt::CaseInsensitive)) {
auto editor = new SourceCodeEdit(this);
editor->open(path);
widget = editor;
} else {
auto hex = new HexEdit(this);
hex->open(path);
widget = hex;
}
const QIcon icon = m_FileIconProvider.icon(info);
auto item = new QStandardItem(icon, info.fileName());
Expand Down Expand Up @@ -1116,9 +1128,15 @@ void MainWindow::reloadChildren(QTreeWidgetItem *item)

bool MainWindow::saveTab(int i)
{
auto edit = dynamic_cast<SourceCodeEdit *>(m_TabEditors->widget(i));
auto widget = m_TabEditors->widget(i);
auto edit = dynamic_cast<SourceCodeEdit *>(widget);
if (edit) {
return edit->save();
} else {
auto hex = dynamic_cast<HexEdit *>(widget);
if (hex) {
return hex->save();
}
}
return true;
}
Expand Down

1 comment on commit d94b7d8

@Emmricjordans
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey sap bro i need your help android studio failed to compile my source code to apk

Please sign in to comment.