mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 19:36:11 +00:00
Cutter RC Editor - Part B (basic editor) (#2162)
This commit is contained in:
parent
26cafecc4e
commit
1181f7ff5c
BIN
docs/source/images/InitializationScriptEditor.png
Normal file
BIN
docs/source/images/InitializationScriptEditor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
@ -13,4 +13,5 @@ Cutter is an advanced reverse engineering platform that is powered by radare2. T
|
||||
|
||||
user-docs/command-line
|
||||
user-docs/menus
|
||||
user-docs/preferences
|
||||
|
||||
|
11
docs/source/user-docs/preferences.rst
Normal file
11
docs/source/user-docs/preferences.rst
Normal file
@ -0,0 +1,11 @@
|
||||
Preferences
|
||||
=====================
|
||||
This part of the documentation will provide the reader with information about different preferences available.
|
||||
Preferences can be opened by clicking ``Edit -> Preferences``.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:glob:
|
||||
|
||||
preferences/initialization-script
|
||||
preferences/*
|
17
docs/source/user-docs/preferences/initialization-script.rst
Normal file
17
docs/source/user-docs/preferences/initialization-script.rst
Normal file
@ -0,0 +1,17 @@
|
||||
Initialization Script
|
||||
===================================
|
||||
|
||||
On the launch of Cutter, it loads ``.cutterrc`` files from various locations if they are present. The directories from where ``.cutterrc`` files are loaded are all directories of type ``QStandardPaths::AppConfigLocation``. These locations vary according to OS. You can visit `here <https://doc.qt.io/qt-5/qstandardpaths.html>`__ to see all the locations.
|
||||
|
||||
If multiple ``.cutterrc`` scripts are present in different directories, all of them will be loaded. In case of conflicting or contradictory commands, the corresponding command in the script loaded last will override all the previous commands. Cutter has a GUI editor for Initialization Script whose description is given below. The script from the editor will be the last loaded initialization script and hence will override all the previous scripts in the event of conflicting commands.
|
||||
|
||||
Initialization Script Editor
|
||||
-----------------------------------
|
||||
|
||||
.. image:: ../../images/InitializationScriptEditor.png
|
||||
:alt: Image of Initialization Script Editor
|
||||
|
||||
|
||||
**Description:** You can add new commands and modify existing commands here. To save the script, click on the ``Save`` button. If you want to see the changes you have made without restarting Cutter, you can use the ``Execute`` button. The hyperlink that shows the location of the script will open the directory containing the script on click.
|
||||
|
||||
**Steps to open:** ``Edit -> Preferences -> Initialization Script``
|
@ -344,6 +344,7 @@ SOURCES += \
|
||||
dialogs/preferences/AppearanceOptionsWidget.cpp \
|
||||
dialogs/preferences/GraphOptionsWidget.cpp \
|
||||
dialogs/preferences/PreferenceCategory.cpp \
|
||||
dialogs/preferences/InitializationFileEditor.cpp \
|
||||
widgets/QuickFilterView.cpp \
|
||||
widgets/ClassesWidget.cpp \
|
||||
widgets/ResourcesWidget.cpp \
|
||||
@ -484,6 +485,7 @@ HEADERS += \
|
||||
dialogs/preferences/AppearanceOptionsWidget.h \
|
||||
dialogs/preferences/PreferenceCategory.h \
|
||||
dialogs/preferences/GraphOptionsWidget.h \
|
||||
dialogs/preferences/InitializationFileEditor.h \
|
||||
widgets/QuickFilterView.h \
|
||||
widgets/ClassesWidget.h \
|
||||
widgets/ResourcesWidget.h \
|
||||
@ -598,6 +600,7 @@ FORMS += \
|
||||
dialogs/preferences/PreferencesDialog.ui \
|
||||
dialogs/preferences/AppearanceOptionsWidget.ui \
|
||||
dialogs/preferences/GraphOptionsWidget.ui \
|
||||
dialogs/preferences/InitializationFileEditor.ui \
|
||||
widgets/QuickFilterView.ui \
|
||||
widgets/DecompilerWidget.ui \
|
||||
widgets/ClassesWidget.ui \
|
||||
|
@ -240,34 +240,49 @@ RCoreLocked CutterCore::core()
|
||||
return RCoreLocked(this);
|
||||
}
|
||||
|
||||
QVector<QDir> CutterCore::getCutterRCDirectories() const
|
||||
QDir CutterCore::getCutterRCDefaultDirectory() const
|
||||
{
|
||||
QVector<QDir> result;
|
||||
result.push_back(QDir::home());
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
|
||||
}
|
||||
|
||||
QVector<QString> CutterCore::getCutterRCFilePaths() const
|
||||
{
|
||||
QVector<QString> result;
|
||||
result.push_back(QFileInfo(QDir::home(), ".cutterrc").absoluteFilePath());
|
||||
QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppConfigLocation);
|
||||
for (auto &location : locations) {
|
||||
result.push_back(QDir(location));
|
||||
result.push_back(QFileInfo(QDir(location), ".cutterrc").absoluteFilePath());
|
||||
}
|
||||
result.push_back(QFileInfo(getCutterRCDefaultDirectory(), "rc").absoluteFilePath()); // File in config editor is from this path
|
||||
return result;
|
||||
}
|
||||
|
||||
void CutterCore::loadCutterRC()
|
||||
{
|
||||
CORE_LOCK();
|
||||
|
||||
const auto result = getCutterRCDirectories();
|
||||
for(auto &dir : result){
|
||||
if(!dir.exists())continue;
|
||||
auto cutterRCFileInfo = QFileInfo(dir, ".cutterrc");
|
||||
auto path = cutterRCFileInfo.absoluteFilePath();
|
||||
if (!cutterRCFileInfo.isFile()) {
|
||||
const auto result = getCutterRCFilePaths();
|
||||
for(auto &cutterRCFilePath : result){
|
||||
auto cutterRCFileInfo = QFileInfo(cutterRCFilePath);
|
||||
if (!cutterRCFileInfo.exists() || !cutterRCFileInfo.isFile()) {
|
||||
continue;
|
||||
}
|
||||
qInfo() << "Loading initialization file from" << path;
|
||||
r_core_cmd_file(core, path.toUtf8().constData());
|
||||
qInfo() << "Loading initialization file from " << cutterRCFilePath;
|
||||
r_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void CutterCore::loadDefaultCutterRC()
|
||||
{
|
||||
CORE_LOCK();
|
||||
auto cutterRCFilePath = QFileInfo(getCutterRCDefaultDirectory(), "rc").absoluteFilePath();
|
||||
const auto cutterRCFileInfo = QFileInfo(cutterRCFilePath);
|
||||
if (!cutterRCFileInfo.exists() || !cutterRCFileInfo.isFile()) {
|
||||
return;
|
||||
}
|
||||
qInfo() << "Loading initialization file from " << cutterRCFilePath;
|
||||
r_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
|
||||
}
|
||||
|
||||
|
||||
QList<QString> CutterCore::sdbList(QString path)
|
||||
{
|
||||
|
@ -46,7 +46,9 @@ public:
|
||||
|
||||
void initialize(bool loadPlugins = true);
|
||||
void loadCutterRC();
|
||||
|
||||
void loadDefaultCutterRC();
|
||||
QDir getCutterRCDefaultDirectory() const;
|
||||
|
||||
AsyncTaskManager *getAsyncTaskManager() { return asyncTaskManager; }
|
||||
|
||||
RVA getOffset() const { return core_->offset; }
|
||||
@ -710,7 +712,7 @@ private:
|
||||
QSharedPointer<R2Task> debugTask;
|
||||
R2TaskDialog *debugTaskDialog;
|
||||
|
||||
QVector<QDir> getCutterRCDirectories() const;
|
||||
QVector<QString> getCutterRCFilePaths() const;
|
||||
};
|
||||
|
||||
class RCoreLocked
|
||||
|
72
src/dialogs/preferences/InitializationFileEditor.cpp
Normal file
72
src/dialogs/preferences/InitializationFileEditor.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include <QLabel>
|
||||
#include <QFontDialog>
|
||||
#include <QTextEdit>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QUrl>
|
||||
|
||||
#include "InitializationFileEditor.h"
|
||||
#include "ui_InitializationFileEditor.h"
|
||||
|
||||
#include "PreferencesDialog.h"
|
||||
|
||||
#include "common/Helpers.h"
|
||||
#include "common/Configuration.h"
|
||||
|
||||
InitializationFileEditor::InitializationFileEditor(PreferencesDialog *dialog)
|
||||
: QDialog(dialog),
|
||||
ui(new Ui::InitializationFileEditor)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(ui->saveRC, &QDialogButtonBox::accepted, this, &InitializationFileEditor::saveCutterRC);
|
||||
connect(ui->executeNow, &QDialogButtonBox::accepted, this, &InitializationFileEditor::executeCutterRC);
|
||||
connect(ui->ConfigFileEdit, &QPlainTextEdit::modificationChanged, ui->saveRC, &QWidget::setEnabled);
|
||||
|
||||
const QDir cutterRCDirectory = Core()->getCutterRCDefaultDirectory();
|
||||
auto cutterRCFileInfo = QFileInfo(cutterRCDirectory, "rc");
|
||||
QString cutterRCLocation = cutterRCFileInfo.absoluteFilePath();
|
||||
|
||||
ui->cutterRCLoaded->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
ui->cutterRCLoaded->setOpenExternalLinks(true);
|
||||
ui->cutterRCLoaded->setText(tr("Script is loaded from <a href=\"%1\">%2</a>")
|
||||
.arg(QUrl::fromLocalFile(cutterRCDirectory.absolutePath()).toString(), cutterRCLocation.toHtmlEscaped()));
|
||||
|
||||
ui->executeNow->button(QDialogButtonBox::Retry)->setText("Execute");
|
||||
ui->ConfigFileEdit->clear();
|
||||
if(cutterRCFileInfo.exists()){
|
||||
QFile cutterRC(cutterRCLocation);
|
||||
if(cutterRC.open(QIODevice::ReadWrite | QIODevice::Text)){
|
||||
ui->ConfigFileEdit->setPlainText(cutterRC.readAll());
|
||||
}
|
||||
cutterRC.close();
|
||||
}
|
||||
ui->saveRC->setDisabled(true);
|
||||
}
|
||||
|
||||
InitializationFileEditor::~InitializationFileEditor() {};
|
||||
|
||||
|
||||
void InitializationFileEditor::saveCutterRC(){
|
||||
const QDir cutterRCDirectory = Core()->getCutterRCDefaultDirectory();
|
||||
if(!cutterRCDirectory.exists()){
|
||||
cutterRCDirectory.mkpath(".");
|
||||
}
|
||||
auto cutterRCFileInfo = QFileInfo(cutterRCDirectory, "rc");
|
||||
QString cutterRCLocation = cutterRCFileInfo.absoluteFilePath();
|
||||
|
||||
QFile cutterRC(cutterRCLocation);
|
||||
if(cutterRC.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)){
|
||||
QTextStream out(&cutterRC);
|
||||
QString text = ui->ConfigFileEdit->toPlainText();
|
||||
out << text;
|
||||
cutterRC.close();
|
||||
}
|
||||
ui->ConfigFileEdit->document()->setModified(false);
|
||||
}
|
||||
|
||||
void InitializationFileEditor::executeCutterRC(){
|
||||
saveCutterRC();
|
||||
Core()->loadDefaultCutterRC();
|
||||
}
|
31
src/dialogs/preferences/InitializationFileEditor.h
Normal file
31
src/dialogs/preferences/InitializationFileEditor.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef INITIALIZATIONFILEEDITOR_H
|
||||
#define INITIALIZATIONFILEEDITOR_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QPushButton>
|
||||
#include <memory>
|
||||
#include "core/Cutter.h"
|
||||
|
||||
class PreferencesDialog;
|
||||
|
||||
namespace Ui {
|
||||
class InitializationFileEditor;
|
||||
}
|
||||
|
||||
class InitializationFileEditor : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InitializationFileEditor(PreferencesDialog *dialog);
|
||||
~InitializationFileEditor();
|
||||
void saveCutterRC();
|
||||
void executeCutterRC();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::InitializationFileEditor> ui;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //INITIALIZATIONFILEEDITOR_H
|
54
src/dialogs/preferences/InitializationFileEditor.ui
Normal file
54
src/dialogs/preferences/InitializationFileEditor.ui
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>InitializationFileEditor</class>
|
||||
<widget class="QWidget" name="InitializationFileEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>667</width>
|
||||
<height>486</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>CutterRC Editor</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="cutterRCLoaded">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QDialogButtonBox" name="saveRC">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>649</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QPlainTextEdit" name="ConfigFileEdit"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDialogButtonBox" name="executeNow">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Retry</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -6,6 +6,7 @@
|
||||
#include "GraphOptionsWidget.h"
|
||||
#include "DebugOptionsWidget.h"
|
||||
#include "PluginsOptionsWidget.h"
|
||||
#include "InitializationFileEditor.h"
|
||||
|
||||
#include "PreferenceCategory.h"
|
||||
|
||||
@ -51,6 +52,11 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
|
||||
tr("Plugins"),
|
||||
new PluginsOptionsWidget(this),
|
||||
QIcon(":/img/icons/plugins.svg")
|
||||
},
|
||||
{
|
||||
tr("Initialization Script"),
|
||||
new InitializationFileEditor(this),
|
||||
QIcon(":/img/icons/initialization.svg")
|
||||
}
|
||||
};
|
||||
|
||||
@ -114,6 +120,7 @@ void PreferencesDialog::chooseThemeIcons()
|
||||
{ QStringLiteral("Graph"), QStringLiteral("graph.svg") },
|
||||
{ QStringLiteral("Appearance"), QStringLiteral("polar.svg") },
|
||||
{ QStringLiteral("Plugins"), QStringLiteral("plugins.svg") },
|
||||
{ QStringLiteral("Initialization Script"), QStringLiteral("initialization.svg") },
|
||||
};
|
||||
QList<QPair<void*, QString>> supportedIconsNames;
|
||||
|
||||
|
99
src/img/icons/initialization.svg
Normal file
99
src/img/icons/initialization.svg
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="528.899px"
|
||||
height="528.899px"
|
||||
viewBox="0 0 528.899 528.899"
|
||||
style="enable-background:new 0 0 528.899 528.899;"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="pencil_thin.svg"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"><metadata
|
||||
id="metadata41"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs39" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1044"
|
||||
id="namedview37"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.2620724"
|
||||
inkscape:cx="101.91659"
|
||||
inkscape:cy="301.06573"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="36"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" />
|
||||
<g
|
||||
id="g4"
|
||||
style="fill:#aaacaf">
|
||||
<path
|
||||
d="M328.883,89.125l107.59,107.589l-272.34,272.34L56.604,361.465L328.883,89.125z M518.113,63.177l-47.981-47.981 c-18.543-18.543-48.653-18.543-67.259,0l-45.961,45.961l107.59,107.59l53.611-53.611 C532.495,100.753,532.495,77.559,518.113,63.177z M0.3,512.69c-1.958,8.812,5.998,16.708,14.811,14.565l119.891-29.069 L27.473,390.597L0.3,512.69z"
|
||||
id="path2"
|
||||
style="fill:#aaacaf" />
|
||||
</g>
|
||||
<g
|
||||
id="g6">
|
||||
</g>
|
||||
<g
|
||||
id="g8">
|
||||
</g>
|
||||
<g
|
||||
id="g10">
|
||||
</g>
|
||||
<g
|
||||
id="g12">
|
||||
</g>
|
||||
<g
|
||||
id="g14">
|
||||
</g>
|
||||
<g
|
||||
id="g16">
|
||||
</g>
|
||||
<g
|
||||
id="g18">
|
||||
</g>
|
||||
<g
|
||||
id="g20">
|
||||
</g>
|
||||
<g
|
||||
id="g22">
|
||||
</g>
|
||||
<g
|
||||
id="g24">
|
||||
</g>
|
||||
<g
|
||||
id="g26">
|
||||
</g>
|
||||
<g
|
||||
id="g28">
|
||||
</g>
|
||||
<g
|
||||
id="g30">
|
||||
</g>
|
||||
<g
|
||||
id="g32">
|
||||
</g>
|
||||
<g
|
||||
id="g34">
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
99
src/img/icons/light/initialization.svg
Normal file
99
src/img/icons/light/initialization.svg
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="528.899px"
|
||||
height="528.899px"
|
||||
viewBox="0 0 528.899 528.899"
|
||||
style="enable-background:new 0 0 528.899 528.899;"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="pencil_thin.svg"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"><metadata
|
||||
id="metadata41"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs39" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1044"
|
||||
id="namedview37"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.2620724"
|
||||
inkscape:cx="101.91659"
|
||||
inkscape:cy="301.06573"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="36"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" />
|
||||
<g
|
||||
id="g4"
|
||||
style="fill:#039be5">
|
||||
<path
|
||||
d="M328.883,89.125l107.59,107.589l-272.34,272.34L56.604,361.465L328.883,89.125z M518.113,63.177l-47.981-47.981 c-18.543-18.543-48.653-18.543-67.259,0l-45.961,45.961l107.59,107.59l53.611-53.611 C532.495,100.753,532.495,77.559,518.113,63.177z M0.3,512.69c-1.958,8.812,5.998,16.708,14.811,14.565l119.891-29.069 L27.473,390.597L0.3,512.69z"
|
||||
id="path2"
|
||||
style="fill:#039be5" />
|
||||
</g>
|
||||
<g
|
||||
id="g6">
|
||||
</g>
|
||||
<g
|
||||
id="g8">
|
||||
</g>
|
||||
<g
|
||||
id="g10">
|
||||
</g>
|
||||
<g
|
||||
id="g12">
|
||||
</g>
|
||||
<g
|
||||
id="g14">
|
||||
</g>
|
||||
<g
|
||||
id="g16">
|
||||
</g>
|
||||
<g
|
||||
id="g18">
|
||||
</g>
|
||||
<g
|
||||
id="g20">
|
||||
</g>
|
||||
<g
|
||||
id="g22">
|
||||
</g>
|
||||
<g
|
||||
id="g24">
|
||||
</g>
|
||||
<g
|
||||
id="g26">
|
||||
</g>
|
||||
<g
|
||||
id="g28">
|
||||
</g>
|
||||
<g
|
||||
id="g30">
|
||||
</g>
|
||||
<g
|
||||
id="g32">
|
||||
</g>
|
||||
<g
|
||||
id="g34">
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -56,6 +56,8 @@
|
||||
<file>img/icons/graph_white.svg</file>
|
||||
<file>img/icons/graph.svg</file>
|
||||
<file>img/icons/light/graph.svg</file>
|
||||
<file>img/icons/initialization.svg</file>
|
||||
<file>img/icons/light/initialization.svg</file>
|
||||
<file>img/icons/hexdump_light.svg</file>
|
||||
<file>img/icons/hexdump_white.svg</file>
|
||||
<file>img/icons/bug.svg</file>
|
||||
|
Loading…
Reference in New Issue
Block a user