Projects Management (#66)

* Add TabWidget to NewFileDialog
* Project loading from NewFileDialog
* Projects dir in NewFileDialog
* Add SaveProjectDialog
* Make SaveProjectDialog work, refactor project saving and Notepad
* Add shortcut for Save
* Fix notes loading
* Sort projects in NewFileDialog
* Implement selecting projects dir in SaveProjectDialog
* Fix QAbstractButton include
This commit is contained in:
Florian Märkl 2017-10-21 21:20:10 +02:00 committed by xarkes
parent ae9df7ed5b
commit c73d9a0678
17 changed files with 947 additions and 351 deletions

View File

@ -61,6 +61,7 @@
#include "dialogs/OptionsDialog.h" #include "dialogs/OptionsDialog.h"
#include "widgets/EntrypointWidget.h" #include "widgets/EntrypointWidget.h"
#include "widgets/DisassemblerGraphView.h" #include "widgets/DisassemblerGraphView.h"
#include "dialogs/SaveProjectDialog.h"
// graphics // graphics
#include <QGraphicsEllipseItem> #include <QGraphicsEllipseItem>
@ -298,16 +299,8 @@ void MainWindow::initUI()
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this); QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this);
connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshVisibleDockWidgets())); connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshVisibleDockWidgets()));
}
void MainWindow::openFile(const QString &fn, int anal_level, QList<QString> advanced) connect(core, SIGNAL(projectSaved(const QString &)), this, SLOT(projectSaved(const QString &)));
{
QString project_name = qhelpers::uniqueProjectName(fn);
if (core->getProjectNames().contains(project_name))
openProject(project_name);
else
openNewFile(fn, anal_level, advanced);
} }
void MainWindow::openNewFile(const QString &fn, int anal_level, QList<QString> advanced) void MainWindow::openNewFile(const QString &fn, int anal_level, QList<QString> advanced)
@ -327,7 +320,7 @@ void MainWindow::openProject(const QString &project_name)
QString filename = core->cmd("Pi " + project_name); QString filename = core->cmd("Pi " + project_name);
setFilename(filename.trimmed()); setFilename(filename.trimmed());
core->cmd("Po " + project_name); core->openProject(project_name);
initUI(); initUI();
finalizeOpen(); finalizeOpen();
@ -347,20 +340,9 @@ void MainWindow::finalizeOpen()
core->cmd("fs sections"); core->cmd("fs sections");
updateFrames(); updateFrames();
// Restore project notes if(core->getNotes().isEmpty())
QString notes = this->core->cmd("Pnj");
//qDebug() << "Notes:" << notes;
if (notes != "")
{ {
QByteArray ba; core->setNotes(tr("# Binary information\n\n") + core->cmd("i") +
ba.append(notes);
notepadDock->setText(QByteArray::fromBase64(ba));
}
else
{
addOutput(tr(" > Adding binary information to notepad"));
notepadDock->setText(tr("# Binary information\n\n") + core->cmd("i") +
"\n" + core->cmd("ie") + "\n" + core->cmd("iM") + "\n"); "\n" + core->cmd("ie") + "\n" + core->cmd("iM") + "\n");
} }
@ -377,14 +359,27 @@ void MainWindow::finalizeOpen()
notepadDock->highlightPreview(); notepadDock->highlightPreview();
} }
void MainWindow::saveProject() bool MainWindow::saveProject(bool quit)
{ {
QString project_name = qhelpers::uniqueProjectName(filename); QString projectName = core->getConfig("prj.name");
core->cmd("Ps " + project_name); if (projectName.isEmpty())
QString notes = this->notepadDock->textToBase64(); {
//this->add_debug_output(notes); return saveProjectAs(quit);
this->core->cmd("Pnj " + notes); }
this->addOutput(tr("Project saved: ") + project_name); else
{
core->saveProject(projectName);
return true;
}
}
bool MainWindow::saveProjectAs(bool quit)
{
SaveProjectDialog dialog(quit, this);
int result = dialog.exec();
return !quit || result != SaveProjectDialog::Rejected;
} }
void MainWindow::toggleSideBarTheme() void MainWindow::toggleSideBarTheme()
@ -411,15 +406,21 @@ void MainWindow::closeEvent(QCloseEvent *event)
(QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel)); (QMessageBox::StandardButtons)(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel));
//qDebug() << ret; //qDebug() << ret;
if (ret == QMessageBox::Save) if (ret == QMessageBox::Save)
{
if(saveProject(true))
{ {
QSettings settings; QSettings settings;
settings.setValue("geometry", saveGeometry()); settings.setValue("geometry", saveGeometry());
settings.setValue("size", size()); settings.setValue("size", size());
settings.setValue("pos", pos()); settings.setValue("pos", pos());
settings.setValue("state", saveState()); settings.setValue("state", saveState());
saveProject();
QMainWindow::closeEvent(event); QMainWindow::closeEvent(event);
} }
else
{
event->ignore();
}
}
else if (ret == QMessageBox::Discard) else if (ret == QMessageBox::Discard)
{ {
QSettings settings; QSettings settings;
@ -670,7 +671,7 @@ void MainWindow::on_actionRefresh_Panels_triggered()
this->updateFrames(); this->updateFrames();
} }
void MainWindow::toggleDockWidget(DockWidget *dock_widget) void MainWindow::toggleDockWidget(QDockWidget *dock_widget)
{ {
if (dock_widget->isVisible()) if (dock_widget->isVisible())
{ {
@ -808,7 +809,7 @@ void MainWindow::on_actionhide_bottomPannel_triggered()
void MainWindow::sendToNotepad(const QString &txt) void MainWindow::sendToNotepad(const QString &txt)
{ {
this->notepadDock->appendPlainText("```\n" + txt + "\n```"); core->setNotes(core->getNotes() + "```\n" + txt + "\n```");
} }
void MainWindow::on_actionFunctionsRename_triggered() void MainWindow::on_actionFunctionsRename_triggered()
@ -841,6 +842,11 @@ void MainWindow::on_actionSave_triggered()
saveProject(); saveProject();
} }
void MainWindow::on_actionSaveAs_triggered()
{
saveProjectAs();
}
void MainWindow::on_actionRun_Script_triggered() void MainWindow::on_actionRun_Script_triggered()
{ {
QFileDialog dialog(this); QFileDialog dialog(this);
@ -970,3 +976,8 @@ void MainWindow::on_actionAsmOptions_triggered()
auto dialog = new AsmOptionsDialog(this); auto dialog = new AsmOptionsDialog(this);
dialog->show(); dialog->show();
} }
void MainWindow::projectSaved(const QString &name)
{
this->addOutput(tr("Project saved: ") + name);
}

View File

@ -53,11 +53,23 @@ public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = 0);
~MainWindow(); ~MainWindow();
void openFile(const QString &fn, int anal_level = -1, QList<QString> advanced = QList<QString>()); void openNewFile(const QString &fn, int anal_level = -1, QList<QString> advanced = QList<QString>());
void openProject(const QString &project_name);
void initUI(); void initUI();
void finalizeOpen(); void finalizeOpen();
void saveProject(); /*!
* @param quit whether to show destructive button in dialog
* @return if quit is true, false if the application should not close
*/
bool saveProject(bool quit = false);
/*!
* @param quit whether to show destructive button in dialog
* @return if quit is true, false if the application should not close
*/
bool saveProjectAs(bool quit = false);
void start_web_server(); void start_web_server();
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
@ -144,6 +156,7 @@ private slots:
void on_actionNew_triggered(); void on_actionNew_triggered();
void on_actionSave_triggered(); void on_actionSave_triggered();
void on_actionSaveAs_triggered();
void on_actionWhite_Theme_triggered(); void on_actionWhite_Theme_triggered();
@ -165,6 +178,8 @@ private slots:
void on_actionAsmOptions_triggered(); void on_actionAsmOptions_triggered();
void projectSaved(const QString &name);
private: private:
CutterCore *core; CutterCore *core;
DisassemblyWidget *disassemblyDock; DisassemblyWidget *disassemblyDock;
@ -206,10 +221,7 @@ private:
SectionsDock *sectionsDock; SectionsDock *sectionsDock;
ConsoleWidget *consoleWidget; ConsoleWidget *consoleWidget;
void openProject(const QString &project_name); void toggleDockWidget(QDockWidget *dock_widget);
void openNewFile(const QString &fn, int anal_level, QList<QString> advanced);
void toggleDockWidget(DockWidget *dock_widget);
public: public:
RVA getCursorAddress() const { return cursorAddress; } RVA getCursorAddress() const { return cursorAddress; }

View File

@ -174,7 +174,7 @@ border-top: 0px;
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1013</width> <width>1013</width>
<height>20</height> <height>22</height>
</rect> </rect>
</property> </property>
<property name="defaultUp"> <property name="defaultUp">
@ -186,10 +186,10 @@ border-top: 0px;
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>273</x> <x>419</x>
<y>136</y> <y>265</y>
<width>148</width> <width>173</width>
<height>167</height> <height>206</height>
</rect> </rect>
</property> </property>
<property name="title"> <property name="title">
@ -199,6 +199,7 @@ border-top: 0px;
<addaction name="actionLoad"/> <addaction name="actionLoad"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionSave"/> <addaction name="actionSave"/>
<addaction name="actionSaveAs"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionRun_Script"/> <addaction name="actionRun_Script"/>
<addaction name="separator"/> <addaction name="separator"/>
@ -419,6 +420,9 @@ QToolButton .svg-icon path {
<property name="text"> <property name="text">
<string>Save</string> <string>Save</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action> </action>
<action name="actionUndo"> <action name="actionUndo">
<property name="text"> <property name="text">
@ -979,6 +983,11 @@ QToolButton .svg-icon path {
<string>Disassembly Options</string> <string>Disassembly Options</string>
</property> </property>
</action> </action>
<action name="actionSaveAs">
<property name="text">
<string>Save As...</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>

View File

@ -46,7 +46,6 @@ CutterCore::CutterCore(QObject *parent) :
QObject(parent) QObject(parent)
{ {
r_cons_new(); // initialize console r_cons_new(); // initialize console
this->projectPath = "";
this->core_ = r_core_new(); this->core_ = r_core_new();
r_core_loadlibs(this->core_, R_CORE_LOADLIBS_ALL, NULL); r_core_loadlibs(this->core_, R_CORE_LOADLIBS_ALL, NULL);
// IMPLICIT r_bin_iobind (core_->bin, core_->io); // IMPLICIT r_bin_iobind (core_->bin, core_->io);
@ -1219,3 +1218,31 @@ void CutterCore::loadPDB(const QString &file)
{ {
cmd("idp " + sanitizeStringForCommand(file)); cmd("idp " + sanitizeStringForCommand(file));
} }
void CutterCore::openProject(const QString &name)
{
cmd("Po " + name);
QString notes = QString::fromUtf8(QByteArray::fromBase64(cmd("Pnj").toUtf8()));
setNotes(notes);
}
void CutterCore::saveProject(const QString &name)
{
cmd("Ps " + name);
cmd("Pnj " + notes.toUtf8().toBase64());
emit projectSaved(name);
}
bool CutterCore::isProjectNameValid(const QString &name)
{
// see is_valid_project_name() in libr/core/project.c
static const QRegExp regexp(R"(^[a-zA-Z0-9\\\._:-]{1,}$)");
return regexp.exactMatch(name) && !name.endsWith(".zip") ;
}
void CutterCore::setNotes(const QString &notes)
{
this->notes = notes;
emit notesChanged(this->notes);
}

View File

@ -184,8 +184,6 @@ class CutterCore: public QObject
friend class ccClass; friend class ccClass;
public: public:
QString projectPath;
explicit CutterCore(QObject *parent = 0); explicit CutterCore(QObject *parent = 0);
~CutterCore(); ~CutterCore();
static CutterCore* getInstance(); static CutterCore* getInstance();
@ -267,6 +265,13 @@ public:
QStringList getAnalPluginNames(); QStringList getAnalPluginNames();
QStringList getProjectNames(); QStringList getProjectNames();
void openProject(const QString &name);
void saveProject(const QString &name);
static bool isProjectNameValid(const QString &name);
const QString &getNotes() const { return notes; }
void setNotes(const QString &notes);
QList<RBinPluginDescription> getRBinPluginDescriptions(const QString &type = nullptr); QList<RBinPluginDescription> getRBinPluginDescriptions(const QString &type = nullptr);
@ -303,6 +308,9 @@ signals:
void flagsChanged(); void flagsChanged();
void commentsChanged(); void commentsChanged();
void notesChanged(const QString &notes);
void projectSaved(const QString &name);
/*! /*!
* emitted when config regarding disassembly display changes * emitted when config regarding disassembly display changes
*/ */
@ -321,6 +329,8 @@ private:
QString default_cpu; QString default_cpu;
int default_bits; int default_bits;
QString notes;
RCore *core_; RCore *core_;
}; };

View File

@ -77,7 +77,8 @@ SOURCES += \
widgets/SidebarWidget.cpp \ widgets/SidebarWidget.cpp \
widgets/HexdumpWidget.cpp \ widgets/HexdumpWidget.cpp \
utils/Configuration.cpp \ utils/Configuration.cpp \
utils/Colors.cpp utils/Colors.cpp \
dialogs/SaveProjectDialog.cpp
HEADERS += \ HEADERS += \
cutter.h \ cutter.h \
@ -126,7 +127,8 @@ HEADERS += \
widgets/SidebarWidget.h \ widgets/SidebarWidget.h \
widgets/HexdumpWidget.h \ widgets/HexdumpWidget.h \
utils/Configuration.h \ utils/Configuration.h \
utils/Colors.h utils/Colors.h \
dialogs/SaveProjectDialog.h
FORMS += \ FORMS += \
widgets/PreviewWidget.ui \ widgets/PreviewWidget.ui \
@ -156,7 +158,8 @@ FORMS += \
widgets/StringsWidget.ui \ widgets/StringsWidget.ui \
widgets/SymbolsWidget.ui \ widgets/SymbolsWidget.ui \
widgets/SidebarWidget.ui \ widgets/SidebarWidget.ui \
widgets/HexdumpWidget.ui widgets/HexdumpWidget.ui \
dialogs/SaveProjectDialog.ui
RESOURCES += \ RESOURCES += \
resources.qrc resources.qrc

View File

@ -64,10 +64,152 @@ NewFileDialog::NewFileDialog(QWidget *parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
ui->recentsList->addAction(ui->actionRemove_item); ui->recentsListWidget->addAction(ui->actionRemove_item);
ui->recentsList->addAction(ui->actionClear_all); ui->recentsListWidget->addAction(ui->actionClear_all);
ui->recentsList->setIconSize(QSize(48, 48));
fillRecentFilesList();
bool projectsExist = fillProjectsList();
if(projectsExist)
{
ui->tabWidget->setCurrentWidget(ui->projectsTab);
}
else
{
ui->tabWidget->setCurrentWidget(ui->filesTab);
}
// Hide "create" button until the dialog works
ui->createButton->hide();
ui->loadProjectButton->setEnabled(ui->projectsListWidget->currentItem() != nullptr);
}
NewFileDialog::~NewFileDialog() {}
void NewFileDialog::on_loadFileButton_clicked()
{
loadFile(ui->newFileEdit->text());
}
void NewFileDialog::on_selectFileButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select file"), QDir::homePath());
if (!fileName.isEmpty())
{
ui->newFileEdit->setText(fileName);
ui->loadFileButton->setFocus();
}
}
void NewFileDialog::on_selectProjectsDirButton_clicked()
{
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::DirectoryOnly);
QString currentDir = CutterCore::getInstance()->getConfig("dir.projects");
if(currentDir.startsWith("~"))
{
currentDir = QDir::homePath() + currentDir.mid(1);
}
dialog.setDirectory(currentDir);
dialog.setWindowTitle(tr("Select project path (dir.projects)"));
if(!dialog.exec())
{
return;
}
QString dir = dialog.selectedFiles().first();
if (!dir.isEmpty())
{
CutterCore::getInstance()->setConfig("dir.projects", dir);
fillProjectsList();
}
}
void NewFileDialog::on_loadProjectButton_clicked()
{
QListWidgetItem *item = ui->projectsListWidget->currentItem();
if (item == nullptr)
{
return;
}
loadProject(item->data(Qt::UserRole).toString());
}
void NewFileDialog::on_recentsListWidget_itemClicked(QListWidgetItem *item)
{
QVariant data = item->data(Qt::UserRole);
QString sitem = data.toString();
ui->newFileEdit->setText(sitem);
}
void NewFileDialog::on_recentsListWidget_itemDoubleClicked(QListWidgetItem *item)
{
loadFile(item->data(Qt::UserRole).toString());
}
void NewFileDialog::on_projectsListWidget_itemSelectionChanged()
{
ui->loadProjectButton->setEnabled(ui->projectsListWidget->currentItem() != nullptr);
}
void NewFileDialog::on_projectsListWidget_itemDoubleClicked(QListWidgetItem *item)
{
loadProject(item->data(Qt::UserRole).toString());
}
void NewFileDialog::on_cancelButton_clicked()
{
close();
}
void NewFileDialog::on_actionRemove_item_triggered()
{
// Remove selected item from recents list
QListWidgetItem *item = ui->recentsListWidget->currentItem();
QVariant data = item->data(Qt::UserRole);
QString sitem = data.toString();
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
files.removeAll(sitem);
settings.setValue("recentFileList", files);
ui->recentsListWidget->takeItem(ui->recentsListWidget->currentRow());
ui->newFileEdit->clear();
}
void NewFileDialog::on_createButton_clicked()
{
// Close dialog and open create new file dialog
close();
CreateNewDialog *n = new CreateNewDialog(nullptr);
n->exec();
}
void NewFileDialog::on_actionClear_all_triggered()
{
// Clear recent file list
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
files.clear();
ui->recentsListWidget->clear();
// TODO: if called from main window its ok, otherwise its not
settings.setValue("recentFileList", files);
ui->newFileEdit->clear();
}
bool NewFileDialog::fillRecentFilesList()
{
// Fill list with recent opened files // Fill list with recent opened files
QSettings settings; QSettings settings;
@ -99,25 +241,45 @@ NewFileDialog::NewFileDialog(QWidget *parent) :
); );
//":/img/icons/target.svg"), name ); //":/img/icons/target.svg"), name );
item->setData(Qt::UserRole, file); item->setData(Qt::UserRole, file);
ui->recentsList->addItem(item); ui->recentsListWidget->addItem(item);
} }
} }
ui->recentsList->setSortingEnabled(true);
// Hide "create" button until the dialog works // Removed files were deleted from the stringlist. Save it again.
ui->createButton->hide();
// Removes files were deleted from the stringlist. Save it again.
settings.setValue("recentFileList", files); settings.setValue("recentFileList", files);
return !files.isEmpty();
} }
NewFileDialog::~NewFileDialog() {} bool NewFileDialog::fillProjectsList()
{
CutterCore *core = CutterCore::getInstance();
void NewFileDialog::on_loadFileButton_clicked() ui->projectsDirEdit->setText(core->getConfig("dir.projects"));
QStringList projects = core->getProjectNames();
projects.sort(Qt::CaseInsensitive);
ui->projectsListWidget->clear();
int i=0;
for(const QString &project : projects)
{
QString info = core->cmd("Pi " + project);
QListWidgetItem *item = new QListWidgetItem(getIconFor(project, i++), project + "\n" + info);
item->setData(Qt::UserRole, project);
ui->projectsListWidget->addItem(item);
}
return !projects.isEmpty();
}
void NewFileDialog::loadFile(const QString &filename)
{ {
// Check that there is a file selected // Check that there is a file selected
QString fname = ui->newFileEdit->text(); QFileInfo checkfile(filename);
QFileInfo checkfile(fname);
if (!checkfile.exists() || !checkfile.isFile()) if (!checkfile.exists() || !checkfile.isFile())
{ {
QMessageBox msgBox(this); QMessageBox msgBox(this);
@ -129,8 +291,8 @@ void NewFileDialog::on_loadFileButton_clicked()
// Add file to recent file list // Add file to recent file list
QSettings settings; QSettings settings;
QStringList files = settings.value("recentFileList").toStringList(); QStringList files = settings.value("recentFileList").toStringList();
files.removeAll(fname); files.removeAll(filename);
files.prepend(fname); files.prepend(filename);
while (files.size() > MaxRecentFiles) while (files.size() > MaxRecentFiles)
files.removeLast(); files.removeLast();
@ -140,90 +302,16 @@ void NewFileDialog::on_loadFileButton_clicked()
// Close dialog and open MainWindow/OptionsDialog // Close dialog and open MainWindow/OptionsDialog
MainWindow *main = new MainWindow(); MainWindow *main = new MainWindow();
main->openFile(fname); main->openNewFile(filename);
//OptionsDialog *o = new OptionsDialog(fname); //OptionsDialog *o = new OptionsDialog(fname);
//o->exec(); //o->exec();
} }
} }
void NewFileDialog::on_newFileButton_clicked() void NewFileDialog::loadProject(const QString &project)
{ {
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setViewMode(QFileDialog::Detail);
dialog.setDirectory(QDir::home());
QString fileName;
fileName = dialog.getOpenFileName(this, tr("Select file"));
if (!fileName.isEmpty())
{
ui->newFileEdit->setText(fileName);
ui->loadFileButton->setFocus();
}
}
void NewFileDialog::on_recentsList_itemClicked(QListWidgetItem *item)
{
QVariant data = item->data(Qt::UserRole);
QString sitem = data.toString();
ui->newFileEdit->setText(sitem);
}
void NewFileDialog::on_recentsList_itemDoubleClicked(QListWidgetItem *item)
{
// Get selected item to send to options dialog
QVariant data = item->data(Qt::UserRole);
QString sitem = data.toString();
// Close dialog and open OptionsDialog
close(); close();
MainWindow *main = new MainWindow(); MainWindow *main = new MainWindow();
main->openFile(sitem); main->openProject(project);
//OptionsDialog *o = new OptionsDialog(sitem);
//o->exec();
}
void NewFileDialog::on_cancelButton_clicked()
{
close();
}
void NewFileDialog::on_actionRemove_item_triggered()
{
// Remove selected item from recents list
QListWidgetItem *item = ui->recentsList->currentItem();
QVariant data = item->data(Qt::UserRole);
QString sitem = data.toString();
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
files.removeAll(sitem);
settings.setValue("recentFileList", files);
ui->recentsList->takeItem(ui->recentsList->currentRow());
ui->newFileEdit->clear();
}
void NewFileDialog::on_createButton_clicked()
{
// Close dialog and open create new file dialog
close();
CreateNewDialog *n = new CreateNewDialog(nullptr);
n->exec();
}
void NewFileDialog::on_actionClear_all_triggered()
{
// Clear recent file list
QSettings settings;
QStringList files = settings.value("recentFileList").toStringList();
files.clear();
ui->recentsList->clear();
// TODO: if called from main window its ok, otherwise its not
settings.setValue("recentFileList", files);
ui->newFileEdit->clear();
} }

View File

@ -19,26 +19,40 @@ public:
~NewFileDialog(); ~NewFileDialog();
private slots: private slots:
void on_loadFileButton_clicked(); void on_loadFileButton_clicked();
void on_selectFileButton_clicked();
void on_createButton_clicked();
void on_newFileButton_clicked(); void on_selectProjectsDirButton_clicked();
void on_loadProjectButton_clicked();
void on_recentsList_itemClicked(QListWidgetItem *item);
void on_recentsList_itemDoubleClicked(QListWidgetItem *item);
void on_cancelButton_clicked(); void on_cancelButton_clicked();
void on_recentsListWidget_itemClicked(QListWidgetItem *item);
void on_recentsListWidget_itemDoubleClicked(QListWidgetItem *item);
void on_projectsListWidget_itemSelectionChanged();
void on_projectsListWidget_itemDoubleClicked(QListWidgetItem *item);
void on_actionRemove_item_triggered(); void on_actionRemove_item_triggered();
void on_createButton_clicked();
void on_actionClear_all_triggered(); void on_actionClear_all_triggered();
private: private:
std::unique_ptr<Ui::NewFileDialog> ui; std::unique_ptr<Ui::NewFileDialog> ui;
/*!
* @return true if list is not empty
*/
bool fillRecentFilesList();
/*!
* @return true if list is not empty
*/
bool fillProjectsList();
void loadFile(const QString &filename);
void loadProject(const QString &project);
static const int MaxRecentFiles = 5; static const int MaxRecentFiles = 5;
}; };

View File

@ -6,15 +6,15 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>452</width>
<height>450</height> <height>532</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Open File</string> <string>Open File</string>
</property> </property>
<property name="windowIcon"> <property name="windowIcon">
<iconset resource="resources.qrc"> <iconset>
<normaloff>:/img/logo-small.png</normaloff>:/img/logo-small.png</iconset> <normaloff>:/img/logo-small.png</normaloff>:/img/logo-small.png</iconset>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@ -42,7 +42,7 @@
<string/> <string/>
</property> </property>
<property name="pixmap"> <property name="pixmap">
<pixmap resource="resources.qrc">:/img/logo-small.png</pixmap> <pixmap>:/img/logo-small.png</pixmap>
</property> </property>
<property name="scaledContents"> <property name="scaledContents">
<bool>false</bool> <bool>false</bool>
@ -96,6 +96,16 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>5</number> <number>5</number>
</property> </property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="filesTab">
<attribute name="title">
<string>Open File</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint"> <property name="sizeConstraint">
@ -104,69 +114,8 @@
<property name="horizontalSpacing"> <property name="horizontalSpacing">
<number>5</number> <number>5</number>
</property> </property>
<item row="3" column="0" colspan="2">
<widget class="Line" name="line">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QListWidget" name="recentsList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::ActionsContextMenu</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="viewMode">
<enum>QListView::ListMode</enum>
</property>
<property name="uniformItemSizes">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="selectionRectVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QPushButton" name="newFileButton"> <widget class="QPushButton" name="selectFileButton">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -178,20 +127,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="loadFileLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Previous sessions&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLineEdit" name="newFileEdit"> <widget class="QLineEdit" name="newFileEdit">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="frame"> <property name="frame">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -215,28 +152,80 @@
</item> </item>
</layout> </layout>
</item> </item>
</layout> <item>
<widget class="Line" name="line">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget> </widget>
</item> </item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="buttonBar" stretch="0,0,0,0"> <widget class="QListWidget" name="recentsListWidget">
<property name="spacing"> <property name="sizePolicy">
<number>10</number> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property> </property>
<property name="topMargin"> <property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::ActionsContextMenu</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number> <number>0</number>
</property> </property>
<item> <property name="iconSize">
<widget class="QPushButton" name="cancelButton"> <size>
<property name="text"> <width>48</width>
<string>Close</string> <height>48</height>
</size>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="viewMode">
<enum>QListView::ListMode</enum>
</property>
<property name="uniformItemSizes">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="selectionRectVisible">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer"> <layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -265,6 +254,189 @@
</layout> </layout>
</item> </item>
</layout> </layout>
</widget>
<widget class="QWidget" name="projectsTab">
<attribute name="title">
<string>Projects</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="horizontalSpacing">
<number>5</number>
</property>
<item row="1" column="1">
<widget class="QPushButton" name="selectProjectsDirButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLineEdit" name="projectsDirEdit">
<property name="frame">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="projectsDirLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Projects path (dir.projects):&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="projectsListWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::ActionsContextMenu</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="iconSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="spacing">
<number>5</number>
</property>
<property name="viewMode">
<enum>QListView::ListMode</enum>
</property>
<property name="uniformItemSizes">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="selectionRectVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="loadProjectButton">
<property name="text">
<string>Open</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="buttonBar" stretch="0,0">
<property name="spacing">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
<action name="actionRemove_item"> <action name="actionRemove_item">
<property name="text"> <property name="text">
<string>Remove item</string> <string>Remove item</string>
@ -277,7 +449,8 @@
</action> </action>
</widget> </widget>
<resources> <resources>
<include location="resources.qrc"/> <include location="../resources.qrc"/>
<include location="../resources.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -0,0 +1,104 @@
#include <QFileDialog>
#include <cutter.h>
#include "SaveProjectDialog.h"
#include "ui_SaveProjectDialog.h"
SaveProjectDialog::SaveProjectDialog(bool quit, QWidget *parent) :
QDialog(parent),
ui(new Ui::SaveProjectDialog)
{
ui->setupUi(this);
CutterCore *core = CutterCore::getInstance();
if (quit)
{
ui->buttonBox->setStandardButtons(QDialogButtonBox::Save
| QDialogButtonBox::Discard
| QDialogButtonBox::Cancel);
}
else
{
ui->buttonBox->setStandardButtons(QDialogButtonBox::Save
| QDialogButtonBox::Cancel);
}
ui->nameEdit->setText(core->getConfig("prj.name"));
ui->projectsDirEdit->setText(core->getConfig("dir.projects"));
ui->filesCheckBox->setChecked(core->getConfigb("prj.files"));
ui->gitCheckBox->setChecked(core->getConfigb("prj.git"));
ui->zipCheckBox->setChecked(core->getConfigb("prj.zip"));
}
SaveProjectDialog::~SaveProjectDialog()
{
}
void SaveProjectDialog::on_selectProjectsDirButton_clicked()
{
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::DirectoryOnly);
QString currentDir = ui->projectsDirEdit->text();
if(currentDir.startsWith("~"))
{
currentDir = QDir::homePath() + currentDir.mid(1);
}
dialog.setDirectory(currentDir);
dialog.setWindowTitle(tr("Select project path (dir.projects)"));
if(!dialog.exec())
{
return;
}
QString dir = dialog.selectedFiles().first();
if (!dir.isEmpty())
{
ui->projectsDirEdit->setText(dir);
}
}
void SaveProjectDialog::on_buttonBox_clicked(QAbstractButton *button)
{
switch(ui->buttonBox->buttonRole(button))
{
case QDialogButtonBox::DestructiveRole:
QDialog::done(Destructive);
break;
case QDialogButtonBox::RejectRole:
QDialog::done(Rejected);
break;
default:
break;
}
}
void SaveProjectDialog::accept()
{
CutterCore *core = CutterCore::getInstance();
core->setConfig("dir.projects", ui->projectsDirEdit->text().toUtf8().constData());
core->setConfig("prj.files", ui->filesCheckBox->isChecked());
core->setConfig("prj.git", ui->gitCheckBox->isChecked());
core->setConfig("prj.zip", ui->zipCheckBox->isChecked());
QString projectName = ui->nameEdit->text().trimmed();
if(!CutterCore::isProjectNameValid(projectName))
{
QMessageBox::critical(this, tr("Save project"), tr("Invalid project name."));
return;
}
core->saveProject(projectName);
QDialog::done(Saved);
}
void SaveProjectDialog::reject()
{
}

View File

@ -0,0 +1,35 @@
#ifndef SAVEPROJECTDIALOG_H
#define SAVEPROJECTDIALOG_H
#include <QDialog>
#include <QAbstractButton>
#include <memory>
namespace Ui
{
class SaveProjectDialog;
}
class SaveProjectDialog : public QDialog
{
Q_OBJECT
public:
enum Result { Saved, Rejected, Destructive };
explicit SaveProjectDialog(bool quit, QWidget *parent = 0);
~SaveProjectDialog();
virtual void accept() override;
virtual void reject() override;
private slots:
void on_buttonBox_clicked(QAbstractButton *button);
void on_selectProjectsDirButton_clicked();
private:
std::unique_ptr<Ui::SaveProjectDialog> ui;
};
#endif // SAVEPROJECTDIALOG_H

View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SaveProjectDialog</class>
<widget class="QDialog" name="SaveProjectDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>506</width>
<height>227</height>
</rect>
</property>
<property name="windowTitle">
<string>Save Project</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinAndMaxSize</enum>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>Project name (prj.name):</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nameEdit"/>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="nameLabel_2">
<property name="text">
<string>Projects path (dir.projects):</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="projectsDirEdit">
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="selectProjectsDirButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="filesCheckBox">
<property name="text">
<string>Save the target binary inside the project directory (prj.files)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="gitCheckBox">
<property name="text">
<string>Project is a git repo and saving is committing (prj.git)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="zipCheckBox">
<property name="text">
<string>Use ZIP format for project files (prj.zip)</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SaveProjectDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SaveProjectDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -82,7 +82,7 @@ int main(int argc, char *argv[])
else // filename specified as positional argument else // filename specified as positional argument
{ {
MainWindow *main = new MainWindow(); MainWindow *main = new MainWindow();
main->openFile(args[0], anal_level_specified ? anal_level : -1); main->openNewFile(args[0], anal_level_specified ? anal_level : -1);
} }
return a.exec(); return a.exec();

View File

@ -39,12 +39,6 @@ namespace qhelpers
#endif #endif
} }
QString uniqueProjectName(const QString &filename)
{
const QByteArray fullHash(QCryptographicHash::hash(filename.toUtf8(), QCryptographicHash::Sha1));
return QFileInfo(filename).fileName() + "_" + fullHash.toHex().left(10);
}
void adjustColumns(QTreeWidget *tw, int columnCount, int padding) void adjustColumns(QTreeWidget *tw, int columnCount, int padding)
{ {
const int count = columnCount == 0 ? tw->columnCount() : columnCount; const int count = columnCount == 0 ? tw->columnCount() : columnCount;

View File

@ -16,8 +16,6 @@ namespace qhelpers
void normalizeFont(QPlainTextEdit *edit); void normalizeFont(QPlainTextEdit *edit);
void normalizeEditFont(QTextEdit *edit); void normalizeEditFont(QTextEdit *edit);
QString uniqueProjectName(const QString &filename);
void adjustColumns(QTreeWidget *tw, int columnCount = 0, int padding = 0); void adjustColumns(QTreeWidget *tw, int columnCount = 0, int padding = 0);
QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(), QTreeWidgetItem *appendRow(QTreeWidget *tw, const QString &str, const QString &str2 = QString(),

View File

@ -15,7 +15,7 @@
Notepad::Notepad(MainWindow *main, QWidget *parent) : Notepad::Notepad(MainWindow *main, QWidget *parent) :
DockWidget(parent), QDockWidget(parent),
ui(new Ui::Notepad) ui(new Ui::Notepad)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -40,35 +40,15 @@ Notepad::Notepad(MainWindow *main, QWidget *parent) :
ui->notepadTextEdit->setContextMenuPolicy(Qt::CustomContextMenu); ui->notepadTextEdit->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->notepadTextEdit, SIGNAL(customContextMenuRequested(const QPoint &)), connect(ui->notepadTextEdit, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(showNotepadContextMenu(const QPoint &))); this, SLOT(showNotepadContextMenu(const QPoint &)));
connect(ui->notepadTextEdit, SIGNAL(textChanged()), this, SLOT(textChanged()));
connect(CutterCore::getInstance(), SIGNAL(notesChanged(const QString &)), this, SLOT(updateNotes(const QString &)));
updateNotes(CutterCore::getInstance()->getNotes());
} }
Notepad::~Notepad() {} Notepad::~Notepad() {}
void Notepad::setup()
{
}
void Notepad::refresh()
{
// TODO: implement
eprintf("%s - not implemented\n", Q_FUNC_INFO);
}
void Notepad::setText(const QString &str)
{
ui->notepadTextEdit->setPlainText(str);
}
QString Notepad::textToBase64() const
{
return notesTextEdit->toPlainText().toUtf8().toBase64();
}
void Notepad::appendPlainText(const QString &text)
{
notesTextEdit->appendPlainText(text);
}
void Notepad::on_fontButton_clicked() void Notepad::on_fontButton_clicked()
{ {
bool ok = true; bool ok = true;
@ -359,3 +339,18 @@ void Notepad::on_actionHexdump_function_triggered()
{ {
ui->previewTextEdit->setPlainText(CutterCore::getInstance()->cmd("pxf @ " + this->addr)); ui->previewTextEdit->setPlainText(CutterCore::getInstance()->cmd("pxf @ " + this->addr));
} }
void Notepad::updateNotes(const QString &notes)
{
disconnect(ui->notepadTextEdit, SIGNAL(textChanged()), this, SLOT(textChanged()));
ui->notepadTextEdit->setPlainText(notes);
connect(ui->notepadTextEdit, SIGNAL(textChanged()), this, SLOT(textChanged()));
}
void Notepad::textChanged()
{
CutterCore *core = CutterCore::getInstance();
disconnect(core, SIGNAL(notesChanged(const QString &)), this, SLOT(updateNotes(const QString &)));
core->setNotes(ui->notepadTextEdit->toPlainText());
connect(core, SIGNAL(notesChanged(const QString &)), this, SLOT(updateNotes(const QString &)));
}

View File

@ -1,8 +1,8 @@
#ifndef NOTEPAD_H #ifndef NOTEPAD_H
#define NOTEPAD_H #define NOTEPAD_H
#include "DockWidget.h"
#include <memory> #include <memory>
#include <QDockWidget>
class MainWindow; class MainWindow;
class MdHighlighter; class MdHighlighter;
@ -14,7 +14,7 @@ namespace Ui
class Notepad; class Notepad;
} }
class Notepad : public DockWidget class Notepad : public QDockWidget
{ {
Q_OBJECT Q_OBJECT
@ -22,15 +22,6 @@ public:
explicit Notepad(MainWindow *main, QWidget *parent = 0); explicit Notepad(MainWindow *main, QWidget *parent = 0);
~Notepad(); ~Notepad();
void setup() override;
void refresh() override;
void setText(const QString &str);
QString textToBase64() const;
void appendPlainText(const QString &text);
void highlightPreview(); void highlightPreview();
public slots: public slots:
@ -38,39 +29,31 @@ public slots:
private slots: private slots:
void on_fontButton_clicked(); void on_fontButton_clicked();
void on_boldButton_clicked(); void on_boldButton_clicked();
void on_italicsButton_clicked(); void on_italicsButton_clicked();
void on_h1Button_clicked(); void on_h1Button_clicked();
void on_h2Button_clicked(); void on_h2Button_clicked();
void on_h3Button_clicked(); void on_h3Button_clicked();
void on_undoButton_clicked(); void on_undoButton_clicked();
void on_redoButton_clicked(); void on_redoButton_clicked();
void on_searchEdit_returnPressed(); void on_searchEdit_returnPressed();
void on_searchEdit_textEdited(const QString &arg1); void on_searchEdit_textEdited(const QString &arg1);
void on_searchEdit_textChanged(const QString &arg1); void on_searchEdit_textChanged(const QString &arg1);
void showNotepadContextMenu(const QPoint &pt); void showNotepadContextMenu(const QPoint &pt);
void on_actionDisassmble_bytes_triggered(); void on_actionDisassmble_bytes_triggered();
void on_actionDisassmble_function_triggered(); void on_actionDisassmble_function_triggered();
void on_actionHexdump_bytes_triggered(); void on_actionHexdump_bytes_triggered();
void on_actionCompact_Hexdump_triggered(); void on_actionCompact_Hexdump_triggered();
void on_actionHexdump_function_triggered(); void on_actionHexdump_function_triggered();
void updateNotes(const QString &notes);
void textChanged();
private: private:
std::unique_ptr<Ui::Notepad> ui; std::unique_ptr<Ui::Notepad> ui;
MdHighlighter *highlighter; MdHighlighter *highlighter;